人工智能程序员面试笔试宝典
上QQ阅读APP看书,第一时间看更新

4.3 LSTM基础知识与PyTorch实战部分

由于传统的神经网络没有设计记忆结构,因此在处理序列数据上无所适从(即便经过特殊的处理),这不仅导致工作量变大,预测的结果也会受到很大的影响。循环神经网络(Recurrent Neural Network,RNN)针对BP神经网络的缺点,增加了信息跨时传递的结构。

对于RNN而言,每个时刻的隐藏层除了连接本期的输入层和输出层,还连接着上一时刻和下一时刻的隐藏单元,这也就是历史信息传递的方式。过去的信息正是通过这样的结构影响当期的输出。此外,在模型训练上,RNN虽然也是采用反向传播的方式,但跟BP模型不一样的是,它还包含从最后一个时间将累积的残差传递回来的过程。这种方法被称为基于时间的反向传播(Back Propagation Through Time,BPTT)。

传统的神经网络模型面对许多问题显得无能为力,因为同层的结点之间无连接,网络的传播也是顺序的。而循环神经网络对序列化数据有很强的模型拟合能力,因为它相比起ANN来讲是一种具有反馈结构的神经网络,其输出不但与当前输入和网络的权值有关,而且也与先前网络的输入有关。本节将介绍循环神经网络(RNN)及其变种长短时记忆网络(LSTM)、门控循环神经网络(GRU)。

4.3.1 什么是循环神经网络(RNN)

循环神经网络在隐含层会对之前的信息进行存储记忆,然后输入到当前计算的隐含层单元中,也就是隐含层的内部结点不再是相互独立的,而是互相有消息传递。RNN通过隐层神经元的记忆功能,实现了所有时刻的权重矩阵共享。在学习同样数量权重的情况下,相比于前馈神经网络,RNN用到的信息更少,也就是说在同样的信息下,RNN学习能力更强。其内部结构如图4-9所示。

图4-9 循环神经网络(RNN)的内部结构

1)xt表示第t步的输入。

2)St表示第t步隐藏层的状态,它是根据当前输入层的输出和上一时刻隐藏层的状态St-1进行计算的,公式如下:

st=f(Uxt+Wst-1)

其中U是输入层的连接矩阵,W是上一时刻隐含层到下一时刻隐含层的权重矩阵,f(x)一般是非线性的激活函数,例如tanh。

3)ht表示第t步的输出,输出层是连接状态,即它每个结点和隐含层的每个结点都互相连接,公式如下:

ht=g(Vst)

其中V是输出层的连接矩阵,g(x)是激活函数。

由该公式可以看出,RNN的输出值与前面多个时刻的历史输入值有关,这也是为什么循环神经网络处理序列数据建模效果好的原因。

普通RNN虽然具备一定的记忆功能,但是却不能很好地处理长期记忆问题。循环神经网络包含非常复杂的参数动态变化,这导致它非常难训练。RNN也是采用后向传播算法对权重和阈值进行优化,虽然可以将之前的隐层状态存储在记忆单元中,但对于处理相隔距离较远的信息却无能为力。当误差的权重大于1时,权重经过多次相乘会导致梯度爆炸的问题,而当误差的权重小于1时,经过多次传播,又会出现梯度消失的情况。RNN训练难的本质在于参数在时间结构的传递中被不断使用,即在不同的时间点反复使用,因此只要权重有微小的变化就有可能造成“蝴蝶效应”。

由于在计算梯度时,需要用到链式法则。而前面层的梯度是由后面层的梯度连乘得到的。而多个比较小的梯度相乘会使梯度值以指数级速度下降,最终在反向传播几步后就完全消失。同时由于RNN的学习依赖于激活函数和网络初始参数,如果梯度值太大,会产生梯度爆炸而不是梯度消失问题。

为了解决普通RNN在处理长时记忆时易出现梯度爆炸和梯度消失的问题,具有门控制功能的LSTM及其变体应运而生。

循环神经网络的优化算法和普通神经网络基本一致,均是利用了反向传播算法,但由于循环神经网络在结构上的特殊性,它采用的被称为基于时间的反向传播算法(BPTT),在这种算法下,在更新参数时,不仅是从输出端反向到隐藏层和输入端,而且是沿着时间——从未来向过去更新参数。

下面给出RNN详细的前向传播和反向传播的公式(忽略偏置):

i:输入神经元;F:输入神经元数量;

h:隐藏层神经元;H:隐藏层神经元数量;

k:输出神经元;K:输出神经元;

U:从输入层到隐藏层的权重向量;V:从隐藏层到输出层的权重向量;

W:上一时刻的隐藏层连接到这一时刻隐藏层的权重向量;

t时刻输入层到隐藏层的输出,该输出并未经过激活函数;

t时刻经由激活函数后的输出值;

t时刻隐藏层的残差。

(1)前向传播

t时刻的为下式:

经由激活函数后的输出值为

输出层的计算为:

根据前向传播的公式就可以看到RNN与BP模型的区别,即在t时刻隐藏层的输入上,除了来自t时刻的输入,还有来自t-1时刻隐藏层的信息。

(2)反向传播

RNN的反向传播采用的是BPTT的方法,其残差的公式如下:

值得注意的是,整个RNN网络共享同一组参数。

t时刻损失函数对于参数的求导公式分别如下:

而根据BPTT的算法,RNN的参数导数为各时间点上导数之和:

4.3.2 RNN的梯度消失问题以及代码展示

RNN神经网络的优点在于引入了记忆结构,可以处理过去对未来有较大影响的时间序列数据,因此,在这类问题的处理上,RNN模型要优于BP模型。但同样地,RNN所利用BPTT算法去求解最优参数依然会面临梯度消失的问题,因此,当某个时刻的神经元和未来时间相隔较远时,该神经元的权重可能面临无法调节的情况,因此这也导致了RNN模型并不能处理长期依赖的问题。

梯度消失原因的公式推导如下:

T时刻预测值与真实值的误差为LT,则利用链式法则有:

其中:

又由于ht=f(Uxt+Wht-1)且:

则记:

其中δw,δh分别表示正则化的上界,将上式代入原连乘的式子有:

由于计算梯度时前面层的梯度是由后面层的梯度连乘得到的,而多个比较小的梯度相乘会使梯度值以指数级速度下降,最终在反向传播几步后就完全消失。同时由于RNN的学习依赖于激活函数和网络初始参数,如果值太大,会产生梯度爆炸而不是梯度消失问题。

RNN代码展示如下:

4.3.3 什么是长短时记忆网络(LSTM)

LSTM模型属于循环神经网络,这类神经网络主要是解决传统的神经网络不具备记忆能力的缺陷。它们的结构中,隐藏层不仅仅和本时刻的输入层和输出层相连接,同时也和过去时刻的状态相连,即过去的信息可以通过这个连接将信息传递到此刻,因此在该类神经网络具有记忆性。从网络结构设计的角度来说,LSTM对RNN的改进主要体现在通过门控制器增加了对不同时刻记忆的权重控制,以及加入跨层连接削减梯度消失问题的影响。如果一个事件非常重要,则输入门就按重要程度将短期记忆合并进行进长期记忆,或者通过遗忘门忘记部分长期记忆,按比例替换为现在的新记忆。而在最后,输出门会基于长期记忆和短期记忆综合判断到底应该有什么样的输出。基于这样的控制机制,LSTM对于长序列的理解分析能力大幅提高,在多种应用中都取得了非常好的效果。

总之改进点是:通过在LSTM模型中设计了一个记忆单元,并通过一个叫作忘记门的控制单元来选择将过去的信息保留多少,当忘却门为1时,代表全部保留过去的信息,而当为0时,代表全部忘记过去的信息,介于0~1,则是部分保留过去的信息;由于这个设定,在LSTM单元中总是保留有稳定的误差流,这样可以使得在反向传播时,始终不会出现梯度消失的现象。

其内部结构如4-10图所示。

图4-10 LSTM算法内部结构图

第一层是忘记层,该层决定细胞状态中丢弃什么信息。把ht-1xt拼接起来传给sigmoid函数并输出0~1之间的值,并将这个值乘到细胞状态ct-1上去。sigmoid函数的输出值直接决定了状态信息保留多少。

ft=σ(Wf·[ht-1,xt]+bf)

下一步是更新层的细胞状态。tanh层是用来产生更新值的候选项,输出值为[-1,1],则意味着细胞状态在某些维度上需要加强,在某些维度上需要减弱;而sigmoid层的输出值要乘到tanh层的输出上,起到一个缩放的作用,在极端情况下sigmoid输出0说明相应维度上的细胞状态不需要更新。

