LSTM

本文详细介绍了LSTM(长短期记忆网络),一种用于处理序列数据的递归神经网络。LSTM通过其独特的门控机制解决了传统RNN的梯度消失问题,使其在语言模型、机器翻译、文本生成等领域表现出色。文章涵盖了LSTM的基本结构、工作原理以及在实际应用中的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                                                                                                                              点击此处返回总目录

 

我们前面讲的RNN只是RNN的最简单的版本。前面讲的memory是最单纯的,我们随时都可以把值存到memory里面去,也可以随时读出来。

但是现在比较常用的memory称之为Long Short-term Memory,简写为LSTM。。

             

这种Long Short-term Memoy是比较复杂的。它有三个门。

当某个神经元的input想要写到Memory cell里面的时候呢,必须先通过一个闸门Input Gate。这个Input Gate打开的时候,才能把值写到Memory cell里面去,如果关起来了,其他神经元就没有办法把值写进去。这个Input Gate是打开还是关闭,是网络自己学的,它可以自己学什么时候要把Input Gate打开,什么时候要把Input Gate关起来。

                                      

输出的地方也有一个Output Gate,这个Output Gate会决定说,外界其他的神经元可不可以从memory里面把值读出来。当Output Gate关闭的时候,就没有办法把值读出来了,Output Gate打开的时候才可以把值读出来。跟Input Gate一样,Output Gate什么时候打开,什么时候关闭,也是网络自己学到的。

                                

 

第三个Gate叫做Forget Gate,Forget Gate是决定说什么时候memory cell把过去记得的东西忘掉。Forget Gate什么时候把里面的值继续保留下来。什么时候忘掉,什么时候保留,也是网络自己学到的。

                                       

 

整个LSTM可以看成有四个input,1个output。这四个input是,想要被存到memory里面的值、操控Input Gate的信号、操控Output Gate 的信号、操控Forget Gate的信号。

                        

 

还有一个小小的冷知识。LSTM名字是"Long Short-term Memory"而不是"Long-short Term Memory"。"-"应该放在"short"和"term"之间,因为其实还是一个Short-term的memory,只是比较长的短时记忆网络。因为RNN的memory在每个时间点都会被洗掉,所以它的short-term是非常短的,它只记得前一个时间点的事情。而LSTM可以记得比较长时间一点,只要Forget Gate不删除的话,它的值就一直有。

 

-------------------------------------------------------------------------------------------------------------------------------

更仔细来看它的formulation的话,长的像这样。1是外界的input,是要存到cell中的input;2是Input Gate;3是Forget Gate;4是Output Gate。现在假设要存到cell中的input叫做z;操控Input Gate的信号叫做Zi,所谓操控Input Gate的信号也就是一个数值,待会讲数值是从哪里来的,这个数值被当做一个input;Forget Gate有一个操控它的数值叫做Zf;Output Gate有一个操控的数值叫做Zo。最后的output是a。

                                                      

假设在有这四个输入之前,cell里面已经存了值c。假设现在输入Z,三个Gate分别由Zi,Zf,Zo操控,那输出a会长什么样子呢?

1. Z 通过激活函数得到g(Z)

2. Zi通过激活函数得到f(Zi)。 Zi,Zf,Zo通过的激活函数通常选择sigmoid函数。选择sigmoid函数的意义就是,sigmoid函数的值在0~1之间。而0~1之间的值代表Gate被打开的程度。如果激活函数的output是1,代表这个Gate是打开的状态。反之代表这个Gate是关起来的。

3. 用g(Z)乘上f(Zi),得到g(Z)f(Zi)

4. Zf通过激活函数得到f(Zf)

5. 把存在memory里面的值c乘上f(Zf),得到cf(Zf)

6. 把cf(Zf)加上g(Z)f(Zi),得到c'。c'就是新的存到memory cell的值。

 

                        

 

根据到目前为止的运算,可以说f(Zi)就是控制g(Z)可不可以输入的一个关卡。因为假设f(Zi)等于0,那g(Z)f(Zi)就等于0,那g(Z)就好像没有输入一样;如果f(Zi)等于1,那相当于把g(Z)当做输入。

