在观摩了李宏毅老师讲解的LSTM以后感觉豁然开朗,其实并没有很多教程里面说得那么晦涩。

理解LSTM有三个步骤,为什么,是什么,怎么用。

我们知道,用MLP和CNN这些网络在处理图像信息是比较work的。但是在处理语音这种序列信息时,其performance就一般了。比如我想要在某知名订票软件DTrip上预定机票,对手机说了一句“I will arrive Beijing on Oct. 1st.”。我们希望说出这句话以后,系统能帮我们识别出目的地和时间。我们可以很清楚的认识到,一般情况下,arrive后面的单词就是目的地,on后面的短语大部分表示日期,而传统的MLP或者CNN显然缺乏根据上下文做分析的能力。

RNN

RNN的出现能够让之前序列的一些信息被记住,其结构如下图所示:

LSTM的通俗易懂理解

下面黄色的方块代表输入是一个2维向量,两个绿色的神经元表示hidden layer,红色的神经元表示output,而左侧的两个蓝色方块,表示的就是RNN的精髓所在,即每一次前向传播时,都将绿色神经元的输出拷贝到蓝色方块中,在序列的下一个元素输入时,绿色神经元的计算值由输入(黄色)的线性变换和上一次保存的值(蓝色)两部分构成。

假设上述网络中所有的权值都为1,一开始的蓝色方块值都为0,黄色输入都为1。那很容易算出两个绿色神经元输出都是2,红色的都是4,此时2被拷贝到蓝色方块中做下一次运算。第二次的运算过程如下图:

LSTM的通俗易懂理解
计算过程与上面一样,不再赘述,此时蓝色方块中的值应被更新为两个6,再做下一次运算,以此类推。

可以看出,RNN考虑了上下文的关系,即后面的判断和决策,不仅仅是由当前的数据决定,还会受到前文中一些数据特征的影响。因此回到一开始的那句话“I will arrive Beijing on Oct. 1st.”,如果此时的输入是“Beijing”,那么此时的RNN中会保存之前“arrive”的某些信息,所以如果有足够的知识,更容易判定此时的输入“Beijing”就是目的地。

RNN在语音识别、机器翻译等一些需要用到序列数据的领域,取得了非常好的成果。

那么为什么还要有LSTM这么看似复杂的模型呢?RNN的问题在于他不能处理“长依赖”的问题,在上面的算法中,我们是用到的是一些近期的信息来处理当前的任务,比如“arrive”和“Beijing”是相邻的,“on”和“Oct. 1st”也是挨着的。

如果现在的输入变成 “我今天跑了马拉松,健身房撸了铁,但是没吃饭,所以饿晕了”。我们显然,这个句子的结局是我饿晕了。但是在RNN中,“饿晕了”一词表示非常疑惑,到底是谁饿晕了。因为“饿晕了”和“我”相距实在是太远了,一个在句首,一个在句末,导致中途失去了“我”的信息,从而RNN无法做到有效的学习。

因此RNN更适合做短期一些的学习,而长期的信息就会被遗忘掉。但幸好LSTM可以用来做稍长期一些的task。

LSTM

LSTM和RNN有相似之处,就是可以存储前面序列的一些信息。一个LSTM的结构如下图所示:
LSTM的通俗易懂理解
乍一看LSTM的架构比较复杂,但其实梳理一下并不难。首先LSTM由四个部分组成,输入门、输出门、遗忘门和记忆细胞。首先网络的其他部分有一个输入,该输入想进入LSTM首先要经过输入门的同意,如果输入门不同意,则该输入无法对LSTM的cell值产生影响;如果输入门同意,则根据遗忘门的遗忘程度来确定之前信息的保存情况,再和这个输入相加,组成新的cell值。输出门决定是否将这个cell值输出。

所以一个LSTM有四个输入,对应下图中的zzziz_{i}zfz_{f}zoz_{o};还有一个输出aa。下图表示的是一个LSTM的运算过程:
LSTM的通俗易懂理解
首先每一个圆圈里面代表的都是Sigmoid函数,目的是将实数集映射到 [0,1] 内。首先输入 zz 经过一个Sigmoid变换得到 g(z)g(z) ,Input Gate的输入 ziz_{i} 经过Sigmoid变换得到 f(zi)f(z_{i})。随后在第一个黑色节点出将两者相乘,得到 g(z)f(zi)g(z)f(z_{i}),可见如果 f(zi)f(z_{i}) 的值越接近0,表示拒绝 g(z)g(z) 进入LSTM;如果 f(zi)f(z_{i}) 越接近于1,表示允许输入 g(z)g(z) 进入LSTM。

在得到了 g(z)f(zi)g(z)f(z_{i}) 以后,就需要根据遗忘门和原来的cell值,计算出新的cell值。首先将遗忘门输入 zfz_{f} 做Sigmoid变换,得到 f(zf)f(z_{f}),随后将 f(zf)f(z_{f}) 和原来的记忆细胞值 cc 做乘法,得到 cf(zf)cf(z_{f}),最后加上之前的输入 g(z)f(zi)g(z)f(z_{i}),就得到新的记忆细胞值 cc',即:

c=g(z)f(zi)+cf(zf)c'=g(z)f(z_{i})+cf(z_{f})

然后 cc' 经过一个Sigmoid以后得到 h(c)h(c') ,再根据输出门输入 zoz_{o} 做Sigmoid以后得到的 f(zo)f(z_{o}),就可以计算输出 a=h(c)f(zo)a=h(c')f(z_{o})。和输入门大同小异,如果 f(zo)f(z_{o}) 接近1,此时的输出值与 h(c)h(c') 基本一致,表示允许 cc' 输出;f(zo)f(z_{o}) 接近0,此时的 h(c)h(c') 接近于0,表示拒绝输出。

那LSTM的长相和传统的神经网络很不一样,怎么能建立一种联系呢?其实把LSTM换一种形式来画,会发现和传统的神经网络还是蛮像的:
LSTM的通俗易懂理解

输入值 xtx^{t} 经过一系列transform以后,得到了LSTM的四个输入,在分别进行一系列的变换得到输出 yty^{t}。这样直觉上LSTM就和平常的神经网络长得比较像了。

实际应用中还有一些额外的连接和trick,这里就不再展开了。

本人纯属小白,有不妥的地方望指正交流~

PS:图片来自李宏毅老师机器学习课件。

相关文章: