![0af29c47435f4819501ce3e75da9595e.png](https://i-blog.csdnimg.cn/blog_migrate/0f055bc843f1896dffdb6e79bbe99980.jpeg)
本文总结一下循环神经网络LSTM的组成以及循环神经网络LSTM的运行过程,希望对读者有所帮助。
本文的大部分内容源于colah的博客:Understanding LSTM Networks,建议可以好好仔细阅读这篇文章,是很不错的入门文章。
循环神经网络(RNN)
我们每时每刻的思想,我们的语言并不是片面孤立的,也就是我们此刻的想法其实是跟前面的有联系,我们句子里面的当前的词语实际上是与前面出现过的词是保持着联系的。举个最通俗的例子,我们都做过英语的完形填空,知道第三人称单数的名字后面的动词要加‘s’,这就是一个语境的问题,动词的形式跟前面的有关。循环神经网络就是这样一个用途:它把“读”过的文字记下来,比如它读到了“Peter”(这里为了举例的方便,实际上RNN是每个字母地阅读),它就会更新当前的主语的状态,可能是把之前的主语“they”这个时候更新成了“Peter”,这样做的目的是,之后如果遇到一个动词了,当前的神经网络就可以根据前面更新过的主语,知道“Peter”是第三人称单数,接下里的动词应该要加“s”。所以,与传统的神经网络输入输出前后无关不同,RNN的输入和输出是前后联系的,克服了传统神经网络的短板。
![7ca3c5edfc51f2a798c9f7a8aaca8a7f.png](https://i-blog.csdnimg.cn/blog_migrate/b825e4456e613400dd78ab0da28ddaa4.jpeg)
神经网络可以认为它的中间层一直都在随着不同的输入在更新,每个阶段的神经网络都并不是完全一样的。
如果我们在时间上展开来看是以下这种形式的:
![49f0e83d32b2cf71ed23bbfc8157f20c.png](https://i-blog.csdnimg.cn/blog_migrate/63935647318205b959431fc5725d1d35.jpeg)
左边是没有展开,随着t时刻的输入值x_{t},中间绿色方块所代表的状态实际上更新了一遍,然后根据更新后的状态再输出对应的输出值。
也就是输入值→结合之前的状态更新状态→根据新状态输出值。
RNN长期记忆的依赖问题
理论上来说,RNN是可以存储长期记忆,并随时根据当前的输入来更新之前的状态的,但是实践上来说,很困难。具体的原因,原文当中有post出链接[Hochreiter (1991) German]和Bengio, et al. (1994)。
有些问题我们并不需要长期记忆,比如“The dog is barking”,我们只需要在句子位置非常近邻的上下文“dog”就可以推断出接下来的动词非常可能是“barking”。
![90f649afca417dcc6eef42445111da72.png](https://i-blog.csdnimg.cn/blog_migrate/d8acede70f1572d0dce7f46c562891d5.jpeg)
但是有些问题,如果上下文内容隔得比较远,实际操作没有那么容易。比如“I grew up in China. There's a lot of declicious food……I speak Chinese”在这里面Chinese和China隔很远了,所以预测起来有难度。
![a1eca8f9e26b21410792db4f73934d9e.png](https://i-blog.csdnimg.cn/blog_migrate/bd6a43cda95f5931147ed2e4d798c2ed.jpeg)
LSTM网络
LSTM网络,全称是long short term memory。是一种特殊的RNN,与一般的RNN区别是中间的更新状态的方式不同。
![9b7564ccddb113dcc0cb92fddab572fb.png](https://i-blog.csdnimg.cn/blog_migrate/200755be8c140e5f5c9e94dcc9a0b890.jpeg)
传统的RNN的更新模块是只有一层tanh层作为激活层。
![790398724fd846549a9dc322fd6f91e5.png](https://i-blog.csdnimg.cn/blog_migrate/8c2a36fac42db2b0c1b3fa121c2ad362.jpeg)
而LSTM的RNN的更新模块具有4个不同的层相互作用。
图上的标识如下所示:
![1de5d090eb25205687ac8080c5669b4d.png](https://i-blog.csdnimg.cn/blog_migrate/760881c671cab74b2ab0bc78445b729c.jpeg)
LSTM的一些核心概念
![fe14a8c7522bdad8c1db8a9c6412d0b9.png](https://i-blog.csdnimg.cn/blog_migrate/65b9cb16b8acc46f71cc2fa097bdab67.jpeg)
C_{t-1}是前一个状态,C_{t}是输出的状态。状态是指记录了到目前为止的所有更新的上下文,前一个状态C_{t-1}输入以后会经过遗忘和添加新的内容,最终输出新的状态到下一个cell。只有部分信息会删除和更新,大部分信息是直接按照以上那条线flow出去的。个人觉得可以把这里的过程看成是流水生产线,加工的产品就是信息。
![e7d0cd43391ff657fb22749e9d21338c.png](https://i-blog.csdnimg.cn/blog_migrate/28841e3d669a12c7623b8e8150a6e79a.png)
LSTM的整体流程
在这里第一个部分是:遗忘。
这里的sigma是指sigmoid函数,对于状态C_{t-1}矩阵当中每个输入的值,都会有对应的一个输出的值,输出的值在[0, 1]之间,相当于是决定了遗忘多少部分。如果输出值为1,说明全部保留,不删除原本的记忆,如果是0,说明状态C_{t-1}矩阵对应的这个值全部删除。
![351588e10c747678476f15bc55fea7a4.png](https://i-blog.csdnimg.cn/blog_migrate/fbd3859489ed7f360fa2b953cad16c8e.jpeg)
比如前一个状态可能包含了主语“He”,名字叫“Peter”,国籍是“America”。接下来话锋一转,新出现了一群人,因此这个时候状态矩阵对应主语的这一栏就会删除“He”,以保证接下来的动词的形式不是第三人称单数。
第二部分是:添加新信息到已有状态矩阵当中。
这里有两部分同时进行:一个是sigmoid函数决定添加多少部分的新信息到前一个状态矩阵当中(类似于权重),tanh层则根据前一个的输出值h_{t-1}和当前的输入值x_{t-1}产生一个新的当前状态(也就是一个新的候选值向量,这个向量之后要加入到已有的状态矩阵当中)。最后根据前面sigmoid输出的权重和新的候选值向量两个共同更新原有的矩阵。
![264d2c75614243ac1ad5cd19f91f2d46.png](https://i-blog.csdnimg.cn/blog_migrate/886336d29e5db9c00a8148e9bccce059.jpeg)
最终更新新的状态
相当于是忘记之后剩下的部分与新添加信息的权重加和。
![4f645324cd054fb0fc30f4c7756bdf27.png](https://i-blog.csdnimg.cn/blog_migrate/4946aab2b7cd7bb7053de276a65fdd97.jpeg)
第三部分是:决定输出h_{t}
![19eb78a17d3bb606f09f2338b4243f6f.png](https://i-blog.csdnimg.cn/blog_migrate/cc6e64d5fec6dacf794cd838d2b801a9.jpeg)
输出由tanh函数激活,但要乘以一个sigmoid函数激活后的输出权重。
总结
以上就是LSTM的整个过程,总体上来说,要掌握几个要点:
1.LSTM模块当中的线就是状态矩阵C和输出h的流动,一般来说变动很少,主线是最上面那条直线,其他的线都是对这条主要流动线进行微加工。
2.里面有一些黄色方块代表层:sigmoid激活层输出0到1的值,代表权重;tanh层表示对输入进行激活,输出新的候选值。
3.粉色的部分代表操作,x号代表矩阵点乘,+代表添加,tanh代表运算(跟tanh层是一样的函数,但是这里的是输出的是预测值)
4.整体流程是:遗忘→根据现有的输入和上一个cell的输出更新状态→根据现有的状态输出预测值