f(Zf)就决定说,我们要不要把存在memory cell的值给洗掉,假设f(Zf)是1,c会直接通过,就等于还是记得以前的值。如果f(zf)等于0,也就是Forget Gate关闭的时候,0乘以c,就相当于过去存在memory里面的值,就相当于0。Forget Gate的开关跟我们直观的想法是相反的,Forget Gate打开的时候表示记得,关闭的时候表示遗忘。所以它的名字有点奇怪,不过习惯就这么叫了。

 

7. 把c'写到memory cell中

8. c'通过激活函数得到h(c')

9. Zo通过激活函数得到f(Zo)

10. h(c')乘以f(Zo)得到a。如果f(Zo)等于1,代表h(c')可以通过Output Gate。等于0,output就是0,代表存在memory cell中的值不能被读取出来。

 

                      

 

-------------------------------------------------------------------------------------------------------------------------------

也许这样还是没有很清楚,所以后面做了一个人工LSTM。这个投影片做了很久。先讲一下举的例子,网络里面只有一个LSTM的cell。我们的input都是三维的向量,output都是一维的向量。

                   

这个三维的向量跟output还有memory里面的值的关系是什么呢?这个关系是这样子。

假设x2的值是1的时候,x1的值就会被写到memory里面去。假设x2的值是-1的时候,memory就会被reset,就会被遗忘。假设x3等于1的时候,才会把Output Gate打开,才能够看到输出。

                  

假设运来存在memory中的值是0。

当输入100的时候,输出是0.

当输入310的时候,x2=1,把x1加到memory中,3+0=3

当输入200的时候,输出是0

当输入410的时候,x2为1,所以把x1加到memory中,3+4=7

当输入200的时候,输出是0

当输入101的时候,x3为1,输出7

当输入3-10的时候,x2=-1,memory中的值变为0

当输入610的时候,x2=1,把x1加到memory中,0+6=6

当输入101的时候,x3=1,输出6

 

                   

 

-------------------------------------------------------------------------------------------------------------------------------

我们来实际做一下运算。下面是一个LSTM的memory cell。LSTM的memory cell总共有4个input,这4个input都是数值。这4个数值是怎么来的呢?是我们input的那个三维的向量(x1,x2,x3)进行线性变换得来的。即x1*w1+x2*w2+x3*w3+b得到。这些w和b应该是多少,是通过training data,用Gradient Descent学到的。假设我们已经知道这些值是多少(如图所示)。

我们实际的输入一组(x1,x2,x3)看看输出是多少。

在实际运算之前呢,我们先根据这些参数(w和b)来分析一下可能会得到的结果。

在1处,只有w1为1,其余全为0,说明就是把x1当做输入。

在2处,x2*100+(-10),也就是说假设x2没有值的时候,因为bias是-10,所以通常Input Gate是被关闭的,因为如果输入-10,通过sigmoid函数,值接近0,代表Input Gate是关闭的。只有在x2有值的时候,x2*100-10就大于0,input就是一个很大的正值,代表Input Gate被打开。

在3处,平时都是被打开的,因为bias为10,经过sigmoid函数得到1,说明遗忘门是打开的,打开意味着不忘记。只有在x2给一个很大的负值的时候,才会把Forget Gate关起来。

在4出,Output Gate通常是关闭的。只有x3是很大的正值的时候,才打开。才有输出。

 

这也就是我们刚才说的:

当x2为1时,Input Gate打开,x1可以输入进来;Forget Gate打开,没有忘记。cell更新为c+x1。

当x2为-1时,Input Gate关闭,x1输入不进来;Forget Gate关闭,忘记。cell 更新为0.

当x3为1时,Output Gate打开,可以输出。

当x3为0是,Output Gate关闭,输出为0.

                             

 

好,我们实际的input一下看看。

我们假设g和h都是线性的。假设存在memory里面的初始值是0。我们输入第一个向量(3,1,0)。经过一下8步运算,输出0。

                          

 

当输入向量(4,1,0)时,得到输出为0。

                         

当输入(2,0,0)的时候计算过程如下:

                         

当输入(1,0,1)时,运算如下:

                        

最后当输入(3,-1,0)时运算如下:

                        

