RNN与LSTM

RNN,或者说最常⽤的LSTM,⼀般⽤于记住之前的状态,以供后续神经⽹络的判断,它由input
gate、forget gate、output gate和cell memory组成,每个LSTM本质上就是⼀个neuron,特殊
之处在于有4个输⼊:z 和三⻔控制信号zi、zf 、zo, 和 每个时间点的输⼊都是由当前输⼊值+上⼀个
时间点的输出值+上⼀个时间点cell值来组成。
 

一、RNN

1.1 从单层网络到经典的RNN结构
在学习LSTM之前,得先学习RNN,而在学习RNN之前,首先要了解一下最基本的单层网络,它的结构如下图所示:

输入是x,经过变换Wx+b和激活函数f,得到输出y。相信大家对这个已经非常熟悉了。

在实际应用中,我们还会遇到很多序列形的数据:


如:

  1. 自然语言处理问题。x1可以看做是第一个单词,x2可以看做是第二个单词,依次类推。
  2. 语音处理。此时,x1、x2、x3……是每帧的声音信号。
  3. 时间序列问题。例如每天的股票价格等等。

而其中,序列形的数据就不太好用原始的神经网络处理了。

为了建模序列问题,RNN引入了隐状态h(hidden state)的概念,h可以对序列形的数据提取特征,接着再转换为输出。

先从h_{1}的计算开始看:


图示中记号的含义是:
a)圆圈或方块表示的是向量。
b)一个箭头就表示对该向量做一次变换。如上图中h_{0}x_{1}分别有一个箭头连接,就表示对h_{0}x_{1}各做了一次变换。
在很多论文中也会出现类似的记号,初学的时候很容易搞乱,但只要把握住以上两点,就可以比较轻松地理解图示背后的含义。

h_{2}的计算和h_{1}类似。但有两点需要注意下:

  1. 在计算时,每一步使用的参数U、W、b都是一样的,也就是说每个步骤的参数都是共享的,这是RNN的重要特点,一定要牢记;
  2. 而下文马上要看到的LSTM中的权值则不共享,因为它是在两个不同的向量中。而RNN的权值为何共享呢?很简单,因为RNN的权值是在同一个向量中,只是不同时刻而已。


依次计算剩下来的(使用相同的参数U、W、b):


我们这里为了方便起见,只画出序列长度为4的情况,实际上,这个计算过程可以无限地持续下去。

我们目前的RNN还没有输出,得到输出值的方法就是直接通过h进行计算:


正如之前所说,一个箭头就表示对对应的向量做一次类似于f(Wx+b)的变换,这里的这个箭头就表示对h1进行一次变换,得到输出y1。

剩下的输出类似进行(使用和y1同样的参数V和c):

OK!大功告成!这就是最经典的RNN结构,是x1, x2, .....xn,输出为y1, y2, ...yn,也就是说,输入和输出序列必须要是等长的。

 RNN的局限:长期依赖(Long-TermDependencies)问题

RNN的关键点之一就是他们可以用来连接先前的信息到当前的任务上,例如使用过去的视频段来推测对当前段的理解。如果RNN可以做到这个,他们就变得非常有用。但是真的可以么?答案是,还有很多依赖因素。

有时候,我们仅仅需要知道先前的信息来执行当前的任务。例如,我们有一个语言模型用来基于先前的词来预测下一个词。如果我们试着预测“the clouds are in the sky”最后的词,我们并不再需要其他的信息,因为很显然下一个词应该是sky。在这样的场景中,相关的信息和预测的词位置之间的间隔是非常小的,RNN可以学会使用先前的信息。


但是同样会有一些更加复杂的场景。假设我们试着去预测“I grew up in France...I speak fluent French”最后的词。当前的信息建议下一个词可能是一种语言的名字,但是如果我们需要弄清楚是什么语言,我们是需要先前提到的离当前位置很远的France的上下文的。这说明相关信息和当前预测位置之间的间隔就肯定变得相当的大。

不幸的是,在这个间隔不断增大时,RNN会丧失学习到连接如此远的信息的能力。


在理论上,RNN绝对可以处理这样的长期依赖问题。人们可以仔细挑选参数来解决这类问题中的最初级形式,但在实践中,RNN肯定不能够成功学习到这些知识。Bengio,etal.(1994)等人对该问题进行了深入的研究,他们发现一些使训练RNN变得非常困难的相当根本的原因。

换句话说, RNN 会受到短时记忆的影响。如果一条序列足够长,那它们将很难将信息从较早的时间步传送到后面的时间步。

