RNN 与 LSTM 的原理详解

本文主要讲解了 RNN 和 LSTM 的结构、前馈、反馈的原理,参考了https://www.jianshu.com/p/f3bde26febed/、https://www.jianshu.com/p/9dc9f41f0b29 与 https://blog.csdn.net/zhaojc1995/article/details/80572098等文章,并纠正了公式的错误、更新了无效的论文链接。

RNN(Recurrent Neural Network)是一类用于处理序列数据的神经网络。

什么是序列呢?序列是一串有顺序的数据,比如某一条数据为 [ x 1 , x 2 , x 3 , x 4 ] [x_1, x_2, x_3, x_4] [x1,x2,x3,x4],其中每个元素可以是一个字符、一个单词、一个向量,甚至是一个声音。比如:

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

RNN 处理这种序列数据,在结构上具有天然的优势(相对于普通的神经网络而言,如全连接、CNN等)。

RNN 的结构

我们从基础的神经网络中知道,神经网络包含输入层、隐层、输出层,通过激活函数控制输出,层与层之间通过权值连接。激活函数是事先确定好的,那么神经网络模型通过训练“学“到的东西就蕴含在“权值“中。单层的神经网络如图:
RNN 与 LSTM 的原理详解_第1张图片

其中,x为输入,W为权重矩阵,b为偏置,f为激活函数,如 sigmoid 等,y 为输出。这样,就建立了输入与输出之间的关联。

基础的神经网络只在层与层之间建立了权连接,RNN最大的不同之处就是在层之间的神经元之间也建立的权连接。如图。

RNN 与 LSTM 的原理详解_第2张图片

这是一个标准的RNN结构图,图中每个箭头代表做一次变换,也就是说箭头连接带有权值。左侧是折叠起来的样子,右侧是展开的样子,左侧中h旁边的箭头代表此结构中的“循环“体现在隐层。

在展开结构中我们可以观察到,在标准的RNN结构中,隐层的神经元之间也是带有权值的。也就是说,随着序列的不断推进,前面的隐层将会影响后面的隐层。图中O代表输出,y代表样本给出的确定值,L代表损失函数,我们可以看到,“损失“也是随着序列的推荐而不断积累的。

除上述特点之外,标准RNN的还有以下特点:

  • 权值共享,图中的W全是相同的,U和V也一样。
  • 每一个输入值都只与它本身的那条路线建立权连接,不会和别的神经元连接。

以上是RNN的标准结构,属于多输入多输出,并且输入与输出的个数是相同的,即每次输入都会对应一个输出。

然而在实际中这一种结构并不能解决所有问题,常见的变种有:

1、多输入单输出

有的时候,我们要处理的问题输入是一个序列,输出是一个单独的值而不是序列,应该怎样建模呢?实际上,我们只在最后一个h上进行输出变换就可以了:
RNN 与 LSTM 的原理详解_第3张图片

这种结构通常用来处理序列分类问题。如输入一段文字判别它所属的类别,输入一个句子判断其情感倾向,输入一段视频并判断它的类别等等。

2、单输入多输出

输入不是序列而输出为序列的情况怎么处理?我们可以只在序列开始进行输入计算,其余只需要隐层状态进行传递。
RNN 与 LSTM 的原理详解_第4张图片

还有一种结构是把输入信息X作为每个阶段的输入:
RNN 与 LSTM 的原理详解_第5张图片

这种单输入多输出的结构可以处理的问题有:

  • 从图像生成文字(image caption),此时输入的X就是图像的特征,而输出的y序列就是一段句子
  • 从类别生成语音或音乐等

3、多输入多输出(输入和输出个数不同)

实际中,还有另外一种多输入多输出的结构,其输入与输出并不是一一对应的,如图:
RNN 与 LSTM 的原理详解_第6张图片

这种结构又叫Encoder-Decoder模型,也可以称之为Seq2Seq模型。

Encoder-Decoder结构先将输入数据编码成一个上下文向量c。得到c有多种方式,最简单的方法就是把Encoder的最后一个隐状态赋值给c,还可以对最后的隐状态做一个变换得到c,也可以对所有的隐状态做变换。