-------------------------------------------------------------------------------------------------------------------------------

看到这里可能会有一个问题,这个东西跟我们以前看到的神经网络很不像。它跟以前的神经网络到底有什么关系呢?可以这样想。

在原来的神经网络里面,我们会有很多的神经元。我们会把input乘上不同的weight,当做是不同神经元的输入。然后每一个神经元都是一个函数,它的输入是一个数值,输出是另外一个数值。

                                          

但是如果是LSTM的话呢?其实只要把LSTM的memory的cell想成是一个神经元就好了。

现在的x1,x2只是会乘上不同的weight,当做LSTM的不同的输入。假设只有两个"神经元"。会把输入(x1,x2)乘上一组weight当做input的输入,乘上一组weight当做三个Gate的输入。

                  

我们刚才讲过LSTM有4个input,1个output。对于LSTM来说,这4个input是不一样的。在原来的神经网络中,一个神经元就是一个input,一个output。在LSTM中有4个input,才能产生一个output。所以假设使用的LSTM的"神经元"跟Original Network神经元的数目是相等的,LSTM的参数的量会是Original network的四倍。

 

-------------------------------------------------------------------------------------------------------------------------------

但是这样讲,可能还是没有办法体会这个跟RNN的关系。所以又画了一个图。这个图也要画非常久。【liupc:我没怎么懂】

假设我们现在有一整排的"神经元",有一整排的LSTM。这一整排的LSTM里面呢,每一个的memory里面,都存了一个值。把这些数值接起来,就变成一个向量。写成c^(t-1)。

 

              

现在在时间点t,输入一个向量xt。这个xt首先会做一个线性变换,乘上一个矩阵,变成另外一个向量z。z这个向量的每一个dimension就代表了操控每一个LSTM的input。Z的第一维就丢给第一个cell ,第二维就丢给第二个cell,第三维就丢给第三个cell。

                                  

 

xt会乘上另外一个矩阵,得到zi,zi的维度也跟cell的数目一样。zi的每一个dimension都会去操控每一个memory。第一维操控第一个Input Gate,第二维操控第二个Input Gate...第n维操控第n个Input Gate.

                                  

同样,也有Zo和Zf。zf会去操控每一个Forget Gate ,zo会去操控每一个Output Gate。

所以把xt乘上不同的四个不同的transform,得到4个不同的向量。这4个不同的vectors,他们的维度都跟cell的数目是一样的。这4个向量合起来,就回去操控这些memory的运作。

                                

 

好,我们知道一个memory cell长右边这样。注意四个输入z、zi、zf、zo分别是四个向量的某一个维度的数值。

其运算过程可以画成左边的图。

       

在下一个时间点,input为xt+1。经过相同的运算。

     

有人说,这个过程已经够复杂的了。但是这并不是LSTM的最终形态。真正的LSTM会把yt也接进来,当做下一个时间点的输入。也就是说,下一个时间点操控这些Gate的值不是只看那个时间点的X,还要看上一个时间点的output h。

         

 

还不止这样,还要加一个东西,叫做"peephole"。这个peephole就是把存在memory里面的值呢,也拉过来。所以在操控LSTM的四个Gate的时候,是同时考虑了x,h,c。把这三个三个向量并在一起,乘上四个不同的transform,得到四个不同的向量。再去操控LSTM。

          

 

LSTM不会只有一层,现在胡乱都要叠个五六层才爽。所以大概就长成这样。

        

每一个第一次看到这个的人,他的反映都是这样:

                                                            

第一次见到都认为不work,但是现在其实还quite standard。当有个人告诉你说,我用RNN做了什么事情的时候,其实他就是用LSTM。

                                                                       

Keras里面有LSTM,所以上面讲的没听懂就算了,在Keras里面就是打LSTM四个字母就结束了。

                            

Keras其实支持三种RNN,"LSTM","GRU","SimpleRNN"。GRU是LSTM的稍微简化的版本,它只有两个Gate,据说少了一个Gate,performance跟LSTM差不多,但是少了三分之一的参数,不容易overfitting。要用上次将的最简单的RNN的话,需要说是SimpleRNN才行。

                            

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值