5

递归神经网络

 2 years ago
source link: https://blog.xpgreat.com/p/rnn_lstm_gru/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

递归神经网络是神经网络的一种,与其他神经网络不同点在于,它可以很好地处理序列数据,即前面的数据的输入与后面的输出是有关系的,比如一句话的语义理解。本文介绍了递归神经网络及其两个变种——LSTM和GRU,目的是梳理一下自己所理解的RRN,也希望能够给初次接触RRN的同学一点帮助。

其他神经网络的不足——为什么需要RRN?

传统神经网络的结构大多为输入-隐藏层(多个)-输出,即给定一组输入数据,输出结果,隐藏层像一个黑盒子,通过各种运算把输入的数据算成需要的结果。输入不同的数据运行两次,它们的结果是完全无关的。而有的时候我们需要处理一个序列,比如一个句子,它是单词的序列,要理解这句话中各个单词的意思,必须要结合语境,也就是要结合其他的单词的意思,一般情况下要结合这个单词前面的单词。例如前面两个词是我、吃,那么后面的一个词很大概率是一个表示食物的名词。

为了解决一些这样类似的问题,能够更好的处理序列的信息,RNN就诞生了。

RNN的结构

循环神经网络也由输入层、隐藏层和输出层构成,这是神经网络的基本结构,不同的是它的隐藏层(也叫cell)可以连续的接收输入xxx,输出ooo,而贯穿其中的sss可以存储这个网络的状态,也就是“记忆”到的前面发生的事情,利用它可以更加精准的预测后面的输出。

一个最简单的RNN结构如图所示,每一个cell输入一个xxx和一个sss,输出两个同样的hhh,通过下列算法算出:

st=tanh⁡(Wst−1+Uxt)ht=Vst \begin{aligned} &s_t = \tanh (Ws_{t-1} + Ux_t) \\&h_t = Vs_t \end{aligned} ​st​=tanh(Wst−1​+Uxt​)ht​=Vst​​

这种简单的结构虽然可以达到记忆的效果,然而存在着一个致命的问题:梯度爆炸梯度消失。即在多次循环后,利用梯度下降法调整,在求导的时候会出现∂Loss∂wi=∂Loss∂ft∂ft∂ft−1…∂fi∂wi\frac{\partial Loss}{\partial w_i} = \frac{\partial Loss}{\partial f_t}\frac{\partial f_t}{\partial f_{t-1}}…\frac{\partial f_i}{\partial w_i} ∂wi​∂Loss​=∂ft​∂Loss​∂ft−1​∂ft​​…∂wi​∂fi​​,如果∂ft∂ft−1\frac{\partial f_t}{\partial f_{t-1}}∂ft−1​∂ft​​部分大于或小于1,会出现类似1.01的99次方(或0.99的99次方)的问题,使得权重过大或过小,无法使用梯度下降。这一问题的根源就在于WWW和sss之间的乘法运算。为了解决这一问题,Hochreiter, Schmidhuber(1997)提出了LSTM。

LSTM全称Long Short Time Memory RRN,长短期记忆循环神经网络,它本质上也是一个循环神经网络,只是cell不一样而已,如下图:

LSTM的关键之处在于cell的状态,也就是图中贯穿顶部的那条水平线。Cell的状态像是一条传送带,它贯穿整条链,其中只发生一些小的线性作用。信息流过这条线而不改变是非常容易的。但是,LSTM也有能力移除或增加信息到cell状态中,由被称为门的结构精细控制。门是一种让信息可选地通过的方法。它们由一个sigmoid(S(t)=11+e−t S(t)={\frac {1}{1+e^{-t}}}S(t)=1+e−t1​)神经网络层和一个点乘操作组成。这里的sigmoid函数取0-1的值,充当了开关的作用,控制影响的程度。

从左往右看这幅图,首先第一步是决定我们需要从cell状态中扔掉什么样的信息。这个决策由一个称为“遗忘门(forget gate)”的sigmoid层决定。输入 ht−1h_{t-1}ht−1​ 和 xtx_txt​ ,输出一个0和1之间的数。1代表“完全保留这个值”,而0代表“完全扔掉这个值”。比如对于一个基于上文预测最后一个词的语言模型。cell的状态可能包含当前主题的信息,来预测下一个准确的词。而当我们得到一个新的语言主题的时候,我们会想要遗忘旧的主题的记忆,应用新的语言主题的信息来预测准确的词。

