RNN
原理:
RNN(Recurrent Neural Network)是一类用于处理序列数据的神经网络。时间序列数据是指在不同时间点上收集到的数据,这类数据反映了某一事物、现象等随时间的变化状态或程度。这是时间序列数据的定义,当然这里也可以不是时间,比如文字序列,但总归序列数据有一个特点——后面的数据跟前面的数据有关系。
RNN是神经网络的一种,类似的还有深度神经网络DNN,卷积神经网络CNN,生成对抗网络GAN等等。RNN对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息(理解上下文),利用了RNN的这种能力,使深度学习模型在解决语音识别、语言模型、机器翻译以及时序分析等NLP领域的问题时有所突破。
在普通的全连接网络或CNN中,每层神经元的信号只能向上一层传播,样本的处理在各个时刻独立,因此又被成为前向神经网络。而在RNN中,神经元的输出可以在下一个时间戳直接作用到自身,即第i层神经元在m时刻的输入,除了(i-1)层神经元在该时刻的输出外,还包括其自身在(m-1)时刻的输出,表示成图就是这样的:
可以看到在隐含层节点之间增加了互连。为了分析方便,常将RNN在时间上进行展开,得到如图所示的结构:
RNN通常会假定不同的层,共享一个Ws,这样可以有效减少训练参数。
RNN的局限:长期依赖(Long-TermDependencies)问题:
RNN的关键点之一就是他们可以用来连接先前的信息到当前的任务上,例如使用过去的视频段来推测对当前段的理解。如果RNN可以做到这个,他们就变得非常有用。但是还有很多依赖因素。有时候,仅仅需要知道先前的信息来执行当前的任务。例如,有一个语言模型用来基于先前的词来预测下一个词。如果试着预测这句话中“the clouds are in the sky”最后的这个词“sky”,并不再需要其他的信息,因为很显然下一个词应该是sky。在这样的场景中,相关的信息和预测的词位置之间的间隔是非常小的,RNN可以学会使用先前的信息。但是同样会有一些更加复杂的场景。比如试着去预测“I grew up in France...I speak fluent French”最后的词“French”。当前的信息建议下一个词可能是一种语言的名字,但是如果需要弄清楚是什么语言,是需要先前提到的离当前位置很远的“France”的上下文。这说明相关信息和当前预测位置之间的间隔就肯定变得相当的大。不幸的是,在这个间隔不断增大时,RNN会丧失学习到连接如此远的信息的能力。
在理论上,RNN绝对可以处理这样的长期依赖问题。人们可以仔细挑选参数来解决这类问题中的最初级形式,但在实践中,RNN则没法太好的学习到这些知识。Bengio,etal.(1994)等人对该问题进行了深入的研究,他们发现一些使训练RNN变得非常困难的相当根本的原因。换句话说,RNN会受到短时记忆的影响。如果一条序列足够长,那它们将很难将信息从较早的时间步传送到后面的时间步。因此,如果正在尝试处理一段文本进行预测,RNN可能从一开始就会遗漏重要信息。在反向传播期间(反向传播是一个很重要的核心议题,本质是通过不断缩小误差去更新权值,从而不断去修正拟合的函数),RNN会面临梯度消失的问题。因为梯度是用于更新神经网络的权重值(新的权值=旧权值-学习率*梯度),梯度会随着时间的推移不断下降减少,而当梯度值变得非常小时,就不会继续学习。
换言之,在递归神经网络中,获得小梯度更新的层会停止学习——那些通常是较早的层。由于这些层不学习,RNN会忘记它在较长序列中以前看到的内容,因此RNN只具有短时记忆。而梯度爆炸则是因为计算的难度越来越复杂导致。然而,幸运的是,有个RNN的变体——LSTM,可以在一定程度上解决梯度消失和梯度爆炸这两个问题!
LSTM
原理
Long ShortTerm网络——一般就叫做LSTM——是一种RNN特殊的类型,可以学习长期依赖信息。当然,LSTM和基线RNN并没有特别大的结构不同,但是它们用了不同的函数来计算隐状态。
LSTM的“记忆”叫做细胞/cells,可以直接把它们想做黑盒,这个黑盒的输入为前状态ht−1和当前输入xt。这些“细胞”会决定哪些之前的信息和状态需要保留/记住,而哪些要被抹去。实际的应用中发现,这种方式可以有效地保存很长时间之前的关联信息。
LSTM由Hochreiter&Schmidhuber(1997)提出,并在近期被AlexGraves进行了改良和推广。在很多问题,LSTM都取得相当巨大的成功,并得到了广泛的使用。LSTM通过刻意的设计来避免长期依赖问题。记住长期的信息在实践中是LSTM的默认行为,而非需要付出很大代价才能获得的能力!
所有RNN都具有一种重复神经网络模块的链式的形式。在标准的RNN中,这个重复的模块只有一个非常简单的结构,例如一个tanh层。
激活函数Tanh作用在于帮助调节流经网络的值,使得数值始终限制在-1和1之间。
红色是不同时间的输入X,蓝色链条是隐层状态S,绿色是网络输出y,长时记忆用C来表示:
以t时刻为例,和RNN相比,计算隐层状态St时,除了输入和前一时刻还要包含当前时刻的日记信息Ct
把St和Ct间的关联放大,包含了两步更细致的操作,删除旧日记,增添新日记。首先,函数f1就像是一块橡皮擦,根据昨天的记忆St-1和今天的输入Xt决定要修改日记中的那些记录。
Sigmoid在0-1之间,矩阵元素相乘时会抹掉那些取值为零的元素,相当于选择性遗忘了一部分记忆,因此常常被称为forget gate。过滤重要特征,忽略无关信息。
函数f2就像是一支铅笔,再次根据昨天的记忆和今天的输入,决定要在日记本上增加那些记录。
Sigmoid函数再次对内容进行了选择,tanh取值在-1-1之间,这步操作不是遗忘,而是相当于把这两天发生的事情进行梳理和归纳,因此也常常被称为input gate。
先用橡皮在日记本上删减,再用铅笔在日记本上增加记录,得到新日记ct,两步的公式为:
它除了会继续往下传递,同时会被用来更新当前短期记忆st,最后可以得到输出yt,同时保持短期记忆链st和长期记忆链ct并且相互更新,这就是LSTM的奥秘了。
把3D模型旋转90°,拉伸变形,然后把长期记忆链C投影到平面上,在扩展长短期记忆链之间的关联,可以对应上:
LSTM的核心思想
LSTM的关键就是细胞状态,水平线在图上方贯穿运行。细胞状态类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面流传保持不变会很容易。
LSTM有通过精心设计的称作为“门”的结构来去除或者增加信息到细胞状态的能力。门是一种让信息选择式通过的方法。他们包含一个sigmoid神经网络层和一个pointwise乘法的非线性操作。
如此,0代表“不许任何量通过”,1就指“允许任意量通过”!从而使得网络就能了解哪些数据是需要遗忘,哪些数据是需要保存。
LSTM拥有三种类型的门结构:遗忘门/忘记门、输入门和输出门,来保护和控制细胞状态。下面,依次来介绍这三个门。
遗忘门/忘记门:
在LSTM中的第一步是决定从细胞状态中丢弃什么信息。这个决定通过一个称为“忘记门”的结构完成。该忘记门会读取上一个输出ht−1和当前输入xt,做一个Sigmoid的非线性映射,然后输出一个向量ft(该向量每一个维度的值都在0到1之间,1表示完全保留,0表示完全舍弃,相当于记住了重要的,忘记了无关紧要的),最后与细胞状态Ct−1相乘。类比到语言模型的例子中,则是基于已经看到的预测下一个词。在这个问题中,细胞状态可能包含当前主语的性别,因此正确的代词可以被选择出来。看到新的主语,希望忘记旧的主语,进而决定丢弃信息。
输入门:
下一步是确定什么样的新信息被存放在细胞状态中。这里包含两个部分:
第一,sigmoid层称“输入门层”决定什么值我们将要更新;
第二,一个tanh层创建一个新的候选值向量C~t,会被加入到状态中。
下一步,会讲这两个信息来产生对状态的更新。
在语言模型的例子中,希望增加新的主语的性别到细胞状态中,来替代旧的需要忘记的主语,进而确定更新的信息。
细胞状态:
现在是更新旧细胞状态的时间了,Ct−1更新为Ct。前面的步骤已经决定了将会做什么,现在就是实际去完成。把旧状态与ft相乘,丢弃掉确定需要丢弃的信息,接着加上it∗C~t。这就是新的候选值,根据决定更新每个状态的程度进行变化。
在语言模型的例子中,这就是实际根据前面确定的目标,丢弃旧代词的性别信息并添加新的信息的地方,类似更新细胞状态。
输出门:
最终,需要确定输出什么值。这个输出将会基于我们的细胞状态,但是也是一个过滤后的版本。
首先,运行一个sigmoid层来确定细胞状态的哪个部分将输出出去。接着,把细胞状态通过tanh进行处理(得到一个在-1到1之间的值)并将它和sigmoid门的输出相乘,最终仅仅会输出我们确定输出的那部分。
在语言模型的例子中,因为他就看到了一个代词,可能需要输出与一个动词相关的信息。例如,可能输出是否代词是单数还是负数,这样如果是动词的话,也知道动词需要进行的词形变化,进而输出信息。