拿到c之后,就用另一个RNN网络对其进行解码,这部分RNN网络被称为Decoder。具体做法就是将c当做之前的初始状态h0输入到Decoder中。

还有另外一种 Decoder,是将c当做每一步的输入:
RNN 与 LSTM 的原理详解_第7张图片

由于这种Encoder-Decoder结构不限制输入和输出的序列长度,因此应用的范围非常广泛,比如:

  • 机器翻译。Encoder-Decoder的最经典应用,事实上这一结构就是在机器翻译领域最先提出的
  • 文本摘要。输入是一段文本序列,输出是这段文本序列的摘要序列。
  • 阅读理解。将输入的文章和问题分别编码,再对其进行解码得到问题的答案。
  • 语音识别。输入是语音信号序列,输出是文字序列。

RNN的前向输出流程

下面对多输入多输出(一一对应)的经典结构作分析:
RNN 与 LSTM 的原理详解_第8张图片
其中,x是输入,h是隐层单元,o为输出,L为损失函数,y为训练集的标签。这些元素右上角带的t代表t时刻的状态,其中需要注意的是,隐层单元h在t时刻的表现不仅由此刻的输入决定,还受t时刻之前时刻的影响。V、W、U是权值,同一类型的权连接权值相同。

前向传播算法其实非常简单,对于t时刻,隐层单元为:
h ( t ) = f ( U x ( t ) + W h ( t − 1 ) + b ) h^{(t)}=f(Ux^{(t)}+Wh^{(t-1)}+b) h(t)=f(Ux(t)+Wh(t1)+b)

其中,f 为激活函数,如 sigmoid、tanh 等,b 为偏置。

t时刻的输出为:
o ( t ) = V h ( t ) + c o^{(t)}=Vh^{(t)}+c o(t)=Vh(t)+c

RNN的训练方法

BPTT(back-propagation through time)算法是常用的训练RNN的方法,其实本质还是BP算法,只不过RNN处理时间序列数据,所以要基于时间反向传播,故叫随时间反向传播。BPTT的中心思想和BP算法相同,沿着需要优化的参数的负梯度方向不断寻找更优的点直至收敛。综上所述,BPTT算法本质还是BP算法,BP算法本质还是梯度下降法,那么求各个参数的梯度便成了此算法的核心。

RNN 与 LSTM 的原理详解_第9张图片

再次拿出这个结构图观察,需要寻优的参数有三个,分别是U、V、W。与BP算法不同的是,其中W和U两个参数的寻优过程需要追溯之前的历史数据,参数V相对简单只需关注目前,那么我们就来先求解参数V的偏导数。
∂ L ( t ) ∂ V = ∂ L ( t ) ∂ o ( t ) ∂ o ( t ) ∂ V \frac{\partial L^{(t)}}{\partial V}=\frac{\partial L^{(t)}}{\partial o^{(t)}} \frac{\partial o^{(t)}}{\partial V} VL(t)=o(t)L(t)Vo(t)
RNN的损失也是会随着时间累加的,所以需要求出所有时刻的偏导然后求和:
L = ∑ t = 1 n L ( t ) L=\sum_{t=1}^n L^{(t)} L=t=1nL(t)
∂ L ∂ V = ∑ t = 1 n ∂ L ( t ) ∂ o ( t ) ∂ o ( t ) ∂ V \frac{\partial L}{\partial V}=\sum_{t=1}^n\frac{\partial L^{(t)}}{\partial o^{(t)}} \frac{\partial o^{(t)}}{\partial V} VL=t=1no(t)L(t)Vo(t)

