LSTM是什么

LSTM即Long Short Memory Network,长短时记忆网络。它其实是属于RNN的一种变种,可以说它是为了克服RNN无法很好处理远距离依赖而提出的。

我们说RNN不能处理距离较远的序列是因为训练时很有可能会出现梯度消失,即通过下面的公式训练时很可能会发生指数缩小,让RNN失去了对较远时刻的感知能力。

∂E∂W=∑t∂Et∂W=∑tk=0∂Et∂nett∂nett∂st(∏tj=k+1∂st∂sk)∂sk∂W

解决思路

RNN梯度消失不应该是由我们学习怎么去避免,而应该通过改良让循环神经网络自己具备避免梯度消失的特性,从而让循环神经网络自身具备处理长期序列依赖的能力。

St=f(St−1,xt),根据链式求导法则会导致梯度变为连乘的形式,而sigmoid小于1会让连乘小得很快。为了解决这个问题,科学家采用了累加的形式,St=∑tτ=1ΔSτ,其导数也为累加,从而避免梯度消失。LSTM即是使用了累加形式,但它的实现较复杂,下面进行介绍。

LSTM模型

回顾一下RNN的模型,如下图,展开后多个时刻隐层互相连接,而所有循环神经网络都有一个重复的网络模块,RNN的重复网络模块很简单,如下下图,比如只有一个tanh层。 

python 神经网络 lstm 需要设置shuffle吗 lstm神经网络算法_Neural network

python 神经网络 lstm 需要设置shuffle吗 lstm神经网络算法_GRU_02

而LSTM的重复网络模块的结构则复杂很多,它实现了三个门计算,即遗忘门、输入门和输出门。每个门负责是事情不一样,遗忘门负责决定保留多少上一时刻的单元状态到当前时刻的单元状态;输入门负责决定保留多少当前时刻的输入到当前时刻的单元状态;输出门负责决定当前时刻的单元状态有多少输出。

python 神经网络 lstm 需要设置shuffle吗 lstm神经网络算法_LSTM_03

每个LSTM包含了三个输入,即上时刻的单元状态、上时刻LSTM的输出和当前时刻输入。

LSTM的机制

python 神经网络 lstm 需要设置shuffle吗 lstm神经网络算法_GRU_04

根据上图咱们一步一步来看LSTM神经网络是怎么运作的。

首先看遗忘门,用来计算哪些信息需要忘记,通过sigmoid处理后为0到1的值,1表示全部保留,0表示全部忘记,于是有

ft=σ(Wf⋅[ht−1,xt]+bf)

Wf是遗忘门的权重矩阵,σ为sigmoid函数,bf为遗忘门的偏置项。设输入层维度为dx,隐藏层维度为dh,上面的状态维度为dc,则Wf的维度为dc×(dh+dx)。

python 神经网络 lstm 需要设置shuffle吗 lstm神经网络算法_deep learning_05

其次看输入门,输入门用来计算哪些信息保存到状态单元中,分两部分,第一部分为

it=σ(Wi⋅[ht−1,xt]+bi)

该部分可以看成当前输入有多少是需要保存到单元状态的。第二部分为

c~t=tanh(Wc⋅[ht−1,xt]+bc)

该部分可以看成当前输入产生的新信息来添加到单元状态中。结合这两部分来创建一个新记忆。

python 神经网络 lstm 需要设置shuffle吗 lstm神经网络算法_Neural network_06

而当前时刻的单元状态由遗忘门输入和上一时刻状态的积加上输入门两部分的积,即

ct=ft∗ct−1+it∗c~t

python 神经网络 lstm 需要设置shuffle吗 lstm神经网络算法_RNN_07

最后看看输出门,通过sigmoid函数计算需要输出哪些信息,再乘以当前单元状态通过tanh函数的值,得到输出。

ot=σ(Wo⋅[ht−1,xt]+bo)

ht=ot∗tanh(ct)

python 神经网络 lstm 需要设置shuffle吗 lstm神经网络算法_deep learning_08

LSTM的训练

化繁为简,这里只讨论包含一个LSTM层的三层神经网络(如果有多个层则误差项除了沿时间反向传播外,还会向上一层传播),LSTM向前传播时与三个门相关的公式如下,

ft=σ(Wf⋅[ht−1,xt]+bf)

it=σ(Wi⋅[ht−1,xt]+bi)

c~t=tanh(Wc⋅[ht−1,xt]+bc)

ct=ft∗ct−1+it∗c~t

ot=σ(Wo⋅[ht−1,xt]+bo)

ht=ot∗tanh(ct)

ht有四个输入分量加权影响,即三个门相关的ftitc~tot,而且其中权重W都是拼接的,所以在学习时需要分割出来,即 Wf=Wfx+Wfh

Wi=Wix+Wih

Wc~=Wc~x+Wc~h

Wo=Wox+Woh

yit=Wyiht,输出为yot=σ(yit)。

Et=12(yd−yot)2,则某样本的损失为

E=∑Tt=1Et

δt=∂E∂ht,那么误差沿着时间反向传递则需要计算t-1时刻的误差项δt−1,则

δt−1=∂E∂ht−1=∂E∂ht∂ht∂ht−1=δt∂ht∂ht−1

ht可看成是一个复合函数,f[ft(ht−1),it(ht−1),c~t(ht−1),ot(ht−1)],由全导数公式有,

∂ht∂ht−1=∂ht∂ct∂ct∂ft∂ft∂netf,t∂netf,t∂ht−1+∂ht∂ct∂ct∂it∂it∂neti,t∂neti,t∂ht−1+∂ht∂ct∂ct∂c~t∂c~t∂netc~,t∂netc~,t∂ht−1+∂ht∂ot∂ot∂neto,t∂neto,t∂ht−1

