RNN 循环神经网络(中):常见的网络架构

实际应用中常见的循环神经网络架构

Posted by Xiaosheng on June 25, 2017

本文内容摘取自 《Deep Learning》,部分内容有修改。向辛勤翻译本书的 Exacity 团队致敬。

双向 RNN

在上一篇《RNN 循环神经网络(上):计算图与网络设计模式》中我们介绍的所有循环神经网络都有一个 ‘‘因果’’ 结构,意味着在时刻 $t$ 的状态只能从过去的序列 $\boldsymbol{x}^{(1)} , \cdots , \boldsymbol{x}^{(t−1)}$ 以及当前的输入 $\boldsymbol{x}^{(t)}$ 中捕获信息。

但是在许多应用中,我们要输出的 $\boldsymbol{y}^{(t)}$ 的预测可能依赖于整个输入序列。例如在语音识别中,由于协同发音,当前声音作为音素的正确解释可能取决于未来几个音素,甚至潜在的可能取决于未来的几个词,因为词与附近的词之间的存在语义依赖:如果当前的词有两种声学上合理的解释,我们可能要在更远的未来(和过去)寻找信息区分它们。这在手写识别和许多其他序列到序列学习的任务中也是如此。

双向循环神经网络(或双向 $\text{RNN}$)就是为满足这种需要而被发明的,它们在需要双向信息的应用中非常成功,如手写识别、语音识别以及生物信息学。

顾名思义,双向 $\text{RNN}$ 结合时间上从序列起点开始移动的 $\text{RNN}$ 和另一个时间上从序列末尾开始移动的 $\text{RNN}$。典型的双向 RNN 如下图所示,其中 $\boldsymbol{h}^{(t)}$ 代表通过时间向前移动的子 $\text{RNN}$ 的状态,$\boldsymbol{g}^{(t)}$ 代表通过时间向后移动的子 $\text{RNN}$ 的状态。这允许输出单元 $\boldsymbol{o}^{(t)}$ 能够计算同时依赖于过去和未来且对时刻 $t$ 的输入值最敏感的表示,而不必指定 $t$ 周围固定大小的窗口(这是前馈网络、卷积网络或具有固定大小的先行缓存器的常规 $\text{RNN}$ 所必须要做的)。

1

上图展示了典型的双向循环神经网络中的计算,意图学习将输入序列 $\boldsymbol{x}$ 映射到目标序列 $\boldsymbol{y}$(在每个步骤 $t$ 具有损失 $L^{(t)}$ )。循环性 $\boldsymbol{h}$ 在时间上向前传播信息(向右),而循环性 $\boldsymbol{g}$ 在时间上向后传播信息(向左)。因此在每个点 $t$,输出单元 $\boldsymbol{o}^{(t)}$ 可以受益于输入 $\boldsymbol{h}^{(t)}$ 中关于过去的相关概要以及输入 $\boldsymbol{g}^{(t)}$ 中关于未来的相关概要。

这个想法可以自然地扩展到 $2$ 维输入,如图像,由四个 $\text{RNN}$ 组成,每一个沿着四个方向中的一个计算:上、下、左、右。如果 $\text{RNN}$ 能够学习到承载长期信息,那在 $2$ 维网格每个点 $(i, j)$ 的输出 $O_{i,j}$ 就能计算一个能捕捉到大多局部信息但仍依赖于长期输入的表示。相比卷积网络,应用于图像的 $\text{RNN}$ 计算成本通常更高,但允许同一特征图的特征之间存在长期横向的相互作用。实际上,对于这样的 $\text{RNN}$,前向传播公式可以写成表示使用卷积的形式,计算自底向上到每一层的输入(在整合横向相互作用的特征图的循环传播之前)。

基于编码-解码的序列到序列架构

在许多场景中,$\text{RNN}$ 将输入序列映射到不一定等长的输出序列,如语音识别、机器翻译或问答,其中训练集的输入和输出序列的长度通常不相同(虽然它们的长度可能相关)。

我们经常将 $\text{RNN}$ 的输入称为 ‘‘上下文’’,并且希望产生此上下文的表示 $C$,$C$ 可能是一个概括输入序列 $\boldsymbol{X} = (\boldsymbol{x}^{(1)} , \cdots , \boldsymbol{x}^{(n_x)})$ 的向量或者向量序列。

编码-解码或序列到序列架构的想法非常简单:

  1. 编码器(encoder)读取器(reader)输入(input) $\text{RNN}$ 处理输入序列,输出上下文 $C$(通常是最终隐藏状态的简单函数)。
  2. 解码器(decoder)写入器(writer)输出(output) $\text{RNN}$ 则以固定长度的向量为条件,产生输出序列 $\boldsymbol{Y} = (\boldsymbol{y}^{(1)} , \cdots , \boldsymbol{y}^{(n_y)})$。

这种架构的创新之处在于长度 $n_x$ 和 $n_y$ 可以彼此不同,而之前的架构约束 $n_x = n_y = \tau$。在序列到序列的架构 中,两个 $\text{RNN}$ 共同训练以最大化 $\log P(\boldsymbol{y}^{(1)} , \cdots , \boldsymbol{y}^{(n_y)} \mid \boldsymbol{x}^{(1)} , \cdots , \boldsymbol{x}^{(n_x)})$(关于训练集中所有 $\boldsymbol{x}$ 和 $\boldsymbol{y}$ 对的平均)。编码器 $\text{RNN}$ 的最后一个状态 $\boldsymbol{h}_{n_x}$ 通常被当作输入的表示 $C$ 并作为解码器 $\text{RNN}$ 的输入。编码-解码或序列到序列架构如下图所示:

2

编码-解码或序列到序列的 $\text{RNN}$ 架构由读取输入序列的编码器 $\text{RNN}$ 以及生成输出序列(或计算给定输出序列的概率)的解码器 $\text{RNN}$ 组成。编码器 $\text{RNN}$ 的最终隐藏状态用于计算一般为固定大小的上下文变量 $C$,$C$ 表示输入序列的语义概要并且作为解码器 $\text{RNN}$ 的输入。

如果上下文 $C$ 是一个向量,则解码器 $\text{RNN}$ 只是在基于上下文的 RNN 序列建模中描述的向量到序列 $\text{RNN}$。如图所示,向量到序列 $\text{RNN}$ 至少有两种接受输入的方法:输入可以被提供为 $\text{RNN}$ 的初始状态,或连接到每个时间步中的隐藏单元,这两种方式也可以结合。这里并不强制要求编码器与解码器的隐藏层具有相同的大小。

此架构的一个明显不足是,编码器 $\text{RNN}$ 输出的上下文 $C$ 的维度太小而难以适当地概括一个长序列。有人提出让 $C$ 成为可变长度的序列,而不是一个固定大小的向量,他们还引入了将序列 $C$ 的元素和输出序列的元素相关联的注意力机制(attention mechanism),这在《深度学习之自然语言处理》中会详细介绍。

深度循环网络

大多数 $\text{RNN}$ 中的计算可以分解成三块参数及其相关的变换:

  1. 从输入到隐藏状态
  2. 从前一隐藏状态到下一隐藏状态
  3. 从隐藏状态到输出

例如下图所示的 $\text{RNN}$ 架构,这三个块都与单个权重矩阵相关联。

article_68_3

换句话说,当网络被展开时,每个块对应一个浅的变换。通常,这是由学成的仿射变换和一个固定非线性表示组成的变换。

能通过深度 $\text{MLP}$(多层感知器)内单个层来表示的变换称为浅变换。

实验证据表明在这些操作中引入深度会有利,与我们需要足够的深度以执行所需映射的想法一致。

Graves 第一个展示了将 $\text{RNN}$ 的状态分为多层的显著好处,如下图所示。

3

循环神经网络可以通过许多方式变得更深:(a) 隐藏循环状态可以被分解为具有层次的组。(b) 可以向输入到隐藏,隐藏到隐藏以及隐藏到输出的部分引入更深的计算 (如 $\text{MLP}$)。这可以延长链接不同时间步的最短路径。(c) 可以引入跳跃连接来缓解路径延长的效应。

我们可以认为,在 (a) 所示层次结构中较低的层起到了将原始输入转化为对更高层的隐藏状态更合适表示的作用。上图 (b) 更进一步提出在上述三个块中各使用一个单独的 $\text{MLP}$(可能是深度的),考虑表示容量,我们建议在这三个步中都分配足够的容量,但增加深度可能会因为优化困难而损害学习效果。在一般情况下,更容易优化较浅的架构,加入 (b) 的额外深度导致从时间步 $t$ 的变量到时间步 $t + 1$ 的最短路径变得更长。例如,如果具有单个隐藏层的 MLP 被用于状态到状态的转换,那么与之前的图相比,我们就会加倍任何两个不同时间步变量之间最短路径的长度。然而 Pascanu 认为,在隐藏到隐藏的路径中引入跳跃连接可以缓和这个问题,如 (c) 所示。

递归神经网络

递归神经网络代表循环网络的另一个扩展, 它被构造为深的树状结构而不是 RNN 的链状结构,因此是不同类型的计算图。递归网络的典型计算图如下图所示。

建议不要将”递归神经网络“缩写为”RNN“,以免与”循环神经网络“混淆。递归神经网络由 Pollack 引入,而 Bottou 描述了这类网络的潜在用途——学习推论。递归网络已成功地应用于输入是数据结构的神经网络,例如自然语言处理和计算机视觉。

4

递归网络将循环网络的链状计算图推广到树状计算图。可变大小的序列 $\boldsymbol{x}^{(1)} , \boldsymbol{x}^{(2)} , \cdots , \boldsymbol{x}^{(t)}$ 可以通过固定的参数集合(权重矩阵 $\boldsymbol{U},\boldsymbol{V},\boldsymbol{W}$)映射到固定大小的表示(输出 $\boldsymbol{o}$)。该图展示了监督学习的情况,其中提供了一些与整个序列相关的目标 $\boldsymbol{y}$。

递归网络的一个明显优势是,对于具有相同长度 $\tau$ 的序列,深度(通过非线性操作的组合数量来衡量)可以急剧地从 $\tau$ 减小为 $O(\log \tau)$,这可能有助于解决长期依赖。一个悬而未决的问题是如何以最佳的方式构造树。一种选择是使用不依赖于数据的树结构,如平衡二叉树。在某些应用领域,外部方法可以为选择适当的树结构提供借鉴。例如,处理自然语言的句子时,用于递归网络的树结构可以被固定为句子语法分析树的结构(可以由语法分析程序提供)。理想的情况下,人们希望学习器自行发现和推断适合于任意给定输入的树结构。

本文内容摘取自 《Deep Learning》,部分内容有修改。向辛勤翻译本书的 Exacity 团队致敬。