循环神经网络(RecurrentNeuralNetwork,RNN)是一类具有短期记忆能力的神经网络.在循环神经网络中,神经元不但可以接受其他神经元的信息,也可以接受自身的信息,形成具有环路的网络结构.和前馈神经网络相比,循环神经网络更加符合生物神经网络的结构.循环神经网络已经被广泛应用在语音识别、语言模型以及自然语言生成等任务上.循环神经网络的参数学习可以通过随 时间反向传播算法来学习.随时间反向传播算法即按照时间的逆序将错误信息一步步地往前传递.当输入序列比较长时,会存在梯度爆炸和消失问题,也称为长程依赖问题.为 了解决这个问题,人们对循环神经网络进行了很多的改进,其中最有效的改进方式引入门控机制(GatingMechanism).

此外,循环神经网络可以很容易地扩展到两种更广义的记忆网络模型:递归神经网络图网络

1. 给网络增加记忆能力

为了处理这些时序数据并利用其历史信息,我们需要让网络具有短期记忆能力. 一般来讲,我们可以通过以下三种方法来给网络增加短期记忆能力.

1.1 延时神经网络

延时神经网络是在前馈网络中的非输出层都添加一个延时器,记录神经元的最近几次活性值.在第t个时刻,第𝑙层神经元的活性值依赖于第𝑙−1层神经 元的最近𝐾个时刻的活性值,即

其中表示\boldsymbol{h}^{(l)}_t\in\mathbb{R}^{M_l}第𝑙层神经元在时刻𝑡的活性值,M_l为第𝑙层神经元的数量.通过延时器,前馈网络就具有了短期记忆的能力.

1.2 由外部输入的非线性自回归模型

自回归模型(AutoRegressive Model,AR)是统计学上常用的一类时间序列模型,用一个变量\boldsymbol{y}_t的历史信息来预测自己.其中𝐾为超参数,w_0,⋯,w_K为可学习参数,\epsilon _t \sim N(0,\sigma ^2)为第𝑡个时刻的噪声, 方差\sigma ^2和时间无关.

有外部输入的非线性自回归模型(Nonlinear AutoRegressive with Exogenous Inputs Model,NARX)是自回归模型的扩展,在每个时刻𝑡都有一个外部输入\boldsymbol{x}_t,产生一个输出\boldsymbol{y}_t.NARX通过一个延时器记录最近K_x次的外部输入和最近K_y次的输出,第t个时刻的输出\boldsymbol{y}_t其中𝑓(⋅)表示非线性函数,可以是一个前馈网络,K_xK_y为超参数.

1.3 循环神经网络

循环神经网络(Recurrent Neural Network,RNN)通过使用带自反馈的神经元,能够处理任意长度的时序数据.

给定一个输入序列\boldsymbol{x}_1∶𝑇 = (\boldsymbol{x}_1,\boldsymbol{x}_2,⋯,\boldsymbol{x}_t,⋯,\boldsymbol{x}_T),循环神经网络通过下面公式更新带反馈边的隐藏层的活性值\boldsymbol{h}_t其中\boldsymbol{h}_0=0,𝑓(⋅)为一个非线性函数,可以是一个前馈网络.

图6.1给出了循环神经网络的示例,其中“延时器”为一个虚拟单元,记录神经元的最近一次(或几次)活性值.

从数学上讲,公式(6.4)可以看成一个动力系统. 因此,隐藏层的活性值\boldsymbol{h}_t在很多文献上也称为状态(State)或隐状态(HiddenState).

由于循环神经网络具有短期记忆能力,相当于存储装置,因此其计算能力十分强大.理论上,循环神经网络可以近似任意的非线性动力系统(参见 第2.1节).前馈神经网络可以模拟任何连续函数,而循环神经网络可以模拟任何程序.

动力系统(Dynamical System)是一个数学上的概念,指系统状态按照一定的规律随时间变化的系统.具体地讲, 动力系统是使用一个函数来描述一个给定空间(如某个物理系统的状态空间)中所有点随时间的变化情况. 生活中很多现象(比如钟摆晃动、台球轨迹等)都可以动力系统来描述.

2. 简单循环网络

简单循环网络(SimpleRecurrentNetwork,SRN)是一个非常简单的循环神经网络,只有一个隐藏层的神经网络.在一个两层的前馈神经网络中,连接存在相邻的层与层之间,隐藏层的节点之间是无连接的.而简单循环网络增加了从隐藏层到隐藏层的反馈连接.

令向量\boldsymbol{x}_t\in\mathbb{R}^M表示在时刻𝑡时网络的输入,\boldsymbol{h}_t\in\mathbb{R}^D表示隐藏层状态(即隐藏层神经元活性值),则\boldsymbol{h}_t不仅和当前时刻的输入\boldsymbol{x}_t相关,也和上一个时刻的隐藏层状态\boldsymbol{h}_{t-1}相关.简单循环网络在时刻𝑡的更新公式为

其中\boldsymbol{z}_t为隐藏层的净输入,𝑼∈\mathbb{R}^{D\times D}状态-状态权重矩阵,𝑾∈\mathbb{R}^{D\times M}状态-输入权重矩阵,𝒃∈\mathbb{R}^{D}为偏置向量,𝑓(⋅)是非线性激活函数,通常为Logistic函数或Tanh函数.公式(6.5)和公式(6.6)也经常直接写为

如果我们把每个时刻的状态都看作前馈神经网络的一层,循环神经网络可以看作在时间维度上权值共享的神经网络.图6.2给出了按时间展开的循环神经网络.

2.1 循环神经网络的计算能力

我们先定义一个完全连接的循环神经网络,其输入为\boldsymbol{x}_t,输出为\boldsymbol{y}_t

其中𝒉为隐状态,𝑓(⋅)为非线性激活函数,𝑼、𝑾、𝒃和𝑽为网络参数.

2.1.1 循环神经网络的通用近似定理

循环神经网络的拟合能力也十分强大.一个完全连接的循环网络是任何非线性动力系统的近似器.

定理6.1 循环神经网络的通用近似定理:如果一个完全连接的循环神经网络有足够数量的sigmoid型隐藏神经元,它可以以任意的准确率去近似任何一个非线性动力系统

其中\boldsymbol{s}_t为每个时刻的隐状态,\boldsymbol{x}_t是外部输入,𝑔(⋅)是可测的状态转换函数, o(⋅)是连续输出函数,并且对状态空间的紧致性没有限制.

 证明. 1)根据通用近似定理,两层的前馈神经网络可以近似任意有界闭集上的任意连续函数.因此,动力系统的两个函数可以用两层的全连接前馈网络近似. 首先,非线性动力系统的状态转换函数\boldsymbol{s}_t=g(\boldsymbol{s}_{t-1},\boldsymbol{x}_t)可以由一个两层的神经网络\boldsymbol{s}_t=\boldsymbol{C}f(\boldsymbol{A}\boldsymbol{s}_{t-1}+\boldsymbol{Bx}_t+\boldsymbol{b})来近似,可以分解为

 其中𝑨,𝑩,𝑪为权重矩阵,𝒃为偏置向量.

同理,非线性动力系统的输出函数\boldsymbol{y}_t=o(\boldsymbol{s}_t)=o(g(\boldsymbol{s}_{t-1},\boldsymbol{x}_t))也可以用一 个两层的前馈神经网络近似.

其中𝐴′,𝐵′,𝐷为权重矩阵,𝒃′为偏置向量.

2)公式(6.13)和公式(6.16)可以合并为

公式(6.17)可以改写为

 令\boldsymbol{h}_t=\left [ \boldsymbol{s}'_t;\boldsymbol{y}'_t \right ],则非线性动力系统可以由下面的全连接循环神经网络来近似.

 其中

2.1.2 图灵完备

图灵完备(Turing Completeness)是指一种数据操作规则,比如一种计算机编程语言,可以实现图灵机(TuringMachine)的所有功能,解决所有的可计算问题. 目前主流的编程语言(比如C++、Java、Python等)都是图灵完备的.

定理6.2–图灵完备: 所有的图灵机都可以被一个由使用Sigmoid型激活函数的神经元构成的全连接循环网络来进行模拟.

因此,一个完全连接的循环神经网络可以近似解决所有的可计算问题.

3. 应用到机器学习

循环神经网络可以应用到很多不同类型的机器学习任务.根据这些任务的特点可以分为以下几种模式:序列到类别模式同步的序列到序列模式异步的序列到序列模式

下面我们分别来看下这几种应用模式.

3.1 序列到类别模式

序列到类别模式主要用于序列数据的分类问题:输入为序列,输出为类别. 比如在文本分类中,输入数据为单词的序列,输出为该文本的类别. 假设一个样本\boldsymbol{x}_{1:T}=(\boldsymbol{x}_1,...,\boldsymbol{x}_T)为一个长度为𝑇的序列,输出为一个类别 y∈ {1,⋯,𝐶}.我们可以将样本𝒙按不同时刻输入到循环神经网络中,并得到不同时刻的隐藏状态\boldsymbol{h}_1,⋯,\boldsymbol{h}_T.我们可以将\boldsymbol{h}_T看作整个序列的最终表示(或特征),并输入给分类器𝑔(⋅)进行分类(如图6.3a所示),即

其中𝑔(⋅)可以是简单的线性分类器(比如Logistic回归)或复杂的分类器(比如多层前馈神经网络) 