第二步是决定我们需要在cell state里存储什么样的信息。这个问题有两个部分。第一,一个sigmoid层调用“输入门(input gate)”以决定哪些数据是需要更新的。然后,一个tanhtanhtanh层为新的候选值创建一个向量 C~t\tilde{C}_tC~t​ ,这些值能够加入state中。下一步,我们要将这两个部分合并以创建对state的更新。

比如还是语言模型,可以表示为想要把新的语言主题的信息加入到cell state中,以替代我们要遗忘的旧的记忆信息。

在决定需要遗忘和需要加入的记忆之后,就可以更新旧的cell state Ct−1C_{t-1}Ct−1​ 到新的cell state CtC_tCt​ 了。在这一步,我们把旧的state Ct−1C_{t-1}Ct−1​ 与 ftf_tft​ 相乘,遗忘我们先前决定遗忘的东西,然后我们加上 it∗C~ti_t * \tilde{C}_tit​∗C~t​ ,这可以理解为新的记忆信息,当然,这里体现了对状态值的更新度是有限制的,我们可以把 iti_tit​ 当成一个权重。

最后,我们需要决定要输出的东西。这个输出基于我们的cell state,但会是一个过滤后的值。首先,我们运行一个sigmoid层,这个也就是输出门(output gate),以决定cell state中的那个部分是我们将要输出的。然后我们把cell state放进tanhtanhtanh(将数值压到-1和1之间),最后将它与sigmoid门的输出相乘,这样我们就只输出了我们想要的部分了。

在LSTM中,状态SSS通过累加的方式来计算,St=∑τ=1tΔSτS_t = \sum_{\tau=1}^t \Delta S_{\tau}St​=∑τ=1t​ΔSτ​,这样就不会是一直复合函数的形式了,它的导数也不是乘积的形式,这样就不会发生梯度消失的情况了。(具体论文:An Empirical Exploration of Recurrent Network Architectures 和 Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling)

GRU全称Gated Recurrent Unit,循环门单元。和LSTM一样,他也只是个cell的种类,本质上是RNN,由 Cho, et al. (2014)提出。它将LSTM的遗忘门和输入门组合成了一个新的更新门,合并了cell state和hidden state,比LSTM更加简单(尽管稍微难理解一些)。

从左往右看,前两个门是reset gate和update gate,计算方法:

rt=σ(Wrxt+Urht−1)zt=σ(Wzxt+Uzht−1) \begin{aligned} &r_t = \sigma (W^rx_t + U^rh_{t-1}) \\&z_t = \sigma (W^zx_t + U^zh_{t-1}) \end{aligned} ​rt​=σ(Wrxt​+Urht−1​)zt​=σ(Wzxt​+Uzht−1​)​

reset gate控制在计算候选状态时使用多少前序的状态,update gate则表示计算新状态时候选状态和原状态各取多少比例(注意特殊的“1-”门,表示把ztz_tzt​当作一个比例)。

总结和比较

RRN是神经网络的一个种类,LSTM和GRU是两种特殊的cell。与最基本的cell结构相比,LSTM和GRU都很好的解决了梯度爆炸和梯度消失的问题。对比LSTM,GRU的参数更少,因而训练稍快或需要更少的数据来泛化。另一方面,如果有足够的数据,LSTM的强大表达能力可能会产生更好的结果。Greff, et al. (2015)对流行的变种做了一个很好的比较,发现它们都是一样的。Jozefowicz, et al.(2015)测试了超过一万中RNN结构,发现某些任务情形下,有些比LSTM工作得更好,但那也是比较特殊的时候。

总的来说,没有通用的最好的模型,只能通过具体的数据和问题来选择模型。如果研究的数据序列会相互影响,比如做词语预测,那么LSTM-RRN和GRU-RRN不失为一种很好的选择。

参考:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK