循环神经网络

**循环神经网络**（recurrent neural network：**RNN**）是神經網絡的一種。

数学形式化定义

*ht*​=*σ*(*Wh*​*xt*​+*Uh*​*ht*−1​+*bh*​)

其中*Wh*, *Uh*​为权重矩阵，*σ*通常为tanh函数

单纯的RNN因为无法处理随着递归，权重指数级爆炸或梯度消失问题，难以捕捉长期时间关联；而结合不同的**[[LSTM]]**可以很好解决这个问题。

*定理*：当最大奇异值*ρ*(∇*ht*​)>1时梯度爆炸，*ρ*(∇*ht*​)\vec{x}编码为一个固定长度的隐藏状态\vec{h}，这里有（用自然语言处理作为例子）：

*c*=∑*t*=1*T*​*αt*​*ht*

其中*αt*​为注意力权重
*  \vec{x} = (x_t, ..., x_1) 是输入序列，比如编码为数字的一系列词语，整个序列就是完整的句子。
* \vec{h_t} = f( x_t, \vec{h_{t-1}} )是随时间更新的隐藏状态。当新的词语输入到方程中，之前的状态\vec{h_{t-1}}就转换为和当前输入x_t相关的\vec{h_{t}}，距离当前时间越长，越早输入的序列，在更新后的状态中所占权重越小，从而表现出时间相关性。

其中，计算隐藏状态的方程f(x, h)是一个非线性方程，可以是简单的Logistic方程（tanh），也可以是复杂的LSTM单元（Long Short-Term Memory）。  而有了隐藏状态序列，就可以对下一个出现的词语进行预测：
* p(y_{t}) = p( y_{t} \, | \, y_{t-1},..., y_{1} )，其中y_t是第t个位置上的输出，它的概率基于之前输出的所有词语。
* 以上概率可以通过隐藏状态来计算：p(y_t) = g( y_{t-1}, \vec{h_t}, \vec{c} )，\vec{c}是所有隐藏状态的编码，总含了所有隐藏状态，比如可以是简单的最终隐藏状态\vec{h_t}，也可以是非线性方程的输出f( h_{t}, ..., h_1 )。因为隐藏状态t就编码了第t个输入前全部的输入信息，y_t也迭代式地隐含了之前的全部输出信息，所以这个概率计算方法是合理的。

这里的非线性方程g( y, h, c )可以是一个复杂的前馈神经网络，也可以是简单的非线性方程（但有可能因此无法适应复杂的条件而得不到任何有用结果）。给出的概率可以用监督学习的方法优化内部参数来给出翻译，也可以训练后用来给可能的备选词语，用计算其第j个备选词y_{t, j}出现在下一位置的概率，给它们排序。排序后用于其它翻译系统，可以提升翻译质量。

### 解码器

更复杂的情况下循环神经网络还可以结合编码器作为解码器（Decoder），用于将编码后（Encoded）的信息解码为人类可识别的信息。也就是上述例子中的y_t = f( y_{t-1}, h_t, c )过程，当中非线性模型f就是作为输出的循环神经网络。只是在解码过程中，隐藏状态因为是解码器的参数，所以为了发挥时间序列的特性，需要对h_t'继续进行迭代：
* h_t' = g(h_{t-1}, y_{t-1}, c)，\vec{c}是解码器传递给编码器的参数，是解码器中状态的summary。h_t'是解码器的隐藏状态。y_t是第t个输出。
* 当输入仍为\vec{x} = (x_t, ..., x_1)，输出是\vec{y} = (y_t, ..., y_1)，最大化条件概率P(\vec{y} \, | \, \vec{x})后就是最好的翻译结果。

### 双向读取

用两个循环神经网络双向读取一个序列可以使人工智能获得“注意力”。简单的做法是将一个句子分别从两个方向编码为两个隐藏状态，然后将两个\vec{h}拼接在一起作为隐藏状态。 这种方法能提高模型表现的原因之一可能是因为不同方向的读取在输入和输出之间创造了更多短期依赖关系，从而被RNN中的LSTM单元（及其变体）捕捉，例如在实验中发现颠倒输入序列的顺序（但不改变输出的顺序）可以意外达到提高表现的效果。

## 架构
RNN 有很多不同的变种

### 完全循环
基本的 RNN 是由组织成的连续的层的网络。给定层中的每个节点都通过(单向)连接连接到下一个连续层中的每个其他节点。每个节点(神经元)都有一个时变的实值激活。每个连接(突触)都有一个可修改的实值。节点要么是输入节点(从网络外部接收数据)，要么是输出节点(产生结果)，要么是隐藏节点(在从输入到输出的过程中修改数据)。

对于离散时间设置中的监督学习，实值输入向量序列到达输入节点，一次一个向量。在任何给定的时间步长，每个非输入单元将其当前激活(结果)计算为与其连接的所有单元的激活的加权和的非线性函数。可以在特定的时间步长为某些输出单元提供主管给定的目标激活。例如，如果输入序列是对应于口语数字的语音信号，则在序列末尾的最终目标输出可以是对该数字进行分类的标签。

在强化学习环境中，没有教师提供目标信号。相反，适应度函数或奖励函数偶尔用于评估RNN的性能，它通过影响输出单元来影响其输入流，输出单元和一个可以影响环境的执行器相连。这可以被用来玩一个游戏，在这个游戏中，进度是用赢得的点数来衡量的。

每个序列产生一个误差，作为所有目标信号与网络计算的相应激活的偏差之和。对于大量序列的训练集，总误差是所有单个序列误差的总和。

### Elman 网络和 Jordan 网络

Elman网络是一个三层网络(在图中水平排列为x、y和z)，添加了一组上下文单元(在图中为u)。中间(隐藏)层连接到这些权重为1的上下文单元。在每个时间步，输入被向前反馈，并且学习规则被应用。固定的反向连接在上下文单元中保存隐藏单元的先前值的副本(因为它们在应用学习规则之前在连接上传播)。因此，网络可以保持某种状态，允许它执行诸如序列预测之类的任务，这些任务超出了标准多层感知器的能力。

Jordan网络类似于Elman网络。上下文单元是从输出层而不是隐藏层馈送的。Jordan网络中的上下文单元也称为状态层。他们与自己有着经常性的联系。

Elman和Jordan网络也被称为“简单循环网络”。

; Elman 网络
: 
\begin{align}
h_t &= \sigma_h(W_{h} x_t + U_{h} h_{t-1} + b_h) \\
y_t &= \sigma_y(W_{y} h_t + b_y)
\end{align}

; Jordan 网络
: 
\begin{align}
h_t &= \sigma_h(W_{h} x_t + U_{h} y_{t-1} + b_h) \\
y_t &= \sigma_y(W_{y} h_t + b_y)
\end{align}


变量和函数

* x_t: 输入向量
* h_t: 隐藏层向量
* y_t: 输出向量
* W, U 和 b: 参数矩阵和参数向量
* \sigma_h 和 \sigma_y: 激活函数

### 双向循环神经网络
双向循环神经网络（Bi-directional RNN，BRNN）基于元素的前向和后向的上下文，使用有限序列来预测或标记序列的每个元素。该方法是通过连接两个 RNN 的输出来完成的：一个从左到右处理序列，另一个从右到左处理序列。BRNN的输出是对目标信号的预测。该技术已被证明在与 LSTM RNN 结合使用时特别有用。

## 参考

## 外部連結
* A Critical Review of Recurrent Neural Networks for Sequence Learning