14.4 堆叠式与双向 RNN 架构
循环网络非常灵活。将展开式计算图的前馈性质与作为通用输入、输出的向量结合起来,就可以把复杂网络视为模块,以富有创造性的方式组合起来。本节介绍 RNN 语言处理中两种较常见的网络架构。
14.4.1 堆叠式 RNN¶
在前面的例子中,RNN 的输入由词或字符嵌入(向量)序列构成,输出则是可用于预测词、标签或序列标签的向量。然而,我们完全可以把一个 RNN 的完整输出序列作为另一个 RNN 的输入序列。堆叠式 RNN 由多个网络组成,其中一层的输出充当后续层的输入,如图 14.10 所示。
堆叠式 RNN 通常优于单层网络。这种成功的一个原因似乎是网络会在不同层次诱导出不同抽象水平的表示。正如人类视觉系统的早期阶段检测边缘,而这些边缘随后被用于寻找更大的区域和形状,堆叠网络的初始层也可以诱导出对后续层有用的抽象表示——这些表示可能很难由单个 RNN 诱导出来。堆叠 RNN 的最佳层数取决于具体应用和训练集。不过,随着堆叠层数增加,训练成本会迅速上升。

图 14.10 堆叠式循环网络。较低层的输出作为较高层的输入,最后一个网络的输出作为最终输出。
14.4.2 双向 RNN¶
RNN 使用左侧(先前的)上下文来做出时间 的预测。但在许多应用中,我们可以访问整个输入序列;这时,我们也希望使用 右侧上下文中的词。一种方法是运行两个独立的 RNN:一个从左到右,另一个从右到左,然后拼接它们的表示。
在前面讨论的从左到右的 RNN 中,给定时间 的隐藏状态表示网络截至该时刻所了解的全部序列信息。该状态是输入 的函数,表示当前时间左侧的网络上下文。
这里的新记号 就是时间 的普通隐藏状态,表示网络迄今从序列中获取的全部信息。
为了利用当前输入右侧的上下文,我们可以在反转后的输入序列上训练 RNN。采用这种方法,时间 的隐藏状态表示当前输入右侧序列的信息:
这里,隐藏状态 表示从 到序列末尾这一部分序列的全部已知信息。
双向 RNN(Schuster and Paliwal, 1997)结合两个独立的 RNN:一个从序列开头处理到结尾,另一个从结尾处理到开头。然后将两个网络计算出的表示拼接为一个向量,在每个时间点同时捕捉输入的左右上下文。这里用分号“;”或等价符号表示向量拼接:
图 14.11 展示了这种将正向与反向过程的输出拼接起来的双向网络。组合正向与反向上下文还有其他简单方式,例如逐元素相加或相乘。因此,每个时间步的输出都捕捉了当前输入左右两侧的信息。在序列标注应用中,这些拼接后的输出可以作为局部标注决策的基础。

图 14.11 双向 RNN。分别训练正向和反向模型,并将每个模型在每个时间点的输出拼接起来,以表示该时间点的双向状态。
双向 RNN 在序列分类中也非常有效。回忆图 14.8,在序列分类中,我们将 RNN 的最终隐藏状态作为后续前馈分类器的输入。这种方法的一个困难是,最终状态自然会反映更多句末而非句首的信息。双向 RNN 提供了一个简单的解决办法:如图 14.12 所示,只需组合正向和反向过程的最终隐藏状态(例如进行拼接),并将其作为后续处理的输入即可。