下一步是旧的细胞状态Ct-1与忘记门ft(f是forget忘记门的意思)相乘来丢弃一部分信息,再加需要更新的部分,这就生成了新的细胞状态

最后是输出部分。输出值跟细胞状态有关,把Ct输给一个tanh函数得到输出值的候选项。sigmoid层会决定候选项中的哪些部分最终会被输出。

ot=σ(Wo· [ht-1,xt]+bo)

ht=ot∗tanh(Ct)

具体来讲,输入门控制了记忆单元的入口,只有当输入门是打开状态时,输入数据才能进入记忆单元,当输入门关闭时,数据不能进入,输入门打开与否是由神经网络学习到的参数决定的。遗忘门决定了记忆单元中的信息是保留还是遗忘,即控制上一时刻进入记忆单元中的信息有多少可以累积到当前时刻,这部分信息将最终汇总到输出门处理。遗忘门开启时记忆单元中的信息被保留,遗忘门关闭时信息被遗忘,遗忘门的开闭状态也是由神经网络学习的权重决定的。输出门是记忆单元的出口,它决定了外部的单元是否可以从记忆单元中读取信息,即控制多少信息可以流入到当前隐层。当输出门打开时数据可读,输出门关闭时数据不可读,同样,输出门的开闭状态是由神经网络学习到的。

LSTM的历史信息累计靠记忆单元的自连接实现,通过“遗忘门”过滤上一时刻记忆单元的信息,并通过“输入门”控制新信息的输入,从而实现了对历史信息的线性累积。隐层状态是根据记忆单元状态计算的,由上面的公式可知记忆单元是线性更新的,因此经过非线性函数tanh再结合输出门的信息得到当前隐含层状态。

总之LSTM与传统的RNN相比,多了3个基于sigmoid函数的“门”来控制信息的流量,通过对历史信息的线性累积,实现了时间序列预测的“长程依赖”。可以有效地解决简单RNN容易出现梯度消失的问题。针对股票预测问题,其处理的时序跨度可以更广,可以有效地捕捉数据中的时序特征,提高模型的预测能力。

RNN和LSTM模型最大的不同在于LSTM模型不仅可以保存来自过去的信息,还可以通过遗忘门决定保存多少过去的信息,在这样的设定下,LSTM模型既克服了RNN模型的长期依赖问题(RNN无法处理超长序列),也克服了RNN模型在训练时产生的梯度爆炸和梯度消失的问题。

LSTM代码展示如下:

以下使用两种方式来实现LSTM:一种是直接调用函数实现;另一种是自己写LSTM函数实现,目的是希望完全熟悉LSTM的内部结构。

第一种是直接调用PyTorch中的nn.LSTM实现:

第二种是自己编写LSTM算法:

4.3.4 什么是门控循环神经网络(GRU)

门限循环单元(Gated Recurrent Unit,GRU),是LSTM的一个变体,GRU在保持了LSTM的效果的同时,结构更加简单。相比于LSTM的三道控制门,GRU只用两个控制门,它将输入门和遗忘门合并成为一体——更新门,并且不把线性更新积累到记忆单元中,而是直接线性累加到隐层状态中,并通过门来控制。其内部结构如图4-11所示。

图4-11 GRU算法内部结构图

相比于LSTM,GRU最大的改进在于更新门,更新门用于控制前一隐层到当前隐层的信息流量,更新门的值越大,从前一隐层流入进当前隐层的信息就越多,更新门的值越小,信息流入的就越少。重置门的作用是判断是否放弃前一隐层的状态,重置门的值越大,上一隐层的状态保留的就越多,重置门的值越小,上一隐层的状态保留的就越少。GRU的数学表达如下:

其中zt是更新门,它有机融合了LSTM中的输入门和忘记门,rt是重置门,用来控制是否要放弃之前的隐层状态。其余部分与LSTM类似,这里不再赘述。

GRU中的更新门相当于LSTM中的输入门与遗忘门的联动,它的结构比LSTM更简单,需要的参数更少,但效果堪比LSTM,在训练时鲁棒性也更好。实验证明,在参数相同的情况下,GRU比LSTM表现好,由于模型更加简化,调参相对简单,可以节省更多的时间,在训练集样本较少的情况下比LSTM更友好。

GRU代码展示如下: