[神经网络与深度学习][6][循环神经网络]

第6章 循环神经网络

经验是智慧之父,记忆是智慧之母.——谚语

前馈神经网络中,信息的传递是单向的,这种限制虽然使得网络变得更容易学习,但在一定程度上也减弱了神经网络模型的能力.在生物神经网络中,神经元之间的连接关系要复杂得多.前馈神经网络可以看作一个复杂的函数,每次输入都是独立的,即网络的输出 只依赖 于当前的输入.但是在很多现实任务中,网络的输出不仅和当前时刻的输入相关,也和其过去一段时间的输出相关.比如一个有限状态自动机,其下一个时刻的状态(输出)不仅仅和当前输入相关,也和当前状态(上一个时刻的输出)相关.此外,前馈网络难以处理时序数据,比如视频、语音、文本等.时序数据的长度一般是不固定的,而前馈神经网络要求输入和输出的维数都是固定的,不能任意改变.因此,当处理这一类和时序数据相关的问题时,就需要一种能力更强的模型.

循环神经网络(Recurrent Neural Network,RNN)是一类具有短期记忆能力神经网络.在循环神经网络中,神经元不但可以接受其他神经元的信息,也可以接受自身的信息,形成具有环路的网络结构.

循环神经网络的参数学习可以通过随时间反向传播算法 来学习.随时间反向传播算法即按照时间的逆序错误信息一步步地往前传递

输入序列比较长时,会存在梯度爆炸消失问题,也称为长程依赖问题.为了解决这个问题,人们对循环神经网络进行了很多的改进,其中最有效的改进方式引入门控机制(Gating Mechanism).

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

6.1 给网络增加记忆能力

为了处理这些时序数据利用其历史信息, 我们需要网络具有短期记忆能力

一般来讲,我们可以通过以下三种方法来给网络增加短期记忆能力

6.1.1 延时神经网络

加一个延时存储单元。在第t 个时刻第𝑙 层神经元活性值依赖于第𝑙 − 1 层神经元最近𝐾 个时刻的活性值

一种简单利用历史信息的方法是建立一个额外的延时单元,用来存储网络的历史信息(可以包括输入、输出、隐状态等).比较有代表性的模型是延时神经网络

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

ht(l)=f(ht(l1),ht1(l1),,htk(l1))h^{(l)}_t = f(h^{(l−1)}_t , h^{(l−1)}_{t-1} , ⋯ , h^{(l−1)}_{t-k})

6.1.2 有外部输入的非线性自回归模型

自回归模型(AutoRegressive Model,AR)是统计学上常用的一类时间序列模型,用一个变量yty_t历史信息预测自己

yt=w0+k=1Kwkytk+ϵty_t = w_0 + \sum ^K _{k=1} w_ky_{t-k} + \epsilon_t

  • 其中KK为超参数
  • w0,,wKw_0, ⋯ , w_K可学习参数
  • ϵtN(0,σ2)\epsilon_t ∼ N(0, \sigma^2) 为第tt个时刻的噪声,方差σ2\sigma ^2和时间无关.

外部输入非线性自回归模型(Nonlinear AutoRegressive with Exogenous Inputs Model,NARX)是自回归模型扩展,在每个时刻t 都有一个外部输入xtx_t产生一个输出yty_tNARX通过一个延时器 记录 最近KxK_x 次的外部输入最近KyK_y次的输出,第t 个时刻的输出𝒚𝑡 为

yt=𝑓(xt,xt1,,xtKx,yt1,yt2,,yt𝐾y)y_t = 𝑓(x_t, x_{t-1}, ⋯ , x_{t−K_x} , y_{t−1}, y_{t−2}, ⋯ , y_{t−𝐾_y} )

其中𝑓(⋅) 表示非线性函数,可以是一个前馈网络,KxK_xKyK_y超参数

6.1.3 循环神经网络

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

给定一个输入序列x1T=(x1,x2,,xt,,xT)x_{1∶T} = (x_1, x_2, ⋯ , x_t, ⋯ , x_T ),循环神经网络通过下面公式更新 带反馈边的 隐藏层的活性值hth_t

ht=𝑓(ht1,xt)h_t = 𝑓(h_{t−1}, x_t)

其中h0=0h_0 = 0𝑓(⋅) 为一个非线性函数,可以是一个前馈网络.

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

循环神经网络可以看成一个动力系统.隐藏层的活性值hth_t在很多文献上也称为状态(State)或隐状态(Hidden State).

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

理论上,循环神经网络可以近似任意的非线性动力系统前馈神经网络可以模拟任何连续函数,而循环神经网络可以模拟任何程序

6.2 简单循环网络

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

令向量xtRMx_t \in R^M 表示在时刻tt时网络的输入htRDh_t \in R^D 表示隐藏层状态(即隐藏层神经元活性值),则hth_t不仅和当前时刻的输入xtx_t 相关,也和上一个时刻的隐藏层状态𝒉t1𝒉_{t−1} 相关.简单循环网络在时刻t的更新公式

zt=Uht1+Wxt+b,\boldsymbol z_t = U \boldsymbol h_{t−1} + W \boldsymbol x_t + \boldsymbol b,

ht=f(zt)h_t = f(z_t)

  • 其中ztz_t为隐藏层的净输入
  • UR𝐷×𝐷U \in R^{𝐷×𝐷}状态-状态权重矩阵
  • WRD×MW \in R^{D×M}状态-输入权重矩阵
  • bRDb \in R^D偏置向量
  • f()f(⋅)非线性激活函数,通常为Logistic函数或Tanh 函数

上述公式通常表示为

ht=f(Uht1+Wxt+b)\boldsymbol h_t = f(U\boldsymbol h_{t-1} + W\boldsymbol x_t + \boldsymbol b)

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

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

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

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

6.2.1.2 图灵完备

图灵机是一种抽象的信息处理装置,可以用来解决所有的可计算问题

图灵完备(Turing Completeness)是指一种数据操作规则,比如一种计算机编程语言,可以实现图灵机(Turing Machine)的所有功能解决所有的可计算问题

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

6.3 应用到机器学习

循环神经网络可以应用到很多不同类型机器学习任务

根据这些任务的特点可以分为以下几种模式:

  • 序列到类别模式
  • 同步的序列到序列模式
  • 异步的序列到序列模式

6.3.1 序列到类别模式

序列到类别模式主要用于序列数据分类问题:输入为序列,输出为类别.比如在文本分类中,输入数据为单词的序列,输出为该文本的类别.

假设一个样本 x1T=(x1,,xT)x_{1∶T} = (x_1, ⋯ , x_T) 为一个长度为TT序列输出为一个类别 y(1,,C)y \in (1, ⋯ , C).我们可以将样本xx 按不同时刻输入到循环神经网络中,并得到不同时刻的隐藏状态h1,,hTh_1, ⋯ , h_T.我们可以hTh_T 看作整个序列的最终表示(或特征),并输入给分类器g(.)g(.) 进行分类(如图6.3a所示),即

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

y^=g(1Tt=1Tht)\hat y = g(\frac 1 T \sum ^T _{t=1} \boldsymbol h_t)

6.3.2 同步的序列到序列模式

同步的序列到序列模式主要用于序列标注(Sequence Labeling)任务,即每一时刻都有输入和输出,输入序列输出序列长度相同.比如在词性标注(Part-of-Speech Tagging)中,每一个单词都需要标注其对应的词性标签.

同步的序列到序列模式(如图6.4所示)中,输入为一个长度为TT的序列x1T=(x1,,xT)x_{1∶T} = (x_1, ⋯ , x_T)输出序列y1T=(y1,,yT)y_{1∶T} = (y_1, ⋯ , y_T)样本𝒙不同时刻输入循环神经网络中,并得到不同时刻的隐状态h1,,hTh_1, ⋯ , h_T.每个时刻的隐状态hth_t代表了当前时刻和历史的信息,并输入给分类器g(.)g(.)得到当前时刻的标签y^t\hat y_t,即

6.3.3 异步的序列到序列模式

异步的序列到序列模式也称为编码器-解码器(Encoder-Decoder)模型,即输入序列和输出序列不需要有严格的对应关系,也不需要保持相同的长度.比如在机器翻译中,输入为源语言的单词序列,输出为目标语言的单词序列.