W和U的偏导的求解由于需要涉及到历史数据,其偏导求起来相对复杂,我们先假设只有三个时刻,那么在第三个时刻 L对W的偏导数为:
∂ L ( 3 ) ∂ W = ∂ L ( 3 ) ∂ o ( 3 ) ∂ o ( 3 ) ∂ h ( 3 ) ∂ h ( 3 ) ∂ W + ∂ L ( 3 ) ∂ o ( 3 ) ∂ o ( 3 ) ∂ h ( 3 ) ∂ h ( 3 ) ∂ h ( 2 ) ∂ h ( 2 ) ∂ W + ∂ L ( 3 ) ∂ o ( 3 ) ∂ o ( 3 ) ∂ h ( 3 ) ∂ h ( 3 ) ∂ h ( 2 ) ∂ h ( 2 ) ∂ h ( 1 ) ∂ h ( 1 ) ∂ W \frac{\partial L^{(3)}}{\partial W}=\frac{\partial L^{(3)}}{\partial o^{(3)}}\frac{\partial o^{(3)}}{\partial h^{(3)}}\frac{\partial h^{(3)}}{\partial W}+\frac{\partial L^{(3)}}{\partial o^{(3)}}\frac{\partial o^{(3)}}{\partial h^{(3)}}\frac{\partial h^{(3)}}{\partial h^{(2)}}\frac{\partial h^{(2)}}{\partial W}+\frac{\partial L^{(3)}}{\partial o^{(3)}}\frac{\partial o^{(3)}}{\partial h^{(3)}}\frac{\partial h^{(3)}}{\partial h^{(2)}}\frac{\partial h^{(2)}}{\partial h^{(1)}}\frac{\partial h^{(1)}}{\partial W} WL(3)=o(3)L(3)h(3)o(3)Wh(3)+o(3)L(3)h(3)o(3)h(2)h(3)Wh(2)+o(3)L(3)h(3)o(3)h(2)h(3)h(1)h(2)Wh(1)
同理,对U的偏导为:
∂ L ( 3 ) ∂ W = ∂ L ( 3 ) ∂ o ( 3 ) ∂ o ( 3 ) ∂ h ( 3 ) ∂ h ( 3 ) ∂ U + ∂ L ( 3 ) ∂ o ( 3 ) ∂ o ( 3 ) ∂ h ( 3 ) ∂ h ( 3 ) ∂ h ( 2 ) ∂ h ( 2 ) ∂ U + ∂ L ( 3 ) ∂ o ( 3 ) ∂ o ( 3 ) ∂ h ( 3 ) ∂ h ( 3 ) ∂ h ( 2 ) ∂ h ( 2 ) ∂ h ( 1 ) ∂ h ( 1 ) ∂ U \frac{\partial L^{(3)}}{\partial W}=\frac{\partial L^{(3)}}{\partial o^{(3)}}\frac{\partial o^{(3)}}{\partial h^{(3)}}\frac{\partial h^{(3)}}{\partial U}+\frac{\partial L^{(3)}}{\partial o^{(3)}}\frac{\partial o^{(3)}}{\partial h^{(3)}}\frac{\partial h^{(3)}}{\partial h^{(2)}}\frac{\partial h^{(2)}}{\partial U}+\frac{\partial L^{(3)}}{\partial o^{(3)}}\frac{\partial o^{(3)}}{\partial h^{(3)}}\frac{\partial h^{(3)}}{\partial h^{(2)}}\frac{\partial h^{(2)}}{\partial h^{(1)}}\frac{\partial h^{(1)}}{\partial U} WL(3)=o(3)L(3)h(3)o(3)Uh(3)+o(3)L(3)h(3)o(3)h(2)h(3)Uh(2)+o(3)L(3)h(3)o(3)h(2)h(3)h(1)h(2)Uh(1)
可以看到,在某个时刻的对W或是U的偏导数,需要追溯这个时刻之前所有时刻的信息,这还仅仅是一个时刻的偏导数,上面说过损失也是会累加的,那么整个损失函数对W和U的偏导数将会非常繁琐。虽然如此但好在规律还是有迹可循,我们根据上面两个式子可以写出L在t时刻对W和U偏导数的通式:
∂ L ( t ) ∂ W = ∂ L ( t ) ∂ o ( t ) ∂ o ( t ) ∂ h ( t ) ∑ k = 1 t ( ∏ i = k + 1 t ∂ h ( i ) ∂ h ( i − 1 ) ) ∂ h ( k ) ∂ W \frac{\partial L^{(t)}}{\partial W}= \frac{\partial L^{(t)}}{\partial o^{(t)}} \frac{\partial o^{(t)}}{\partial h^{(t)}}\sum_{k=1}^t(\prod_{i=k+1}^{t}\frac{\partial h^{(i)}}{\partial h^{(i-1)}})\frac{\partial h^{(k)}}{\partial W} WL(t)=o(t)L(t)h(t)o(t)k=1t(i=k+1th(i1)h(i))Wh(k)
∂ L ( t ) ∂ U = ∂ L ( t ) ∂ o ( t ) ∂ o ( t ) ∂ h ( t ) ∑ k = 1 t ( ∏ i = k + 1 t ∂ h ( i ) ∂ h ( i − 1 ) ) ∂ h ( k ) ∂ U \frac{\partial L^{(t)}}{\partial U}= \frac{\partial L^{(t)}}{\partial o^{(t)}} \frac{\partial o^{(t)}}{\partial h^{(t)}}\sum_{k=1}^t(\prod_{i=k+1}^{t}\frac{\partial h^{(i)}}{\partial h^{(i-1)}})\frac{\partial h^{(k)}}{\partial U} UL(t)=o(t)L(t)h(t)o(t)k=1t(i=k+1th(i1)h(i))Uh(k)
与V相同,对W或U的整体偏导,也是将所有t时刻的偏导相加。

前面说过激活函数是嵌套在里面的,如果我们把激活函数放进去,拿出中间累乘的那部分:
∏ i = k + 1 t ∂ h ( i ) ∂ h ( i − 1 ) = ∏ i = k + 1 t t a n h ′ ⋅ W \prod_{i=k+1}^{t}\frac{\partial h^{(i)}}{\partial h^{(i-1)}}=\prod_{i=k+1}^{t}tanh'·W i=k+1th(i1)h(i)=i=k+1ttanhW

∏ i = k + 1 t ∂ h ( i ) ∂ h ( i − 1 ) = ∏ i = k + 1 t s i g m o i d ′ ⋅ W \prod_{i=k+1}^{t}\frac{\partial h^{(i)}}{\partial h^{(i-1)}}=\prod_{i=k+1}^{t}sigmoid'·W i=k+1th(i1)h(i)=i=k+1tsigmoidW

我们会发现累乘会导致激活函数导数和权重矩阵的累乘,进而会导致“梯度消失“和“梯度爆炸“现象的发生。

为什么会出现“梯度消失“?我们先来看看这两个激活函数的图像:
RNN 与 LSTM 的原理详解_第10张图片
RNN 与 LSTM 的原理详解_第11张图片

可见,sigmoid函数的导数范围是(0,0.25],tach函数的导数范围是(0,1],他们的导数最大都不大于1。累乘的过程中,如果取sigmoid函数作为激活函数的话,那么必然是一堆小数在做乘法,结果就是越乘越小。随着时间序列的不断深入,小数的累乘就会导致梯度越来越小直到接近于0,这就是“梯度消失“现象。其实RNN的时间序列与深层神经网络很像,在较为深层的神经网络中使用sigmoid函数做激活函数也会导致反向传播时梯度消失,梯度消失就意味消失那一层的参数再也不更新,那么那一层隐层就变成了单纯的映射层,毫无意义了,所以在深层神经网络中,有时候多加神经元数量可能会比多家深度好。

同理,由于权重矩阵的累乘,可能会导致“梯度爆炸”的发生。

RNN的特点本来就是能“追根溯源“利用历史数据,现在告诉我可利用的历史数据竟然是有限的,这就令人非常难受,解决“梯度消失“是非常必要的。解决“梯度消失“的方法主要有:

  • 选取更好的激活函数
  • 改变传播结构

关于第一点,一般选用ReLU函数作为激活函数,ReLU函数的图像为:
RNN 与 LSTM 的原理详解_第12张图片

ReLU函数的左侧导数为0,右侧导数恒为1,这就避免了“梯度消失“的发生。但恒为1的导数容易导致“梯度爆炸“,即W的累乘可能会使得导数值越来越大。还有一点就是如果左侧横为0的导数有可能导致把神经元学死,不过设置合适的步长(学习旅)可以有效避免这个问题的发生。

关于第二点,LSTM结构可以解决这个问题。

总结一下,sigmoid函数的缺点:

  • 导数值范围为(0,0.25],反向传播时会导致“梯度消失“。tanh函数导数值范围更大,相对好一点。
  • sigmoid函数不是0中心对称,tanh函数是,可以使网络收敛的更好。

LSTM

下面来了解一下LSTM(long short-term memory)。长短期记忆网络是RNN的一种变体,RNN由于梯度消失的原因只能有短期记忆,LSTM网络通过精妙的门控制将短期记忆与长期记忆结合起来,并且一定程度上解决了梯度消失的问题。

长期依赖(Long-Term Dependencies)问题

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

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

RNN 与 LSTM 的原理详解_第13张图片

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

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

RNN 与 LSTM 的原理详解_第14张图片

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

LSTM网络

Long Short Term 网络—— 一般就叫做 LSTM ——是一种 RNN 特殊的类型,可以学习长期依赖信息。LSTM 由Hochreiter & Schmidhuber (1997)提出,并在近期被Alex Graves进行了改良和推广。在很多问题,LSTM 都取得相当巨大的成功,并得到了广泛的使用。

LSTM 通过刻意的设计来避免长期依赖问题。记住长期的信息在实践中是 LSTM 的默认行为,而非需要付出很大代价才能获得的能力!

所有 RNN 都具有一种重复神经网络模块的链式的形式。在标准的 RNN 中,这个重复的模块只有一个非常简单的结构,例如一个 tanh 层。

RNN 与 LSTM 的原理详解_第15张图片

LSTM 同样是这样的结构,但是重复的模块拥有一个不同的结构。不同于单一神经网络层,这里是有四个,以一种非常特殊的方式进行交互。整体上除了h在随时间流动,细胞状态c也在随时间流动,细胞状态c就代表着长期记忆。

RNN 与 LSTM 的原理详解_第16张图片

不必担心这里的细节。我们会一步一步地剖析 LSTM 解析图。现在,我们先来熟悉一下图中使用的各种元素的图标。

RNN 与 LSTM 的原理详解_第17张图片

  • 黄色的矩形是学习得到的神经网络层
  • 粉色的圆形表示一些运算操作,诸如加法乘法
  • 黑色的单箭头表示向量的传输
  • 两个箭头合成一个表示向量的连接
  • 一个箭头分开表示向量的复制

LSTM 的关键就是细胞状态,水平线在图上方贯穿运行。

细胞状态类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面流传保持不变会很容易。

RNN 与 LSTM 的原理详解_第18张图片

LSTM 有通过精心设计的称作为“门”的结构来去除或者增加信息到细胞状态的能力。门是一种让信息选择式通过的方法。他们包含一个 sigmoid 神经网络层和一个 pointwise 乘法操作。

RNN 与 LSTM 的原理详解_第19张图片

Sigmoid 层输出 0 到 1 之间的数值,描述每个部分有多少量可以通过。0 代表“不许任何量通过”,1 就指“允许任意量通过”!

LSTM 拥有三个门,来保护和控制细胞状态。

理解LSTM的三个门

遗忘门

在我们 LSTM 中的第一步是决定我们会从细胞状态中丢弃什么信息。这个决定通过一个称为遗忘门完成。该门会读取 h t − 1 h_{t-1} ht1 x t x_t xt,输出一个在 0 到 1 之间的数值给每个在细胞状态 C t − 1 C_{t-1} Ct1中的数字。1 表示“完全保留”,0 表示“完全舍弃”。

让我们回到语言模型的例子中来基于已经看到的预测下一个词。在这个问题中,细胞状态可能包含当前主语的性别,因此正确的代词可以被选择出来。当我们看到新的主语,我们希望忘记旧的主语。

RNN 与 LSTM 的原理详解_第20张图片

这里可以抛出两个问题:这个门怎么做到“遗忘“的呢?怎么理解?既然是遗忘旧的内容,为什么这个门还要接收新的 x t x_t xt?

对于第一个问题,“遗忘“可以理解为“之前的内容记住多少“,其精髓在于只能输出(0,1)小数的sigmoid函数和粉色圆圈的乘法,LSTM网络经过学习决定让网络记住以前百分之多少的内容。对于第二个问题就更好理解,决定记住什么遗忘什么,其中新的输入肯定要产生影响。

输入门

下一步是确定什么样的新信息被存放在细胞状态中。这里包含两个部分。第一,sigmoid 层称 “输入门层” 决定什么值我们将要更新。然后,一个 tanh 层创建一个新的候选值向量, C t ~ \tilde{C_{t}} Ct~,会被加入到状态中。下一步,我们会讲这两个信息来产生对状态的更新。

在我们语言模型的例子中,我们希望增加新的主语的性别到细胞状态中,来替代旧的需要忘记的主语。

RNN 与 LSTM 的原理详解_第21张图片

现在是更新旧细胞状态的时间了, C t − 1 C_{t-1} Ct1 更新为 C t C_t Ct。前面的步骤已经决定了将会做什么,我们现在就是实际去完成。
我们把旧状态与 f t f_t ft相乘,丢弃掉我们确定需要丢弃的信息。接着加上 i t ⋅ C t ~ i_t·\tilde{C_t} itCt~。这就是新的候选值,根据我们决定更新每个状态的程度进行变化。

有了上面的理解基础输入门,输入门理解起来就简单多了。tanh函数创建新的输入值,sigmoid函数决定可以输入进去的比例。
RNN 与 LSTM 的原理详解_第22张图片

输出门

最终,我们需要确定输出什么值。这个输出将会基于我们的细胞状态,但是也是一个过滤后的版本。首先,我们运行一个 sigmoid 层来确定细胞状态的哪个部分将输出出去。接着,我们把细胞状态通过 tanh 进行处理(得到一个在 -1 到 1 之间的值)并将它和 sigmoid 门的输出相乘,最终我们仅仅会输出我们确定输出的那部分。

RNN 与 LSTM 的原理详解_第23张图片

这三个门虽然功能上不同,但在执行任务的操作上是相同的。他们都是使用sigmoid函数作为选择工具,tanh函数作为变换工具,这两个函数结合起来实现三个门的功能。

LSTM的变体

我们到目前为止都还在介绍正常的 LSTM。但是不是所有的 LSTM 都长成一个样子的。实际上,几乎所有包含 LSTM 的论文都采用了微小的变体。差异非常小,但是也值得拿出来讲一下。

窥视孔连接

一个流行的LSTM变种,由Gers & Schmidhuber (2002提出,加入了“窥视孔连接(peephole connection)”。也就是说我们让各种门可以接受到细胞状态的输入。

RNN 与 LSTM 的原理详解_第24张图片

上面的图例中,我们增加了 peephole 到每个门上,但是许多论文会加入部分的 peephole 而非所有都加。

对偶忘记门和输入门

另一个变体是通过使用对偶(coupled)忘记门和输入门。不同于之前是分开确定什么忘记和需要添加什么新的信息,这里是一同做出决定。我们仅仅会当我们将要输入在当前位置时忘记。我们仅仅输入新的值到那些我们已经忘记旧的信息的那些状态 。
RNN 与 LSTM 的原理详解_第25张图片

GRU

另一个改动较大的变体是 Gated Recurrent Unit (GRU),这是由 Cho, et al. (2014) 提出。它将忘记门和输入门合成了一个单一的 更新门。同样还混合了细胞状态和隐藏状态,和其他一些改动。最终的模型比标准的 LSTM 模型要简单,也是非常流行的变体。
RNN 与 LSTM 的原理详解_第26张图片

这里只是部分流行的 LSTM 变体。当然还有很多其他的,如Yao, et al. (2015) 提出的 Depth Gated RNN。还有用一些完全不同的观点来解决长期依赖的问题,如Koutnik, et al. (2014) 提出的 Clockwork RNN。

要问哪个变体是最好的?其中的差异性真的重要吗?Greff, et al. (2015) 给出了流行变体的比较,结论是他们基本上是一样的。Jozefowicz, et al. (2015) 则在超过 1 万种 RNN 架构上进行了测试,发现一些架构在某些任务上也取得了比 LSTM 更好的结果。

你可能感兴趣的:(Machine,Learning,算法)