因此,如果你正在尝试处理一段文本进行预测,RNN 可能从一开始就会遗漏重要信息。在反向传播期间(反向传播是一个很重要的核心议题,本质是通过不断缩小误差去更新权值,从而不断去修正拟合的函数),RNN 会面临梯度消失的问题。

因为梯度是用于更新神经网络的权重值(新的权值 = 旧权值 - 学习率*梯度),梯度会随着时间的推移不断下降减少,而当梯度值变得非常小时,就不会继续学习。​

换言之,在递归神经网络中,获得小梯度更新的层会停止学习—— 那些通常是较早的层。 由于这些层不学习,RNN 可以忘记它在较长序列中看到的内容,因此具有短时记忆。

而梯度爆炸则是因为计算的难度越来越复杂导致。

然而,幸运的是,有个RNN的变体——LSTM,可以在一定程度上解决梯度消失和梯度爆炸这两个问题!

简单解释梳理RNN与LSTM

在智能客服、智能订票系统中,往往会需要 slot filling 技术,它会分析⽤⼾说出的语句,将时间、地址
等有效的关键词填到对应的槽上,并过滤掉⽆效的词语
词汇要转化成 vector ,可以使⽤ 1-of-N 编码, word hashing 或者是 word vector 等⽅式,此外我们可以
尝试使⽤ Feedforward Neural Network 来分析词汇,判断出它是属于时间或是⽬的地的概率
但这样做会有⼀个问题,该神经⽹络会先处理 “arrive” “leave” 这两个词汇,然后再处理 “Taipei” ,这时
NN 来说,输⼊是相同的,它没有办法区分出 “Taipei” 是出发地还是⽬的地
这个时候我们就希望神经⽹络是有记忆的,如果 NN 在看到 “Taipei” 的时候,还能记住之前已经看过的
“arrive” 或是 “leave” ,就可以根据上下⽂得到正确的答案

这种有记忆⼒的神经⽹络,就叫做 Recurrent Neural Network(RNN)
RNN 中, hidden layer 每次产⽣的 output  a1  、a2 ,都会被存到 memory ⾥,下⼀次有 input 的时候,
这些 neuron 就不仅会考虑新输⼊的x1 x2、 ,还会考虑存放在 memory 中的 a1,a2。
注:在input之前,要先给内存⾥的 赋初始值,⽐如0。
 
每次 NN 的输出都要考虑 memory 中存储的临时值,⽽不同的输⼊产⽣的临时值也尽不相同,
因此改变输⼊序列的顺序会导致最终输出结果的改变 (Changing the sequence order will change the
output)。
 
Slot Filling with RNN

 

用RNN处理Slot Filling的流程举例如下:

  • “arrive”的vector作为x 1输入RNN,通过hidden layer生成a 1 ,再根据a 1 生成y 1 ,表示“arrive”属于每个slot的概率,其中a 1 会被存储到memory中
  • “Taipei”的vector作为x 2 输入RNN,此时hidden layer同时考虑x 2 和存放在memory中的a 1 ,生成a 2 ,再根据a 2 生成y 2,表示“Taipei”属于某个slot的概率,此时再把a 2 存到memory中
  • 依次类推

Elman Network & Jordan Network

RNN有不同的变形:

  • Elman Network:将hidden layer的输出保存在memory里
  • Jordan Network:将整个neural network的输出保存在memory里

由于hidden layer没有明确的训练目标,而整个NN具有明确的目标,因此Jordan Network的表现会更好一些

Bidirectional RNN

RNN 还可以是双向的,你可以同时训练一对正向和反向的RNN,把它们对应的hidden layer x t 拿出来,都接给一个output layer,得到最后的y t 

使用Bi-RNN的好处是,NN在产生输出的时候,它能够看到的范围是比较广的,RNN在产生y t + 1 的时候,它不只看了从句首x 1 开始到x t + 1 的输入,还看了从句尾x n 一直到x t + 1 的输入,这就相当于RNN在看了整个句子之后,才决定每个词汇具体要被分配到哪一个槽中,这会比只看句子的前一半要更好。

 

双向RNN

LSTM

前文提到的RNN只是最简单的版本,并没有对memory的管理多加约束,可以随时进行读取,而现在常用的memory管理方式叫做长短期记忆(Long Short-term Memory),简称LSTM。

Three-gate

LSTM有三个gate:

  • 当某个neuron的输出想要被写进memory cell,它就必须要先经过一道叫做input gate的闸门,如果input gate关闭,则任何内容都无法被写入,而关闭与否、什么时候关闭,都是由神经网络自己学习到的

  • output gate决定了外界是否可以从memory cell中读取值,当output gate关闭的时候,memory里面的内容同样无法被读取

  • forget gate则决定了什么时候需要把memory cell里存放的内容忘记清空,什么时候依旧保存