在异步的序列到序列模式中,输入为长度为TT的序列x1T=(x1,,xT)x_{1∶T} = (x_1, ⋯ , x_T ),输出为长度为MM的序列y1:M=(y1,...,yM)y_{1:M} = (y_1, ..., y_M)

异步的序列到序列模式一般通过先编码 后解码的方式来实现.

  1. 将样本𝒙 按不同时刻 输入到一个循环神经网络(编码器)中,并得到其编码h𝑇h_𝑇
  2. 然后再使用另一个循环神经网络(解码器),得到输出序列y1My_{1∶M}.为了建立输出序列之间的依赖关系,在解码器中通常使用非线性的自回归模型

f1()f_1(⋅)f2()f_2(⋅) 分别为用作编码器解码器循环神经网络,则编码器-解码器模型可以写为

6.4 参数学习

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

以随机梯度下降为例,给定一个训练样本(x,y)(\boldsymbol x, \boldsymbol y),其中x1:T=(x1,...,xT)\boldsymbol x_{1:T} = (\boldsymbol x_1, ... ,\boldsymbol x_T)为长度是𝑇 的输入序列,𝑦1∶𝑇 = (𝑦1, ⋯ , 𝑦𝑇 ) 是长度为𝑇 的标签序列.即在每个时刻tt,都有一个监督信息yty_t,我们定义时刻tt的损失函数为

Lt=L(yt,g(ht))L_t = L(y_t, g(\boldsymbol h_t))

  • 其中g(ht)g(\boldsymbol h_t)为第tt时刻的输出,
  • LL为可微分的损失函数,比如交叉熵.

那么整个序列的损失函数为

L=t=1TLtL = \sum ^T _{t=1} L_t

整个序列的损失函数LL关于参数UU的梯度为

δLδU=t=1TδLtδU\frac {\delta L} {\delta \boldsymbol U} = \sum ^T _{t=1} \frac {\delta L_t} {\delta \boldsymbol U}

每个时刻损失LtL_t对参数UU偏导数之和

在循环神经网络中主要有两种计算梯度的方式:

  • 随时间反向传播(BPTT)算法
  • 实时循环学习(RTRL)算法

6.4.1 随时间反向传播算法

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

BPTT 算法将循环神经网络看作一个展开的多层前馈网络

  • 其中“每一层”对应循环网络中的“每个时刻”(见图6.2).
  • 这样,循环神经网络就可以按照前馈网络中的反向传播算法计算参数梯度.
  • 在“展开”的前馈网络中,所有层的参数共享的,因此参数的真实梯度所有“展开层”的参数梯度之和

6.4.1.1 计算偏导数δLtδU\frac {\delta L_t} {\delta U}

因为参数UU和隐藏层在每个时刻k(1kt)k(1 \leq k \leq t)净输入zk=Uhk1+Wxk+b\boldsymbol z_k = U\boldsymbol h_{k-1} + W\boldsymbol x_k + \boldsymbol b有关,因此第tt时刻的损失函数LtL_t关于参数ui,ju_{i,j}的梯度为:

δLtδui,j=k=1tδ+ztδui,jδLtδzt6.31\frac {\delta L_t} {\delta u_{i,j}} = \sum ^t _{k=1} \frac {\delta ^+ \boldsymbol z_t} {\delta u_{i,j}} \frac {\delta L_t} {\delta \boldsymbol z_t} (6.31)

定义误差项δt,k=δLtδzk\delta_{t,k} = \frac {\delta L_t} {\delta {\boldsymbol z_k}}tt时刻的损失kk时刻隐藏神经层的净输入zk\boldsymbol z_k的导数,则当1kt1 \leq k \leq t

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

6.4.1.2 参数梯度

整个序列的损失函数LL关于参数UU的梯度

δLδU=t=1Tk=1tδt,khk1T\frac {\delta L} {\delta {\boldsymbol U}} = \sum ^T _{t=1} \sum ^t _{k=1} \delta_{t,k} \boldsymbol h^T_{k-1}

同理可得,LL关于权重W\boldsymbol W和偏置b\boldsymbol b的梯度为

δLδW=t=1Tk=1tδt,kxkT\frac {\delta L} {\delta {\boldsymbol W}} = \sum ^T _{t=1} \sum ^t _{k=1} \delta_{t,k} \boldsymbol x^T_{k}