除了将最后时刻的状态作为整个序列的表示之外,我们还可以对整个序列的所有状态进行平均,并用这个平均状态来作为整个序列的表示(如图6.3b所示),即

3.2 同步的序列到序列模式

同步的序列到序列模式主要用于序列标注(SequenceLabeling)任务,即每一时刻都有输入和输出,输入序列和输出序列的长度相同.比如在词性标注 (Part-of-SpeechTagging)中,每一个单词都需要标注其对应的词性标签. 在同步的序列到序列模式(如图6.4所示)中,输入为一个长度为𝑇的序列 \boldsymbol{x}_{1:T}=(\boldsymbol{x}_1,...,\boldsymbol{x}_T),输出为序列y_{1:T}=(y_1,...,y_T).样本𝒙按不同时刻输入到循环神经网络中,并得到不同时刻的隐状态\boldsymbol{h}_1,⋯,\boldsymbol{h}_T.每个时刻的隐状态\boldsymbol{h}_t代表了当前时刻和历史的信息,并输入给分类器𝑔(⋅)得到当前时刻的标签y_t,即

3.3 异步的序列到序列模式

异步的序列到序列模式也称为编码器-解码器(Encoder-Decoder)模型,即输入序列和输出序列不需要有严格的对应关系,也不需要保持相同的长度.比如在机器翻译中,输入为源语言的单词序列,输出为目标语言的单词序列.参见第15.6节. 在异步的序列到序列模式中,输入为长度为𝑇的序列\boldsymbol{x}_{1:T}=(\boldsymbol{x}_1,...,\boldsymbol{x}_T), 输出为长度为𝑀的序列y_{1:M}=(y_1,...,y_M).异步的序列到序列模式一般通过先 编码后解码的方式来实现.先将样本𝒙按不同时刻输入到一个循环神经网络(编 码器)中,并得到其编码\boldsymbol{h}_T.然后再使用另一个循环神经网络(解码器),得到输 出序列\hat{y}_{1:T}.为了建立输出序列之间的依赖关系,在解码器中通常使用非线性的 自回归模型.令𝑓1(⋅)和𝑓2(⋅)分别为用作编码器和解码器的循环神经网络,则编码器-解码器模型可以写为

其中𝑔(⋅)为分类器,\boldsymbol{\hat{y}}_t为预测输出\hat{y}_t的向量表示.在解码器通常采用自回归模型,每个时刻的输入为上一时刻的预测结果\hat{y}_{t-1}

图6.5给出了异步的序列到序列模式示例,其中⟨𝐸𝑂𝑆⟩表示输入序列的结束, 虚线表示将上一个时刻的输出作为下一个时刻的输入.

4. 参数学习

循环神经网络的参数可以通过梯度下降方法来进行学习.

以随机梯度下降为例,给定一个训练样本(𝒙,𝒚),其中\boldsymbol{x}_{1:T}=(\boldsymbol{x}_1,...,\boldsymbol{x}_T) 为长度是𝑇的输入序列,y_{1:T}=(y_1,...,y_T)是长度为𝑇的标签序列.即在每个时刻𝑡,都有一个监督信息y_t,我们定义时刻𝑡的损失函数为

其中g(\boldsymbol{h}_t)为第𝑡时刻的输出,ℒ为可微分的损失函数,比如交叉熵.那么整个序列的损失函数为

整个序列的损失函数ℒ关于参数𝑼的梯度为

即每个时刻损失ℒ𝑡对参数𝑼的偏导数之和.

循环神经网络中存在一个递归调用的函数𝑓(⋅),因此其计算参数梯度的方式和前馈神经网络不太相同.在循环神经网络中主要有两种计算梯度的方式:随时间反向传播(BPTT)算法和实时循环学习(RTRL)算法.

4.1 随时间反向传播算法

随时间反向传播(BackPropagation Through Time,BPTT)算法的主要思想是通过类似前馈神经网络的错误反向传播算法来计算梯度.

BPTT算法将循环神经网络看作一个展开的多层前馈网络,其中“每一层”对应循环网络中的“每个时刻”(见图6.2).这样,循环神经网络就可以按照前馈网络中的反向传播算法计算参数梯度.在“展开”的前馈网络中,所有层的参数是共享的,因此参数的真实梯度是所有“展开层”的参数梯度之和. 计算偏导数\frac{\partial L_t}{\partial \boldsymbol{U}}           先来计算公式(6.30)中第𝑡时刻损失对参数𝑼的偏导数\frac{\partial L_t}{\partial \boldsymbol{U}}

因为参数𝑼和隐藏层在每个时刻𝑘(1 ≤ 𝑘 ≤ 𝑡)的净输入\boldsymbol{z}_k=\boldsymbol{Uh}_{k-1}+\boldsymbol{Wx}_k+\boldsymbol{b}有关,因此第𝑡时刻的损失函数ℒ𝑡关于参数u_{ij}的梯度为:

其中\frac{\partial ^+ \boldsymbol{z}_k}{\partial u_{ij}}表示“直接”偏导数,即公式\boldsymbol{z}_k=\boldsymbol{Uh}_{k-1}+\boldsymbol{Wx}_k+\boldsymbol{b}中保持\boldsymbol{h}_{k-1}不变,对u_{ij}进行求偏导数,得到 

其中[\boldsymbol{h}_{k-1}]_j为第𝑘−1时刻隐状态的第𝑗维;\mathbb{I}_i(x)除了第𝑖行值为𝑥外,其余都为0的行向量. 定义误差项\delta _{t,k}=\frac{\partial L_t}{\partial \boldsymbol{z}_k}为第𝑡时刻的损失对第𝑘时刻隐藏神经层的净输入\boldsymbol{z}_k的导数,则当1≤𝑘<𝑡时

将公式(6.36)和公式(6.33)代入公式(6.31)得到 

 将上式写成矩阵形式为

 图6.6给出了误差项随时间进行反向传播算法的示例.

参数梯度   将公式(6.38)代入到公式(6.30),得到整个序列的损失函数ℒ关于参数𝑼的梯度

同理可得,ℒ关于权重𝑾和偏置𝒃的梯度为 

计算复杂度  在BPTT算法中,参数的梯度需要在一个完整的“前向”计算和“反向”计算后才能得到并进行参数更新 

4.2 实时循环学习算法

与反向传播的BPTT算法不同的是,实时循环学习(Real-Time Recurrent Learning,RTRL)是通过前向传播的方式来计算梯度.

假设循环神经网络中第𝑡+1时刻的状态\boldsymbol{h}_{t+1}

其关于参数u_{ij}的偏导数为

其中\mathbb{I}_i(x)是除了第𝑖行值为𝑥外,其余都为0的行向量. 

RTRL算法从第1个时刻开始,除了计算循环神经网络的隐状态之外,还利用公式(6.45)依次前向计算偏导数\frac{\partial \boldsymbol{h}_1}{\partial u_{ij}}, \frac{\partial \boldsymbol{h}_2}{\partial u_{ij}}, \frac{\partial \boldsymbol{h}_3}{\partial u_{ij}} , ⋯. 这样,假设第𝑡个时刻存在一个监督信息,其损失函数为ℒ𝑡,就可以同时算损失函数对u_{ij}的偏导数

这样在第𝑡时刻,可以实时地计算损失ℒ𝑡关于参数𝑼的梯度,并更新参数.参数\boldsymbol{W}\boldsymbol{b}的梯度也可以同样按上述方法实时计算.

两种算法比较 RTRL算法和BPTT算法都是基于梯度下降的算法,分别通过前向模式和反向模式应用链式法则来计算梯度.在循环神经网络中,一般网络输出维度远低于输入维度,因此BPTT算法的计算量会更小,但是BPTT算法需要保存所有时刻的中间梯度,空间复杂度较高.RTRL算法不需要梯度回传,因此非常适合用于需要在线学习或无限序列的任务中.

5. 长程依赖问题

循环神经网络在学习过程中的主要问题是由于梯度消失或爆炸问题,很难建模长时间间隔(LongRange)的状态之间的依赖关系.

在BPTT算法中,将公式(6.36)展开得到

如果定义\gamma \cong \left \| diag(f'(\boldsymbol{z}_\tau ))\boldsymbol{U}^\top \right \|,则

若𝛾>1,当𝑡−𝑘→\infty时,𝛾𝑡−𝑘 →\infty.当间隔𝑡−𝑘比较大时,梯度也变得很大,会造成系统不稳定,称为梯度爆炸问题(GradientExplodingProblem).

相反,若𝛾 < 1,当𝑡−𝑘 →\infty时,𝛾𝑡−𝑘 → 0.当间隔𝑡−𝑘比较大时, 度也变得非常小,会出现和深层前馈神经网络类似的梯度消失问题(Vanishing Gradient Problem).

要注意的是,在循环神经网络中的梯度消失不是说\frac{\partial L_t}{\partial \boldsymbol{U}}的梯度消失了,而是\frac{\partial L_t}{\partial \boldsymbol{h}_k}的梯度消失了(当间隔𝑡−𝑘比较大时).也就是说,参数𝑼的更新主要靠当前时刻𝑡的几个相邻状态\boldsymbol{h}_k来更新,长距离的状态对参数𝑼没有影响.

由于循环神经网络经常使用非线性激活函数为Logistic函数或Tanh函数作为非线性激活函数,其导数值都小于1,并且权重矩阵‖𝑼‖也不会太大,因此如果时间间隔𝑡−𝑘过大,\delta _{t,k}会趋向于0,因而经常会出现梯度消失问题.

虽然简单循环网络理论上可以建立长时间间隔的状态之间的依赖关系,但是由于梯度爆炸或消失问题,实际上只能学习到短期的依赖关系.这样,如果时刻𝑡的输出𝑦𝑡依赖于时刻𝑘的输入\boldsymbol{x}_k,当间隔𝑡−𝑘比较大时,简单神经网络很难建模这种长距离的依赖关系,称为长程依赖问题(Long-TermDependencies Problem).

5.1 改进方案

为了避免梯度爆炸或消失问题,一种最直接的方式就是选取合适的参数,同时使用非饱和的激活函数,尽量使得diag(f'(\boldsymbol{z}_\tau ))\boldsymbol{U}^\top\approx 1,这种方式需要足够的人工调参经验,限制了模型的广泛应用.比较有效的方式是通过改进模型或优化方法来缓解循环网络的梯度爆炸和梯度消失问题.

梯度爆炸   一般而言,循环网络的梯度爆炸问题比较容易解决,一般通过权重衰减或梯度截断来避免. 权重衰减是通过给参数增加ℓ1或ℓ2范数的正则化项来限制参数的取值范围,从而使得𝛾≤1.梯度截断是另一种有效的启发式方法,当梯度的模大于一定阈值时,就将它截断成为一个较小的数.

梯度消失  梯度消失是循环网络的主要问题.除了使用一些优化技巧外,更有效的方式就是改变模型,比如让𝑼=𝑰,同时令\frac{\partial \boldsymbol{h}_t}{\partial \boldsymbol{h}_{t-1}}=\boldsymbol{I}为单位矩阵,即

其中𝑔(⋅)是一个非线性函数,𝜃为参数.

(6.49) 公式(6.49)中,\boldsymbol{h}_{t}\boldsymbol{h}_{t-1}之间为线性依赖关系,且权重系数为1,这样就不存在梯度爆炸或消失问题.但是,这种改变也丢失了神经元在反馈边上的非线性激活的性质,因此也降低了模型的表示能力.

为了避免这个缺点,我们可以采用一种更加有效的改进策略: 

这样\boldsymbol{h}_{t}\boldsymbol{h}_{t-1}之间为既有线性关系,也有非线性关系,并且可以缓解梯度消失问题.但这种改进依然存在两个问题:

(1)梯度爆炸问题: 令\boldsymbol{z}_k=\boldsymbol{Uh}_{k-1}+\boldsymbol{Wx}_k+\boldsymbol{b}为在第𝑘时刻函数𝑔(⋅)的输入,在计算公式(6.34)中的误差项\delta _{t,k}=\frac{\partial L_t}{\partial \boldsymbol{z}_k}时,梯度可能会过大,从而导致梯度爆炸问题.

(2)记忆容量(MemoryCapacity)问题:随着\boldsymbol{h}_{t}不断累积存储新的输入信息,会发生饱和现象.假设𝑔(⋅)为Logistic函数,则随着时间𝑡的增长,\boldsymbol{h}_{t}会变得越来越大,从而导致𝒉变得饱和.也就是说,隐状态\boldsymbol{h}_{t}可以存储的信息是有限的, 随着记忆单元存储的内容越来越多,其丢失的信息也越来越多.

为了解决这两个问题,可以通过引入门控机制来进一步改进模型.

6. 基于门控的循环神经网络

为了改善循环神经网络的长程依赖问题,一种非常好的解决方案是在公式(6.50)的基础上引入门控机制来控制信息的累积速度,包括有选择地加入新的信息,并有选择地遗忘之前累积的信息.这一类网络可以称为基于门控的循环神经网络(GatedRNN).本节中,主要介绍两种基于门控的循环神经网络:长短期记忆网络门控循环单元网络

6.1 长短期记忆网络

长短期记忆网络(LongShort-Term Memory Network,LSTM)是循环神经网络的一个变体,可以有效地解决简单循环神经网络的梯度爆炸或消失问题.

在公式(6.50)的基础上,LSTM网络主要改进在以下两个方面:

新的内部状态        LSTM网络引入一个新的内部状态(internalstate)\boldsymbol{c}_t\in \mathbb{R}^D专 门进行线性的循环信息传递,同时(非线性地)输出信息给隐藏层的外部状态\boldsymbol{h}_t\in \mathbb{R}^D.内部状态\boldsymbol{c}_{t}通过下面公式计算:

其中\boldsymbol{f}_t\in[0,1]^D\boldsymbol{i}_t\in[0,1]^D\boldsymbol{o}_t\in[0,1]^D为三个门(gate)来控制信息传递的路径;⊙为向量元素乘积;\boldsymbol{c}_{t-1}为上一时刻的记忆单元;\boldsymbol{\tilde{c}}_t\in[0,1]^D是通过非线性函数得到的候选状态: 

在每个时刻𝑡,LSTM网络的内部状态\boldsymbol{c}_{t}记录了到当前时刻为止的历史信息.

门控机制   在数字电路中,门(gate)为一个二值变量{0,1},0代表关闭状态,不许任何信息通过;1代表开放状态,允许所有信息通过.

LSTM网络引入门控机制(Gating Mechanism)来控制信息传递的路径.公式(6.51)和公式(6.52)中三个“门”分别为输入门\boldsymbol{i}_{t}、遗忘门\boldsymbol{f}_{t}和输出门\boldsymbol{o}_{t}.这 三个门的作用为

(1) 输入门\boldsymbol{i}_{t}控制当前时刻的候选状态\boldsymbol{\tilde{c}}_{t}有多少信息需要保存.

(2)遗忘门\boldsymbol{f}_{t}控制上一个时刻的内部状态\boldsymbol{c}_{t-1}需要遗忘多少信息.

(3) 输出门\boldsymbol{o}_{t}控制当前时刻的内部状态\boldsymbol{c}_{t}有多少信息需要输出给外部状态\boldsymbol{h}_{t}

\boldsymbol{f}_{t}=0 ,\boldsymbol{i}_{t}=1时,记忆单元将历史信息清空,并将候选状态向量\boldsymbol{c}_{t}写入. 但此时记忆单元\boldsymbol{c}_{t}依然和上一时刻的历史信息相关.当\boldsymbol{f}_{t}=1 ,\boldsymbol{i}_{t}=0时,记忆单元将复制上一时刻的内容,不写入新的信息.

LSTM网络中的“门”是一种“软”门,取值在(0,1)之间,表示以一定的比例允许信息通过.三个门的计算方式为:

其中𝜎(⋅)为Logistic函数,其输出区间为(0,1),\boldsymbol{x}_{t}为当前时刻的输入,\boldsymbol{h}_{t-1}为上 一时刻的外部状态. 图6.7给出了LSTM网络的循环单元结构,其计算过程为:1)首先利用上一 时刻的外部状态\boldsymbol{h}_{t-1}和当前时刻的输入\boldsymbol{x}_{t},计算出三个门,以及候选状态\boldsymbol{c}_{t};2) 结合遗忘门\boldsymbol{f}_{t}和输入门\boldsymbol{i}_{t}来更新记忆单元\boldsymbol{c}_{t};3)结合输出门\boldsymbol{o}_{t},将内部状态的信息传递给外部状态\boldsymbol{h}_{t}

