前言:网上关于LSTM的介绍实在太多,作为小白一个,自然不能够与大神相提并论。希望通过写这篇博客,整理一下自己的收获,如有错误之处,请各位前辈批评指正!因为作者水平有限,只希望能够向读者简单的介绍下LSTM。更为详细的过程,请再去查阅相关资料。(适合新手!)
希望通过这篇文章能够说明以下三个问题:
1. 为什么要有LSTM?
2. LSTM是什么?
3. LSTM的简单计算过程。
废话少说,开始吧!
一、 为什么要有LSTM?
要想回答这个问题,那就避不开RNN。所以简单介绍一下RNN吧!
循环神经网络RNN(Recurrent Neural Network)
RNN的出现是基于一种特别的需求:如果当前状态不仅仅受当前输入的影响还受上一个状态的影响,那常规的神经网络是无法处理的。可将其理解为==“时序”==。举几个应用的例子:语音识别,自然语言处理,机器翻译,天气预测,故障检测等等。这些任务的特点都是之前的状态可能会影响之后的状态。而RNN就是专门为解决这类问题而设计的。说完了RNN的背景,再来看看RNN的具体结构吧:
RNN的标准结构如下图所示:
从这个图中不难看到,在隐藏层构成了一个闭环循环,这即是RNN完成特定功能的方法,也是名字中“循环”两字的由来。
虽然标准结构比较简洁,但不是特别易于理解,所以常常使用展开结构作为研究的对象(展开结构就是把循环变成了一个个独立个体):
那有一个问题来了:为什么把RNN划入深度神经网络模型中呢?我们都知道CNN里面确实有很多层(池化层,卷积层等),比如VGG(19层),ResNet(152层)。那RNN里面的“深度”从何说起呢?
其实是这样的:RNN中循环可看作为时序,如果以每一个时钟作为一个状态,那在一段时间内就会存在多个状态,状态之间可看作为层与层之间的关系,层一多,深度也就产生了。也可简单的理解为CNN是空间上的深度,RNN是时间上的深度(个人观点,不知道是否正确)。
以上简要介绍了RNN(更为详细的,请去网上参照更优秀的文章)。但好像还是没有提到为什么会有LSTM。其实LSTM是RNN的一种改进版本,也就是LSTM也是RNN,不过略有不同。RNN同样具有深度网络学习中一个很严重的问题:梯度爆炸/梯度消失,下面简单介绍一下:
梯度爆炸/梯度消失
神经网络的模型训练大致可分为两部分:前向预测过程和反向训练过程。梯度爆炸/梯度消失就发生在反向训练的过程。基于前面的时序结构和神经网络模型的特性,前面神经元对后面神经元的影响体现在层与层权重乘法上。这种说法没有得到老师的赞同,说是一种表面的理解,希望有的大神能给我一个更有效地解答
梯度计算的详细过程可参考博客:https://zhuanlan.zhihu.com/p/28687529
最后可得到梯度计算的表达式如下图:
梯度可分为两部分tanh’和W(s)。
注:tanh是激活函数的一种,此处对其求导。可证明tanh’的取值范围为[0,1]。W(s)是梯度的输入。
梯度消失:
当W(s)较小时,每一梯度都在[0,1]范围。当t较大时,得到的结果就会趋近于0。可类比于0.1^100=0
梯度爆炸:
当W(s)较大时,每一梯度都大于1。当t较大时,得到的结果就会趋近于无穷大。可类比于10^100=∞
上面从数学上解释了一下梯度爆炸和消失。那到底是什么意思呢?看下面这个图:
之前介绍到RNN以时序为基础,前面状态会影响后面状态。那影响大小呢?就近似可以理解为梯度大小。在长期依赖(两个状态离的较远)的情况下如果梯度太小,发生了梯度消失现象说明前面状态对当前状态因为层数太多/相差太远影响消失。这种影响消失可能不是我们所期望的,所以问题就产生了!同理,梯度爆炸则是前面状态对当前状态的影响过于巨大,相对改变了离当前状态较近的状态影响。
换一种角度理解梯度消失/梯度爆炸:梯度消失就是对于具有长期依赖关系的神经元影响较小,当前状态被短期依赖关系的神经元所左右。梯度爆炸就是对于具有长期依赖关系的神经元影响太大,当前状态被长期依赖关系的神经元左右,而忽略掉了短期依赖关系的神经元影响。(有点儿绕,不过意思很直接~)
LSTM的目的就是为了缓解传统RNN网络中梯度爆炸/梯度消失这一现象
二、 什么是LSTM?
长短期记忆网络LSTM(Long short-term memory )
Ps:这里有个点需要注意下:单横线一定要放在short和term之间,不能放在long和short之间。LSTM本质还是short-term,只不过比较long~
我们先从功能上理解LSTM,也就是LSTM是怎么缓解梯度消失/梯度爆炸的?
再次必须明确一个概念:LSTM只是缓解了梯度消失/梯度爆炸,而不是完全解决,原因会在后面进行解释。
我简单将其总结为:乘法变加法。梯度爆炸/梯度消失的原因就是不断乘法,最终导致参数呈现指数级增长和下降,进而产生了不好影响。而加法则不会有这种问题,加法基本不会改变数量级。下面来更详细阐述如何实现的:
下面分析下LSTM的具体结构:
LSTM在RNN标准模型的基础上增加了三个门:遗忘门(forget gate),输入门(input gate),输出门(output gate)。三个门恰好可以把LSTM分成三部分结构,整个LSTM的实现也是围绕这三个门来的。
上面那个图有点儿抽象,找不到门,我又找了一张更清晰的:
从两张图可以清晰的看到,神经元的核心操作变成了+(也就是最中间的圈加一个+),这个+也是连接逐个模块的枢纽。
看到这儿为止!你可能还会说还是不懂LSTM,你也没说明白LSTM是神马啊。别急,相信看完LSTM的计算过程后,你会找到答案的。
三、 LSTM的简单计算过程
看看这个图,找找LSTM有几个输入,几个输出?
结果就是三个输入,三个输出。那都代表什么呢?X(t)代表当前神经元的输入,h(t-1)和C(t-1)代表前一神经元的输入。C(t)和h(t斜)代表当前神经元要提供给下一神经元的(也就是下个阶段的h(t)和c(t-1)),即下一层训练的输入。另外一个h(t)就是当前神经元的细胞输出。
那有个问题来了:**为什么上一神经元会给两个输入呢?**其实这就是LSTM保持远端状态的奥秘所在。C(t-1)叫做long-term memory,h(t-1)叫做work-memory。从上面的图可以看到,c(t)和c(t-1)连接是一条直线,而h(t)和h(t-1)则相对曲折。当很多个时序连在一起时c(t-1)这条直线更容易追溯到远端的情况,而h(t-1)则更多反应了上一神经元的状态。
再多问个为什么?为什么这里面是c和h(是其他24个英文字母不香吗?)。其实都有其代表的含义:c代表cell,以细胞状态来描述当前神经元的状态。H代表hide,即隐藏层,也就是上一神经元的输入。(隐藏层一般指深度网络中除了输入和输出的其他层,这里的隐藏层可以理解为相对于本层的直接输入层)明白这个更能理解c(t-1)和h(t-1)的关系了吧。
下面再详细的分析一下计算步骤:
我先把这个计算式子列出来,看不懂没关系。看完后面的内容再回来看就很清晰了。
我先解释下里面参数的含义,并且计算也需要一些先修知识,我也介绍一下。
W(f),W(i),W©,W(o)为权重矩阵
b(f),b(i),b©,b(o)为偏置常数
以上两部分都是神经网络模型训练的必要部分,也是模型训练的修改对象。
那tanh和σ 呢?其实这是两种激活函数:
σ (sigmoid)
对于sigmoid激活函数现在通常被Relu激活函数替代,因为sigmoid激活函数容易造成梯度消失,所以后人设计了Relu激活函数。但经典中仍是sigmoid。
tanh
这两种激活函数都是比较常见的,但在此处我们只需要了解它们的取值范围即可。对于激活函数更详细的内容可以上网去查查资料,会有很多。
下面伴随结构来描述下计算过程:
计算过程可分为三大部分(正好对应于三个门),第二大部分里面又可分为两个部分。
(一) 计算对上一输入的遗忘程度(上一神经元对本神经元的影响)
通过上面对于激活函数的介绍,我们可以知道f(t)是一个[0,1]之间的数值。一个这样的数乘以上一状态的结果是不是相当于上一状态的影响比例。
举个例子:有一个门,门外是上一个状态的结果。我可以选择不开门(f(t)=0)那就是完全屏蔽上一个状态的影响,也可以选择全部打开(f(t)=1)那就是完全接受上一状态。当然,也可以0~1之间的数字,那就是不同的开门比例。也就是不同的遗忘程度。
LSTM中正是凭借这遗忘门这步来有效地保持前后状态的连接。
(二_1)计算当前输入对本细胞状态的影响
这个部分主要计算的当前输入的影响,i(t)也是一个[0,1]之间的数值,乘以经过tanh计算的预备c(t)就计算出了通过输入门后的数值。
(二_2)确定本细胞状态
本细胞状态由两部分组成:经过遗忘门的过去细胞状态和经过输入门的当前输入影响。这里面有两种操作,定义如下图(圈中点和圈中x是一样的):
注意:圈中点/叉代表的是矩阵点乘(之前写了对应位置相乘,感觉好low,hhhh),而不是矩阵相乘。因为在计算过程中二者都涉及到了,所以要特别进行区分。
截至目前为止,C(t)已经被计算完成。
(三)计算当前神经元输出
这步就是通过运算最终得到两个输出,并分别作用于不同对象。
到此!再回去看看那个计算式以及神经元的结构应该更加清晰了吧!
所以,我们再问自己一个问题?LSTM到底是怎么解决梯度爆炸和梯度消失的呢?LSTM的记忆性又体现在哪里呢?
对于LSTM来说,细胞状态c(t)的传输就是记忆性的体现。而c(t)计算中涉及两部分(过去状态和当前输入)做加法,避免了连乘的困扰,解决了梯度问题。通过对于遗忘门的调控来决定对过去状态的取舍。这就是LSTM。
再解释最后一个问题:那为什么LSTM只是缓解而不是彻底解决呢?
其实可以看到,当数据流向在c(t)这条线上时是没有问题的,除此之外还会有一些其他的支路,如果在训练过程中,通过支路,仍是存在梯度爆炸/梯度消失的风险的。所以只是缓解,而不是解决。
LSTM也不是终点,对其的优化仍在进行。如GRU等等,剩下的就慢慢学习吧!
留一些好的参考资料:
1.新手入门理解
https://www.jianshu.com/p/9dc9f41f0b29
https://baijiahao.baidu.com/s?id=1573792228593933&wfr=spider&for=pc
2.三个门参数计算
https://zhuanlan.zhihu.com/p/52701603
3.三个门的计算过程:
https://blog.csdn.net/jamesjjjjj/article/details/83046491
4.RNN梯度消失和梯度爆炸
https://zhuanlan.zhihu.com/p/28687529
感谢施老师对于本篇文章的耐心修改
因作者水平有限,文章如有错误之处,请各位高手在下方评论区批评指正,谢谢!