δLδb=t=1Tk=1tδt,k\frac {\delta L} {\delta {\boldsymbol b}} = \sum ^T _{t=1} \sum ^t _{k=1} \delta_{t,k}

6.4.1.3 计算复杂度

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

6.4.2 实时循环学习算法

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

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

ht+1=f(zt+1)=f(Uht+Wxt+1+b)\boldsymbol h_{t+1} = f(\boldsymbol z_{t+1}) = f(\boldsymbol U \boldsymbol h_t + \boldsymbol W \boldsymbol x_{t+1} + \boldsymbol b)

其关于参数ui,ju_{i,j}的偏导数为

RTRL 算法从第1个时刻开始,除了计算循环神经网络的隐状态之外,还利用公式(6.45) 依次前向计算偏导数δh1δui,j\frac {\delta \boldsymbol h_1} {\delta u_{i,j}}δh2δui,j\frac {\delta \boldsymbol h_2} {\delta u_{i,j}}

δh3δui,j\frac {\delta \boldsymbol h_3} {\delta u_{i,j}},…

这样,假设第tt个时刻存在一个监督信息,其损失函数为LtL_t,就可以同时计算损失函数对ui,ju_{i,j}的偏导数

Ltδui,j=δhtδui,jδLtδht\frac {L_t} {\delta u_{i,j}} = \frac {\delta \boldsymbol h_t} {\delta u_{i,j}} \frac {\delta L_t} {\delta \boldsymbol h_t}

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

6.4.3 两种算法的比较

RTRL算法和BPTT算法都是基于梯度下降的算法,分别通过前向模式反向模式应用链式法则计算梯度

  • 循环神经网络中,一般网络输出维度远低于输入维度,因此BPTT 算法的计算量会更小,但是BPTT 算法需要保
    存所有时刻的中间梯度,空间复杂度较高
  • RTRL 算法不需要梯度回传,因此非常适合用于需要在线学习无限序列的任务中.

6.5 长程依赖问题

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

在BPTT 算法中,将公式(6.36)

展开得到

如果定义$ \gamma \cong ||diag(f’(\boldsymbol z _{\tau} )U^T||$,则

δt,kγtkδt,t\delta _{t,k} \cong \gamma^{t-k} \delta_{t,t}

  • 若𝛾 > 1,当𝑡 − 𝑘 → ∞ 时,γtk\gamma^{t−k} → ∞.当间隔𝑡 − 𝑘 比较大时,梯度也变得很大,会造成系统不稳定,称为梯度爆炸问题(Gradient Exploding Problem).
  • 相反,若𝛾 < 1,当𝑡 − 𝑘 → ∞ 时,γtk0\gamma^{t-k} → 0.当间隔𝑡 − 𝑘 比较大时,梯度也变得非常小,会出现和深层前馈神经网络类似的梯度消失问题(Vanishing Gradient Problem)

要注意的是,在循环神经网络中的梯度消失不是说δLtδU\frac {\delta L_t} {\delta U}的梯度消失了,而是δLtδhk\frac {\delta L_t} {\delta h_k}的梯度消失了(当间隔tkt-k比较大时).也就是说,参数𝑼 的更新主要靠当前时刻tt的几个相邻状态hkh_k来更新长距离的状态对参数UU没有影响

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

虽然简单循环网络理论上可以建立长时间间隔的状态之间的依赖关系但是由于梯度爆炸或消失问题,实际上只能学习到短期的依赖关系.

这样,如果时刻tt的输出yt\boldsymbol y_t依赖于时刻kk的输入xk\boldsymbol x_k,当间隔tkt-k比较大时,简单神经网络很难建模这种长距离的依赖关系,称为长程依赖问题(Long-Term Dependencies Problem).

6.5.1 改进方案

比较有效的方式是通过改进模型或优化方法来缓解循环网络的梯度爆炸和梯度消失问题.

6.5.1.1 梯度爆炸的改进

一般而言,循环网络的梯度爆炸问题比较容易解决,一般通过权重衰减梯度截断避免

权重衰减是通过给参数增加l1l_1l2l_2范数的正则化项来限制参数的取值范围,从而使得𝛾 ≤ 1.

梯度截断是另一种有效的启发式方法,当梯度的模大于一定阈值时,就将它截断成为一个较小的数.

6.5.1.2 梯度消失的改进

梯度消失是循环网络的主要问题.除了使用一些优化技巧外,更有效的方式就是改变模型

可以将ht=f(Uht1+Wxt+b)\boldsymbol h_t = f(U \boldsymbol h_{t-1} +W \boldsymbol x_t + \boldsymbol b)中的U=IU = I,同时令δhtδht1=I\frac {\delta h_t} {\delta h_{t-1}} = I为单位矩阵,即

ht=ht1+g(xt;θ)\boldsymbol h_t = \boldsymbol h_{t-1} + g(\boldsymbol x_t;\theta)

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

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

ht=ht1+g(xt;ht1;θ)\boldsymbol h_t = \boldsymbol h_{t-1} + g(\boldsymbol x_t;\boldsymbol h_{t-1}; \theta)

这样hth_tht1h_{t-1}之间为既有线性关系也有非线性关系,并且可以缓解梯度消失问题.

但这种改进依然存在两个问题:

  1. 梯度爆炸问题
  2. 记忆容量问题:随着hth_t不断累积存储新的输入信息,会发生饱和现象.假设g(.)g(.)为Logistic 函数,则随着时间tt的增长,ht\boldsymbol h_t会变得越来越大,从而导致hh变得饱和.也就是说,隐状态hth_t可以存储的信息是有限的,随着记忆单元存储的内容越来越多,其丢失的信息也越来越多.

logistic函数

6.6 基于门控的循环神经网络

为了改善循环神经网络的长程依赖问题, 一种非常好的解决方案是在公式(6.50)的基础上引入门控机制控制信息的累积速度,包括有选择地加入新的信息,并有选择地遗忘之前累积的信息

主要介绍两种基于门控的循环神经网络:

  • 长短期记忆网络(LSTM)
  • 门控循环单元网络(GRU)

6.6.1 长短期记忆网络

在公式ht=ht1+g(xt;ht1;θ)\boldsymbol h_t = \boldsymbol h_{t-1} + g(\boldsymbol x_t;\boldsymbol h_{t-1}; \theta)的基础上,LSTM 网络主要改进在以下两个方面

6.6.1.1 新的内部状态

LSTM 网络引入一个新的内部状态(internal state)ctRD\boldsymbol c_t \in R^D.内部状态ct\boldsymbol c_t通过下面公式计算:

ct=ftct1+itc^t\boldsymbol c_t = \boldsymbol f_t \odot \boldsymbol c_{t-1} + \boldsymbol i_t \odot \boldsymbol {\hat c_t}

ht=ottanh(ct)\boldsymbol h_t = \boldsymbol o_t \odot tanh(\boldsymbol c_t)

  • 其中ft[0,1]D\boldsymbol f_t \in [0,1]^Dit[0,1]D\boldsymbol i_t \in [0,1]^Dot[0,1]D\boldsymbol o_t \in [0,1]^D为三个(gate)来控制信息传递的路径。
  • \odot向量元素乘积
  • ct1\boldsymbol c_{t-1}上一时刻的记忆单元
  • c^tRD\boldsymbol {\hat c_t} \in R^D通过非线性函数得到的候选状态c^t=tanh(Ucht1+Wcxt+bc)\boldsymbol {\hat c_t} = tanh(U_c\boldsymbol h_{t-1} + W_c\boldsymbol x_t + \boldsymbol b_c)

在每个时刻tt,LSTM网络的内部状态ct\boldsymbol c_t记录了到当前时刻为止的历史信息.

6.6.1.2 门控机制

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

LSTM 网络引入门控机制(Gating Mechanism)来控制信息传递的路径.公式(6.51) 和公式(6.52) 中三个“门”分别为输入门it\boldsymbol i_t遗忘门ft\boldsymbol f_t输出门ot\boldsymbol o_t.这三个门的作用为

  1. 遗忘门ftf_t控制上一个时刻的内部状态ct1c_{t-1}需要遗忘多少信息
  2. 输入门iti_t控制当前时刻的候选状态ctc_t有多少信息需要保存
  3. 输出门oto_t 控制当前时刻的内部状态ctc_t有多少信息需要输出给外部状态hth_t

例如:

  • ft=0,it=1f_t = 0, i_t = 1时,记忆单元将历史信息清空,并将候选状态向量c^t\boldsymbol {\hat c_t}写入.
  • ft=1,it=0f_t = 1, i_t = 0时,记忆单元将复制上一时刻的内容不写入新的信息

LSTM 网络中的“门”是一种**“软”门**,取值在(0, 1) 之间,表示以一定的比例允许信息通过

三个门的计算方式为:

it=σ(Uiht1+Wixt+bi)\boldsymbol {i_t} = \sigma(U_i\boldsymbol h_{t-1} + W_i\boldsymbol x_t + \boldsymbol b_i)

ft=σ(Ufht1+Wfxt+bf)\boldsymbol {f_t} = \sigma(U_f\boldsymbol h_{t-1} + W_f\boldsymbol x_t + \boldsymbol b_f)

ot=σ(Uoht1+Woxt+bo)\boldsymbol {o_t} = \sigma(U_o\boldsymbol h_{t-1} + W_o\boldsymbol x_t + \boldsymbol b_o)

  • 其中𝜎(⋅) 为Logistic 函数,其输出区间为(0, 1),
  • 𝒙𝑡 为当前时刻的输入,
  • 𝒉𝑡−1 为上一时刻的外部状态.

下图给出了 LSTM 网络的循环单元结构,其计算过程为:

  1. 首先利用上一时刻的外部状态ht1\boldsymbol h_{t-1}和当前时刻的输入xt\boldsymbol x_t,计算出三个门,以及候选状态c^t\boldsymbol {\hat c_t}
  2. 结合遗忘门ft\boldsymbol f_t和输入门it\boldsymbol i_t来更新记忆单元ct\boldsymbol c_t
  3. 结合输出门it\boldsymbol i_t,将内部状态的信息传递给外部状态ht\boldsymbol h_t

6.6.2 LSTM网络的各种变种

6.6.2.1 无遗忘门的LSTM 网络

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

ct=ct1+itc^t\boldsymbol c_t = \boldsymbol c_{t-1} + \boldsymbol i_t \odot \boldsymbol {\hat c_t}

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

6.6.2.2 peephole 连接

另外一种变体是三个门不但依赖于输入xt\boldsymbol x_t 和上一时刻的隐状态ht1\boldsymbol h_{t-1},也依赖于上一个时刻的记忆单元ct1\boldsymbol c_{t-1},即

it=σ(Uiht1+Wixt+Vict1+bi)\boldsymbol {i_t} = \sigma(U_i\boldsymbol h_{t-1} + W_i\boldsymbol x_t + V_i\boldsymbol c_{t-1} + \boldsymbol b_i)

ft=σ(Ufht1+Wfxt+Vfct1+bf)\boldsymbol {f_t} = \sigma(U_f\boldsymbol h_{t-1} + W_f\boldsymbol x_t + V_f\boldsymbol c_{t-1} + \boldsymbol b_f)

ot=σ(Uoht1+Woxt+Voct1+bo)\boldsymbol {o_t} = \sigma(U_o\boldsymbol h_{t-1} + W_o\boldsymbol x_t + V_o\boldsymbol c_{t-1} + \boldsymbol b_o)

6.6.2.2 将输入门和遗忘门耦合

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

ct=(1it)ct1+itc^t\boldsymbol c_t = (\boldsymbol 1 - \boldsymbol i_t) \odot \boldsymbol c_{t-1} + \boldsymbol i_t \odot \boldsymbol {\hat c_t}

6.6.3 门控循环单元网络(Gated Recurrent Unit,GRU)

GRU 网络引入门控机制来控制信息更新的方式.和LSTM 不同,GRU 不引入额外的记忆单元,GRU 网络也是在公式ht=ht1+g(xt,ht1;θ)\boldsymbol h_t = \boldsymbol h_{t-1} + g(\boldsymbol x_t, \boldsymbol h_{t-1}; \theta)的基础上引入一个更新门(Update Gate)来控制当前状态需要从历史状态中保留多少信息,以及需要从候选状态中接受多少新信息,即

ht=ztht1+(1zt)g(xt,ht1;θ)\boldsymbol h_t = \boldsymbol z_t \odot \boldsymbol h_{t-1} +(1 - \boldsymbol z_t) \odot g(\boldsymbol x_t, \boldsymbol h_{t-1}; \theta)

其中zt[0,1]D\boldsymbol z_t \in [0,1]^D更新门

zt=σ(Wzxt+Uzht1+bz)\boldsymbol z_t = \sigma(W_z \boldsymbol x_t + U_z \boldsymbol h_{t-1} + \boldsymbol b_z)

LSTM 网络中,输入门和遗忘门是互补关系,具有一定的冗余性GRU 网络直接使用一个门控制输入和遗忘之间的平衡

  • zt=0\boldsymbol z_t = \boldsymbol 0时,当前状态ht\boldsymbol h_t和前一时刻的状态ht1\boldsymbol h_{t-1}之间为非线性函数关系;
  • zt=0\boldsymbol z_t = \boldsymbol 0时,ht\boldsymbol h_tht1\boldsymbol h_{t-1}之间为线性函数关系.

在GRU 网络中,函数$g(\boldsymbol x_t, \boldsymbol h_{t-1}; \theta) $的定义为

h^t=g(xt,ht1;θ)=tanh(Whxt+Uh(rtht1)+bn)\boldsymbol {\hat h_t} = g(\boldsymbol x_t, \boldsymbol h_{t-1}; \theta) = tanh(\boldsymbol W_h\boldsymbol x_t + \boldsymbol U_h(\boldsymbol r_t \odot \boldsymbol h_{t-1}) + \boldsymbol b_n)

  • 其中h^t\boldsymbol {\hat h_t}表示当前时刻的候选状态
  • rt[0,1]D\boldsymbol r_t \in [0, 1]^D重置门:$\boldsymbol r_t =\sigma(W_r \boldsymbol x_t + U_r \boldsymbol h_{t-1} + \boldsymbol b_r) $

rt\boldsymbol r_t用来控制候选状态h^t\boldsymbol {\hat h_t}的计算是否依赖上一时刻的状态h^t1\boldsymbol {\hat h_{t-1}}

  • rt=0\boldsymbol r_t = 0,候选状态h^t=tanh(Whxt+bn)\boldsymbol {\hat h_t} = tanh(\boldsymbol W_h\boldsymbol x_t + \boldsymbol b_n),即只和当前输入xt\boldsymbol x_t相关和历史状态无关.
  • rt=1\boldsymbol r_t = 1,候选状态h^t=tanh(Whxt+Uhht1+bn)\boldsymbol {\hat h_t} = tanh(\boldsymbol W_h\boldsymbol x_t + \boldsymbol U_h \boldsymbol h_{t-1} + \boldsymbol b_n)和当前输入𝒙𝑡 以及历史状态𝒉𝑡−1 相关,和简单循环网络一致.

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

image-20201023204148468

6.7 深层循环神经网络

如果将深度定义为网络中信息传递路径长度的话,循环神经网络可以看作**既“深”又“浅”**的网络.

  • 一方面来说,如果我们把循环网络按时间展开,长时间间隔的状态之间的路径很长,循环网络可以看作一个非常深的网络.
  • 从另一方面来说,如果同一时刻网络输入到输出之间的路径xtyt\boldsymbol x_t \rarr \boldsymbol y_t,这个网络是非常的.

因此,我们可以增加循环神经网络的深度从而增强循环神经网络的能力.增加循环神经网络的深度主要是增加同一时刻网络输入到输出之间的路径xtyt\boldsymbol x_t \rarr \boldsymbol y_t

  • 比如增加隐状态到输出htyt\boldsymbol h_t \rarr \boldsymbol y_t
  • 以及输入到隐状态xtht\boldsymbol x_t \rarr \boldsymbol h_t之间的路径的深度

6.7.1 堆叠循环神经网络

一种常见的增加循环神经网络深度的做法将多个循环网络堆叠起来,称为堆叠循环神经网络(Stacked Recurrent Neural Network,SRNN).

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

ht(l)=f(U(l)ht1(l)+W(l)ht(l1)+b(l))\boldsymbol h_t ^{(l)} = f(U^{(l)}\boldsymbol h^{(l)}_{t-1} + W^{(l)}\boldsymbol h^{(l-1)}_t + \boldsymbol b^{(l)})

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

6.7.2 双向循环神经网络

在有些任务中,一个时刻的输出不但和过去时刻的信息有关,也和后续时刻的信息有关

比如给定一个句子,其中一个词的词性由它的上下文决定,即包含左右两边的信息.

因此,在这些任务中,我们可以增加一个按照时间的逆序来传递信息的网络层,来增强网络的能力.

双向循环神经网络(Bidirectional Recurrent Neural Network,Bi-RNN)由两层循环神经网络组成,它们的输入相同,只是信息传递的方向不同

假设第1 层按时间顺序,第2 层按时间逆序,在时刻tt时的隐状态定义为ht(1)\boldsymbol h_t^{(1)}ht(2)\boldsymbol h^{(2)}_t ,则

ht(1)=f(U(1)ht1(1)+W(1)xt+b(1))\boldsymbol h_t^{(1)} = f(U^{(1)} \boldsymbol h^{(1)}_{t-1} + W^{(1)} \boldsymbol x_t + \boldsymbol b^{(1)})

ht(2)=f(U(2)ht+1(2)+W(2)xt+b(2))\boldsymbol h_t^{(2)} = f(U^{(2)}\boldsymbol h^{(2)}_{t+1} + W^{(2)}\boldsymbol x_t + \boldsymbol b^{(2)})

ht=ht(1)ht(2)\boldsymbol h_t = \boldsymbol h_t^{(1)} \oplus \boldsymbol h_t^{(2)}

其中\oplus向量拼接操作

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

6.8 扩展到图结构

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

6.8.1 递归神经网络

递归神经网络(Recursive Neural Network,RecNN)是循环神经网络在有向无循环图上的扩展

递归神经网络的一般结构为树状的层次结构,如图6.11a所示.

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

对于一个节点hi\boldsymbol h_i,它可以接受来自父节点集合πi\pi_i中所有节点的消息,并更新自己的状态.

hi=f(hπi)\boldsymbol h_i = f(\boldsymbol h_{\pi_i})

  • 其中hπi\boldsymbol h_{\pi_i}表示集合πi\pi_i所有节点状态拼接
  • f(.)f(.)是一个和节点位置无关的非线性函数,可以为一个单层的前馈神经网络

比如上图所示的递归神经网络具体可以写为

  • 其中σ(.)\sigma (.)表示非线性激活函数
  • WWb\boldsymbol b可学习的参数

同样,输出层𝑦 可以为一个分类器

y=g(Wh3+b)y = g(W'\boldsymbol h_3 + \boldsymbol b')

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

6.8.2 图神经网络

在实际应用中,很多数据图结构的,比如知识图谱、社交网络、分子网络等.而前馈网络反馈网络难处理图结构的数据

图神经网络(Graph Neural Network,GNN)是将消息传递的思想扩展到图结构数据上的神经网络

对于一个任意的图结构G(v,ε)G(v, \varepsilon)

  • 其中𝒱 表示节点集合,ℰ 表示边集合.
  • 每条边表示两个节点之间的依赖关系.
  • 节点之间的连接可以是有向的,也可以是无向的.
  • 图中每个节点𝑣 都用一组神经元来表示其状态𝒉(𝑣),初始状态可以为节点𝑣的输入特征𝒙(𝑣).
  • 每个节点可以收到来自相邻节点的消息,并更新自己的状态.

mt(v)=uN(v)f(ht1(v),ht1(u),e(e,v))\boldsymbol m^{(v)}_t = \sum _{u \in N(v)} f(\boldsymbol h^{(v)}_{t-1}, h^{(u)}_{t-1}, \boldsymbol e^{(e,v)})

ht(v)=g(ht1(v),mt(v))\boldsymbol h^{(v)}_t = g(\boldsymbol h^{(v)}_{t-1}, \boldsymbol m^{(v)}_t)

  • 𝒩(𝑣) 表示节点𝑣 的邻居集合
  • mt(v)\boldsymbol m^{(v)}_t表示在第tt时刻节点vv收到的信息
  • e(u,v)\boldsymbol e^{(u,v)}为边e(u,v)e^{(u,v)}上的特征.

在整个图更新TT次后,可以通过一个读出函数(Readout Function)g(.)g(.)来得到整个网络的表示:

ot=g({hT(v)vV})\boldsymbol o_t = g(\{\boldsymbol h^{(v)} _T | v \in V\})