通过LSTM循环单元,整个网络可以建立较长距离的时序依赖关系.公式 (6.51)~公式(6.56)可以简洁地描述为

其中\boldsymbol{x}_t\in \mathbb{R}^M为当前时刻的输入,\boldsymbol{W}\in \mathbb{R}^{4D\times (D+M)}\boldsymbol{b}\in \mathbb{R}^{4D}为网络参数.

记忆      循环神经网络中的隐状态𝒉存储了历史信息,可以看作一种记忆(Memory).在简单循环网络中,隐状态每个时刻都会被重写,因此可以看作一种短期记忆(Short-TermMemory).在神经网络中,长期记忆(Long-TermMem ory)可以看作网络参数,隐含了从训练数据中学到的经验,其更新周期要远远慢于短期记忆.而在LSTM网络中,记忆单元𝒄可以在某个时刻捕捉到某个关键信息,并有能力将此关键信息保存一定的时间间隔.记忆单元𝒄中保存信息的生命周期要长于短期记忆𝒉,但又远远短于长期记忆,长短期记忆是指长的 “短期记忆”. 因此称为长短期记忆(Long Short-Term Memory).

一般在深度网络参数学习时,参数初始化的值一般都比较小.但是在训练LSTM网络时,过小的值会使得遗忘门的值比较小.这意味着前一时刻的信息大部分都丢失了,这样网络很难捕捉到长距离的依赖信息.并且相邻时间间隔的梯度会非常小,这会导致梯度弥散问题.因此遗忘的参数初始值一般都设得比较大,其偏置向量\boldsymbol{b}_f设为1或2.

6.2 LSTM网络的各种变体

目前主流的LSTM网络用三个门来动态地控制内部状态应该遗忘多少历史信息,输入多少新信息,以及输出多少信息.我们可以对门控机制进行改进并获得LSTM网络的不同变体.

无遗忘门的LSTM网络    最早提出的LSTM网络是没有遗忘门的,其内部状态的更新为

如之前的分析,记忆单元𝒄会不断增大.当输入序列的长度非常大时,记忆单元的容量会饱和,从而大大降低LSTM模型的性能.

peephole连接      另外一种变体是三个门不但依赖于输入\boldsymbol{x}_{t}和上一时刻的隐状态\boldsymbol{h}_{t-1},也依赖于上一个时刻的记忆单元\boldsymbol{c}_{t-1},即

 其中\boldsymbol{V}_{i}\boldsymbol{V}_{f}\boldsymbol{V}_{o}为对角矩阵.

耦合输入门和遗忘门 LSTM网络中的输入门和遗忘门有些互补关系,因此同时用两个门比较冗余.为了减少LSTM网络的计算复杂度,将这两门合并为一个门.令\boldsymbol{f}_t=1-\boldsymbol{i}_t,内部状态的更新方式为

6.3 门控循环单元网络

门控循环单元(Gated Recurrent Unit,GRU)网络是一种比LSTM网络更加简单的循环神经网络. GRU网络引入门控机制来控制信息更新的方式.和LSTM不同,GRU不引入额外的记忆单元,GRU网络也是在公式(6.50)的基础上引入一个更新门(Update Gate)来控制当前状态需要从历史状态中保留多少信息(不经过非线性变换),以及需要从候选状态中接受多少新信息,即

其中\boldsymbol{z}_t\in[0,1]^D为更新门:

在LSTM网络中,输入门和遗忘门是互补关系,具有一定的冗余性.GRU网络直接使用一个门来控制输入和遗忘之间的平衡.当\boldsymbol{z}_t=0时,当前状态\boldsymbol{h}_t和前一时刻的状态\boldsymbol{h}_{t-1}之间为非线性函数关系;当\boldsymbol{z}_t=1时,\boldsymbol{h}_t\boldsymbol{h}_{t-1}之间为线性函数关系.

在GRU网络中,函数g(\boldsymbol{x}_t,\boldsymbol{h}_{t-1};\theta )的定义为

其中\boldsymbol{\tilde{h}}_t表示当前时刻的候选状态,\boldsymbol{r}_t\in[0,1]^D重置门(Reset Gate)

用来控制候选状态\boldsymbol{\tilde{h}}_t的计算是否依赖上一时刻的状态\boldsymbol{h}_{t-1}

\boldsymbol{r}_t=0时,候选状态\boldsymbol{\tilde{h}}_t=tanh(\boldsymbol{W_cx_t}+\boldsymbol{b})只和当前输入\boldsymbol{x}_t相关,和历史状态无关.当\boldsymbol{r}_t=1时,候选状态\boldsymbol{\tilde{h}}_t=tanh(\boldsymbol{W_hx_t}+\boldsymbol{U_hh_{t-1}}+\boldsymbol{b_h})和当前输入\boldsymbol{x}_t以及历史状态\boldsymbol{h}_{t-1}相关,和简单循环网络一致.

综上,GRU网络的状态更新方式为

 可以看出,当\boldsymbol{z}_t=0,\boldsymbol{r}=1时,GRU网络退化为简单循环网络;若\boldsymbol{z}_t=0,\boldsymbol{r}=0 时,当前状态\boldsymbol{h}_t只和当前输入\boldsymbol{x}_t相关,和历史状态\boldsymbol{h}_{t-1}无关.当\boldsymbol{z}_t=1时,当前状态\boldsymbol{h}_t=\boldsymbol{h}_{t-1}等于上一时刻状态\boldsymbol{h}_{t-1},和当前输入\boldsymbol{x}_t无关.

图6.8给出了GRU网络的循环单元结构.

7. 深层循环神经网络

如果将深度定义为网络中信息传递路径长度的话,循环神经网络可以看作既“深”又“浅”的网络.一方面来说,如果我们把循环网络按时间展开,长时间间隔的状态之间的路径很长,循环网络可以看作一个非常深的网络.从另一方面来说,如果同一时刻网络输入到输出之间的路径\boldsymbol{x}_t\rightarrow \boldsymbol{y}_t,这个网络是非常浅的.

因此,我们可以增加循环神经网络的深度从而增强循环神经网络的能力.增加循环神经网络的深度主要是增加同一时刻网络输入到输出之间的路径\boldsymbol{x}_t\rightarrow \boldsymbol{y}_t,比如增加隐状态到输出\boldsymbol{h}_t\rightarrow \boldsymbol{y}_t,以及输入到隐状态\boldsymbol{x}_t\rightarrow \boldsymbol{h}_t之间的路径的深度.

7.1 堆叠循环神经网络

一种常见的增加循环神经网络深度的做法是将多个循环网络堆叠起来,称为堆叠循环神经网络(Stacked Recurrent Neural Network,SRNN).一个堆叠的简单循环网络(StackedSRN)也称为循环多层感知器

图6.9给出了按时间展开的堆叠循环神经网络.第𝑙层网络的输入是第𝑙−1 层网络的输出.我们定义\boldsymbol{h}^{(l)}_t为在时刻𝑡时第𝑙层的隐状态