整个LSTM可以看做是4个input,1个output:

  • 4个input=想要被存到memory cell里的值+操控input gate的信号+操控output gate的信号+操控forget gate的信号
  • 1个output=想要从memory cell中被读取的值

Memory Cell

如果从表达式的角度看LSTM,它比较像下图中的样子

  • z 是想要被存到cell里的输入值
  • z i 是操控input gate的信号
  • z o ​是操控output gate的信号
  • z f 是操控forget gate的信号
  • a 是综合上述4个input得到的output值

把z 、z i ​、z o ​、z f f​通过activation function,分别得到g ( z )、f ( z i ) 、f ( z o ) 、f ( z f ) 

其中对z i 、z o 和z f 来说,它们通过的激活函数f ( )一般会选sigmoid function,因为它的输出在0~1之间,代表gate被打开的程度

令g ( z ) 与f ( z i ) 相乘得到g ( z ) ⋅ f ( z i ) ,然后把原先存放在cell中的c 与f ( z f )相乘得到c. f ( z f ) ,两者相加得到存在memory中的新值c ′ = g ( z ) ⋅ f ( z i ) + c f ( z f ) 

  • 若f ( z i ) = 0,则相当于没有输入,若f ( z i ) = 1,则相当于直接输入g ( z ) 
  • 若f ( z f ) = 1,则保存原来的值c 并加到新的值上,若f ( z f ) = 0 ,则旧的值将被遗忘清除

从中也可以看出,forget gate的逻辑与我们的直觉是相反的,控制信号打开表示记得,关闭表示遗忘

此后,c ′ ′通过激活函数得到h ( c ′ ) ,与output gate的f ( z o )相乘,得到输出a = h ( c ′ ) f ( z o ) 

LSTM Example

下图演示了一个LSTM的基本过程,x 1 ​、x 2​、x 3 ​是输入序列,y 是输出序列,基本原则是:

  • 当x 2 = 1 时,将x 1 ​的值写入memory
  • 当x 2 = − 1 时,将memory里的值清零
  • 当x 3 = 1时,将memory里的值输出
  • 当neuron的输入为正时,对应gate打开,反之则关闭.

LSTM Structure

你可能会觉得上面的结构与平常所见的神经网络不太一样,实际上我们只需要把LSTM整体看做是下面的一个neuron即可

假设目前我们的hidden layer只有两个neuron,则结构如下图所示:

  • 输入x 1 ​、x 2 ​会分别乘上四组不同的weight,作为neuron的输入以及三个状态门的控制信号
  • 在原来的neuron里,1个input对应1个output,而在LSTM里,4个input才产生1个output,并且所有的input都是不相同的
  • 从中也可以看出LSTM所需要的参数量是一般NN的4倍

LSTM for RNN

从上图中你可能看不出LSTM与RNN有什么关系,接下来我们用另外的图来表示它

假设我们现在有一整排的LSTM作为neuron,每个LSTM的cell里都存了一个scalar值,把所有的scalar连接起来就组成了一个vector c t − 1 

在时间点t ,输入了一个vector x t ,它会乘上一个matrix,通过转换得到z ,而z 的每个dimension就代表了操控每个LSTM的输入值,同理经过不同的转换得到z i i、z f 和z o ,得到操控每个LSTM的门信号

下图是单个LSTM的运算情景,其中LSTM的4个input分别是z 、z i 、z f 和z o 的其中1维,每个LSTM的cell所得到的input都是各不相同的,但它们却是可以一起共同运算的,整个运算流程如下图左侧所示:

f ( z f ) 与上一个时间点的cell值c t − 1 相乘,并加到经过input gate的输入g ( z ) ⋅ f ( z i ) 上,得到这个时刻cell中的值c t ,最终再乘上output gate的信号f ( z o ) ,得到输出y t 

上述的过程反复进行下去,就得到下图中各个时间点上,LSTM值的变化情况,其中与上面的描述略有不同的是,这里还需要把hidden layer的最终输出y t 以及当前cell的值c t 都连接到下一个时间点的输入上

因此在下一个时间点操控这些gate值,不只是看输入的x t + 1 x^{t+1}xt+1,还要看前一个时间点的输出h t h^tht和cell值c t c^tct,你需要把x t + 1 x^{t+1}xt+1、h t h^tht和c t c^tct这3个vector并在一起,乘上4个不同的转换矩阵,去得到LSTM的4个输入值z 、z i 、z f 、z o ,再去对LSTM进行操控

注意:下图是同一个LSTM在两个相邻时间点上的情况

上图是单个LSTM作为neuron的情况,事实上LSTM基本上都会叠多层。

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&刘仔很忙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值