起源

全连接神经网络能够很好地拟合复杂的样本特征,卷积神经网络能很好地建模局部与全局特征的关系。但它们都只能处理定长的输入、输出,而自然语言的处理对象一般是变长的语句,句子中各元素出现的顺序先后暗含着时序关系,循环神经网络(Recurrent Neural Network,下称RNN)能够较好地处理这种关系。


基本结构

RNN的基本思想是:将处理对象在时序上分解为具有相同结构的单元,单元间有着时序关联,即本单元接收上一时序对应单元的输出,并把计算结果输出到下一时序对应的单元。网络结构由这样一系列的单元构成,能够在时序上进行展开。
笔记(总结)-循环神经网络
可以看到每一时刻,隐层不仅接收输入,还接收了上一时刻隐层的输出,综合计算得到该时刻的隐层输出。公式化过程如下:


ht={0,                    t=0f(xt,ht1),    otherwise

给出框架图和具体化公式如下:
笔记(总结)-循环神经网络


ht=f(Wxt+Uht1+b)yt=softmax(Vht)

RNN每个时刻都有输入、输出。由公式可以看到,每个时刻的输入(初始时刻必须有输入)、输出其实也是可以去除的,这样就得到了以RNN为基础的不同类型的网络架构:
笔记(总结)-循环神经网络
其中one to one架构就退化为了普通的前馈神经网络架构。而其它不同的变种可用于不同的时间序列相关场景,比如对齐的many to many可以用来做序列标注,针对当前时刻的词进行标注;错开的many to many适合做机器翻译,当源语句全部输入网络后,才开始逐步翻译过程。


RNN的训练

由于RNN涉及时间序列的运算,我们使用BPTT(Back Propagation Through Time)进行参数更新,即梯度需要沿着时间序列回流到最初的时间点。
笔记(总结)-循环神经网络

假设我们采用对齐的many to many架构,每个时刻都有一个监督值tt,损失为Jt,定义损失函数如下:


Jt=ttlogytJ=t=1TJt=t=1Tttlogyt

其中yt定义如上,则有J关于V的梯度为:


JV=t=1TJtVJtV=Jtytytztztht,     yt=softmax(zt),  zt=Vht

J关于U的梯度为:


JtU=JththtU

由于htht1,U的函数,而ht1又是ht2,U的函数…所以ht是关于ht1,ht2,...,h1,U的函数,可以得到(注:ht的链式求导展开,建议手算一遍):


htU=k=1ththkhkU

其中:


hthk=i=k+1thihi1=i=k+1tUTdiag[f(hi1)]

则有:


JU=t=1TJthtk=1t{i=k+1tUTdiag[f(hi1)]}hkU

由于W也在f函数中,类似于U,我们可以得到:


JW=t=1TJthtk=1t{i=k+1tUTdiag[f(hi1)]}hkW

可以看到,JUJW两部分都涉及到了连乘,当连乘项数很多,且乘子UT<1时,梯度便会接近于0;而当乘子UT>1时,梯度便会接近于无穷,这就是RNN的梯度消失/梯度爆炸的问题。这导致RNN只能学习到短周期的关系,当周期过长(连乘项很多),便会导致学习过程出问题,因此也叫长期依赖问题


RNN的改进方案——LSTM、GRU

长短时记忆神经网络(Long Short-Term Memory Neural Network,下称LSTM)是RNN的一个变体,可以有效地解决简单循环神经网络的梯度消失/爆炸问题。LSTM 模型的关键是引入了一组记忆单元(Memory Units),允许网络学习何时遗忘历史信息,何时用新信息更新记忆单元。在时刻 t 时,记忆单元ct记录了到当前时刻为止的所有历史信息,并受三个“门”控制:输入门 it , 遗忘门ft和输出门ot 。三个门的元素的值在[0, 1] 之间。LSTM与原始RNN对比如下:
笔记(总结)-循环神经网络
可以直观感受到,原始RNN中,梯度流向的路线是相对单一的,而在LSTM中通过三个门的控制,使得梯度流向更加得复杂,公式如下:

ft=σ(Wfxt+Ufht1+bf)it=σ(Wixt+Uiht1+bi)ot=σ(Woxt+Uoht1+bo)ct=tanh(Wcxt+Ucht1)ct=ftct1+itctht=ottanh(ct)

遗忘门ft控制每一个内存单元需要遗忘多少信息,输入门it控制每一个内存单元需要加入多少新的信息,输出门ot控制每一个内存单元输出多少信息,σ是logsitic函数。那么这样改进有什么好处呢?以hU为例,转化为求hchoct是由两部分求和构成,避免了在求导连乘时过大或过小的情况,ot同理。通过引入门控制,将梯度分流到了不同的部分,也就极大地降低了梯度消失/爆炸出现的风险。

可是LSTM在实际使用过程中带有大量的参数,且其中门的功能多少有重叠。既想要在保持效果的基础上加快训练速度,又要杜绝梯度消失/爆炸的出现。于是就有了LSTM的简化版本——门限循环单元(Gated Recurrent Unit,下称GRU)。GRU将输入门和遗忘门合并成一个门:更新门(Update Gate),同时还合并了记忆单元ct和隐层输出ht,更新门zt控制当前的状态需要遗忘多少历史和接收多少新信息。重置门rt用来控制接收信息中有多少时来自于历史信息。GRU视图与公式如下:
笔记(总结)-循环神经网络


基于RNN模型基础单元衍生出的LSTM、GRU,能够很好地服务于上文提到的几种架构。在解决了梯度消失/爆炸的问题后,RNN-Based模型能够很好地处理较长的序列。本篇到此为止,就不再细致讲具体应用了。