循环神经网络

循环神经网络（recurrent neural network：RNN）是神经网络的一种。

数学形式化定义$$h_t=\sigma(W_h x_t+U_h h_{t-1}+b_h)$$

其中$W_h$, $U_h$为权重矩阵，$\sigma$通常为 $\tanh$ 函数

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

定理：当最大奇异值ρ(∇ht)>1时梯度爆炸，ρ(∇ht)<1时梯度消失

时间循环神经网络可以描述动态时间行为，因为和前馈神经网络（feedforward neural network）接受较特定结构的输入不同，RNN将状态在自身网络中循环传递，因此可以接受更广泛的时间序列结构输入。手写识别是最早成功利用RNN的研究结果。

## 历史

循环神经网络是基于大卫·鲁梅尔哈特1986年的工作。1982年，约翰·霍普菲尔德发现了Hopfield神经网络——一种特殊的RNN。1993年，一个神经历史压缩器系统解决了一个“非常深度学习”的任务，这个任务在RNN展开之后有1000多个后续层。

### LSTM

Hochreiter和Schmidhuber于1997年提出了长短期记忆(LSTM)网络，并在多个应用领域创造了精确度记录。

大约在2007年，LSTM开始革新语音识别领域，在某些语音应用中胜过传统模型。2009年，一个由 训练的LSTM网络赢得了多项连笔手写识别竞赛，成为第一个赢得模式识别竞赛的RNN。2014年，百度在不使用任何传统语音处理方法的情况下，使用经过CTC训练的RNNs打破了Switchboard Hub5'00 语音识别基准。

LSTM还改进了大词汇量语音识别和文本到语音合成并在谷歌安卓系统中使用。据报道，2015年，谷歌语音识别通过接受过CTC训练的LSTM(谷歌语音搜索使用的)实现了49%的引用量的大幅提升。

LSTM打破了改进机器翻译、语言建模和多语言处理的记录。LSTM 结合卷积神经网络改进了图像自动标注。

## 循环神经网络

### 编码器

循环神经网络将输入序列$\vec{x}$编码为一个固定长度的隐藏状态$\vec{h}$，这里有（用自然语言处理作为例子）：

c=∑t=1Tαtht

其中:

- $\alpha_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 网络

<image>

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