其中\boldsymbol{U}^{(l)}\boldsymbol{W}^{(l)}\boldsymbol{b}^{(l)}为权重矩阵和偏置向量,\boldsymbol{h}^{(0)}_t=\boldsymbol{x}_t. 

7.2 双向循环神经网络

在有些任务中,一个时刻的输出不但和过去时刻的信息有关,也和后续时刻的信息有关.比如给定一个句子,其中一个词的词性由它的上下文决定,即包含左右两边的信息.因此,在这些任务中,我们可以增加一个按照时间的逆序来传递信息的网络层,来增强网络的能力.

双向循环神经网络(Bidirectional Recurrent Neural Network,Bi-RNN)由两层循环神经网络组成,它们的输入相同,只是信息传递的方向不同. 假设第1层按时间顺序,第2层按时间逆序,在时刻𝑡时的隐状态定义为\boldsymbol{h}^{(1)}_t\boldsymbol{h}^{(2)}_t,则

其中⊕为向量拼接操作. 

图6.10给出了按时间展开的双向循环神经网络.

8. 扩展到图结构

如果将循环神经网络按时间展开,每个时刻的隐状态\boldsymbol{h}_t看作一个节点,那 么这些节点构成一个链式结构,每个节点𝑡都收到其父节点的消息(Message),更新自己的状态,并传递给其子节点.而链式结构是一种特殊的图结构,我们可以比较容易地将这种消息传递(Message Passing)的思想扩展到任意的图结构上。

8.1 递归神经网络

递归神经网络(Recursive Neural Network,RecNN)是循环神经网络在有向无循环图上的扩展.递归神经网络的一般结构为树状的层次结构,如图6.11a所示.

以图6.11a中的结构为例,有三个隐藏层\boldsymbol{h}_1\boldsymbol{h}_2\boldsymbol{h}_3,其中\boldsymbol{h}_1由两个输入层 \boldsymbol{x}_1\boldsymbol{x}_2计算得到,\boldsymbol{h}_2由另外两个输入层\boldsymbol{x}_3\boldsymbol{x}_4计算得到,\boldsymbol{h}_3由两个隐藏层\boldsymbol{h}_1\boldsymbol{h}_2计算得到. 对于一个节点\boldsymbol{h}_i,它可以接受来自父节点集合\pi_i中所有节点的消息,并更新自己的状态.

其中\boldsymbol{h}_{\pi_i}表示集合\pi_i中所有节点状态的拼接,𝑓(⋅)是一个和节点位置无关的非线性函数,可以为一个单层的前馈神经网络.比如图6.11a所示的递归神经网络具体可以写为

 其中𝜎(⋅)表示非线性激活函数,𝑾和𝒃是可学习的参数.同样,输出层𝑦可以为 一个分类器,比如

 其中𝑔(⋅)为分类器,𝑾′和𝒃′为分类器的参数.

当递归神经网络的结构退化为线性序列结构(见图6.11b)时,递归神经网络就等价于简单循环网络.

递归神经网络主要用来建模自然语言句子的语义. 给定一个句子的语法结构(一般为树状结构),可以使用递归神经网络来按照句法的组合关系来合成一个句子的语义.句子中每个短语成分又可以分成一些子成分,即每个短语的语义都可以由它的子成分语义组合而来,并进而合成整句的 语义.

同样,我们也可以用门控机制来改进递归神经网络中的长距离依赖问题, 比如树结构的长短期记忆模型(Tree-Structured LSTM)就是将LSTM模型的思想应用到树结构的网络中,来实现更灵活的组合函数.

8.2 图神经网络

图神经网络(GraphNeural Network,GNN)是将消息传递的思想扩展到图结构数据上的神经网络. 对于一个任意的图结构𝐺(𝒱,ℰ),其中𝒱表示节点集合,ℰ表示边集合.每条边表示两个节点之间的依赖关系.节点之间的连接可以是有向的,也可以是无向的.图中每个节点𝑣都用一组神经元来表示其状态\boldsymbol{h}^{(v)},初始状态可以为节点𝑣 的输入特征\boldsymbol{x}^{(v)}.每个节点可以收到来自相邻节点的消息,并更新自己的状态.

其中𝒩(𝑣)表示节点𝑣的邻居,\boldsymbol{m}^{(v)}_t表示在第𝑡时刻节点𝑣收到的信息,\boldsymbol{e}^{(u,v)}为边e^{(u,v)}上的特征. 公式(6.79)和公式(6.80)是一种同步的更新方式,所有的结构同时接受信息并更新自己的状态.而对于有向图来说,使用异步的更新方式会更有效率,比如循环神经网络或递归神经网络.在整个图更新𝑇次后,可以通过一个读出函数 (Readout Function)𝑔(⋅)来得到整个网络的表示: 

完。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