netf,tneti,tnetc~,tneto,t表示对应函数的输入。将上述所有偏导都求出来,

∂ht∂ct=ot∗(1−tanh(ct)2)∂ct∂ft=ct−1∂ft∂netf,t=ft∗(1−ft)∂netf,t∂ht−1=Wfh

同样地,其他也可以求出来,最后得到t时刻和t-1时刻之间的关系。再设 

δf,t=∂E∂netf,tδi,t=∂E∂neti,tδc~,t=∂E∂netc~,tδo,t=∂E∂neto,t

得到, 

δt−1=δf,tWfh+δi,tWih+δc~,tWch+δo,tWoh

接着对某时刻t的所有权重进行求偏导, 

∂E∂Wfh,t=∂E∂netf,t∂netf,t∂Wfh,t=δf,tht−1

∂E∂Wih,t=∂E∂neti,t∂neti,t∂Wih,t=δi,tht−1

∂E∂Wch,t=∂E∂netc~,t∂netc~,t∂Wch,t=δc~,tht−1

∂E∂Woh,t=∂E∂neto,t∂neto,t∂Woh,t=δo,tht−1

∂E∂Wfx=∂E∂netf,t∂netf,t∂Wfx=δf,txt

∂E∂Wix=∂E∂neti,t∂neti,t∂Wix=δi,txt

∂E∂Wcx=∂E∂netc~,t∂netc~,t∂Wcx=δc~,txt

∂E∂Wox=∂E∂neto,t∂neto,t∂Wox=δo,txt

∂E∂bo,t=∂E∂neto,t∂neto,t∂bo,t=δo,t

∂E∂bf,t=∂E∂netf,t∂netf,t∂bf,t=δf,t

∂E∂bi,t=∂E∂neti,t∂neti,t∂bi,t=δi,t

∂E∂bc,t=∂E∂netc~,t∂netc~,t∂bc,t=δc~,t

对于整个样本,它的误差是所有时刻的误差之和,而与上个时刻相关的权重的梯度等于所有时刻的梯度之和,其他权重则不必累加,最终得到

∂E∂Wfh=∑j=1tδf,jhj−1

∂E∂Wih=∑j=1tδi,jhj−1

∂E∂Wch=∑j=1tδc~,jhj−1

∂E∂Woh=∑j=1tδo,jhj−1

∂E∂bf=∑j=1tδf,j

∂E∂bi=∑j=1tδi,j

∂E∂bc=∑j=1tδc~,j

∂E∂bo=∑j=1tδo,j

∂E∂Wfx=∂E∂netf,t∂netf,t∂Wfx=δf,txt

∂E∂Wix=∂E∂neti,t∂neti,t∂Wix=δi,txt

∂E∂Wcx=∂E∂netc~,t∂netc~,t∂Wcx=δc~,txt

∂E∂Wox=∂E∂neto,t∂neto,t∂Wox=δo,txt

================================================================================================================================

GRU神经网络

前面已经详细讲了LSTM神经网络(文末有链接回去),接着往下讲讲LSTM的一个很流行的变体。

GRU是什么

GRU即Gated Recurrent Unit。前面说到为了克服RNN无法很好处理远距离依赖而提出了LSTM,而GRU则是LSTM的一个变体,当然LSTM还有有很多其他的变体。GRU保持了LSTM的效果同时又使结构更加简单,所以它也非常流行。

GRU模型

回顾一下LSTM的模型,LSTM的重复网络模块的结构很复杂,它实现了三个门计算,即遗忘门、输入门和输出门。

python 神经网络 lstm 需要设置shuffle吗 lstm神经网络算法_LSTM_03

zt和rt。更新门用于控制前一时刻的状态信息被带入到当前状态中的程度,更新门的值越大说明前一时刻的状态信息带入越多。重置门用于控制忽略前一时刻的状态信息的程度,重置门的值越小说明忽略得越多。

python 神经网络 lstm 需要设置shuffle吗 lstm神经网络算法_Neural network_10

GRU向前传播

根据前面GRU模型图来一步步看他是怎么向前传播的,根据图不难得到以下式子: 

rt=σ(Wr⋅[ht−1,xt])

zt=σ(Wz⋅[ht−1,xt])

h~t=tanh(Wh~⋅[rt∗ht−1,xt])

ht=(1−zt)∗ht−1+zt∗h~t

yt=σ(Wo⋅ht)

其中[]表示两个向量相连接,*表示矩阵元素相乘。

GRU的训练

WrWzWhWo那些权重参数,其中前三个权重都是拼接的,所以在学习时需要分割出来,即

Wr=Wrx+Wrh

Wz=Wzx+Wzh

Wh~=Wh~x+Wh~h

yit=Woh,输出为yot=σ(yit)。

Et=12(yd−yot)2,则某样本的损失为

E=∑Tt=1Et

与前面LSTM网络类似,最终可以推出

∂E∂Wo=δy,tht

∂E∂Wzx=δz,txt

∂E∂Wzh=δz,tht−1

∂E∂Wh~x=δtxt

∂E∂Wh~h=δt(rt⋅ht−1)

∂E∂Wrx=δr,txt

∂E∂Wrh=δr,tht−1

δy,t=(yd−yot)⋅σ′

δh,t=δy,tWo+δz,t+1Wzh+δt+1Wh~h⋅rt+1+δh,t+1Wrh+δh,t+1⋅(1−zt+1)

δz,t=δt,h⋅(h~t−ht−1)⋅σ′

δt=δh,t⋅zt⋅ϕ′

δr,t=ht−1⋅[(δh,t⋅zt⋅ϕ′)Wh~h]⋅σ′