目录
1 循环神经网络
2 长依赖存在的问题
3 LSTM Networks
4 LSTM背后的核心理念
5 一步步的拆解LSTM
5.1 forget gate忘记门(遗忘门)
5.2 input gate输入门
5.3 更新上一个状态值Ct−1
5.4 输出门output gate
6 LSTM的变种
6.1 peephole connections
6.2 耦合的忘记和输入门
6.3 门控循环单元GRU
7 Keras中使用LSTM层时设置的units参数是什么
8 LSTM 反向传播
9 LSTM为什么可以解决梯度消失的问题?
人类针对每个问题的思考,一般不会是完全的从头开始思考。正如当你阅读这篇译文的时候,你会根据已经阅读过的内容来对后面的内容进行理解,你不会把之前的东西都丢掉从头进行思考,你对内容的理解是贯穿的。
传统的神经网络做不到这一点,而这似乎是一个主要的缺点。 例如,假设您想对电影中的每个事件进行分类。我们无法想象传统神经网络如何能够利用前面的场景去干预后面的预测。
幸好循环神经网络解决了这个问题, 它们是具有循环的网络,允许信息持续存在,示意图如下。
图1 带循环的递归神经网络
在上图中,一组神经网络 A接收某些输入,并输出一个值。 循环允许信息从网络的一个步骤传递到下一个。
这些循环使得循环神经网络看起来很神秘。 然而,如果你再多考虑一下,你就会发现其实它和传统的神经网络并不是完全不同。 一个循环神经网络可以被认为是同一个网络的多个副本,每一个都传递一个消息给后继者。 我们考虑一下如果将循环展开会发生什么:(示意如下)
图2 循环神经网络的展开式
这种链状特征揭示了循环神经网络与序列和列表密切相关。 它们是用于此类数据的自然神经网络结构。
在过去的几年里,RNN应在语音识别、语言建模、翻译,图像字幕等各种问题上取得了巨大成功。在Andrej Karpathy的这篇博文——RNN的难以理解的有效性(The Unreasonable Effectiveness of Recurrent Neural Networks)中讨论了RNN取得的惊人成果,他们真的很神奇
这些成功的案例的共同点就是都是用了LSTM,这是一种非常特殊的循环神经网络,对于许多任务来说,它们比基准版本好的多。 几乎所有令人兴奋的结果都是基于循环神经网络实现的,这篇文章将探讨这些LSTM,带你解开LSTM的神秘面纱。
循环神经网络的设计初衷之一就是能够捕获长距离输入之间的依赖。 从结构上来看, 循环神经网络也理应能够做到这一点。 然而实践发现, 使用BPTT算法学习的循环神经网络并不能成功捕捉到长距离的依赖关系, 这一现象主要源于深度神经网络中的梯度消失。
有时,为了处理当前的任务,我们只需要查看最近的信息。 例如,考虑一种语言模型,该模型根据前面的词语来预测下一个单词。 如果我们试图预测“the clouds are in the sky”的最后一个单词,我们不需要任何其他的语境信息——下一个单词显然是sky。 在相关信息和需要该信息的距离较近的时候,RNN能够学会去利用历史信息。
图3
但也有需要更多上下文的情况。 考虑尝试预测文本中的最后一个单词“I grew up in France… I speak fluent French.”。最近的信息表明,下一个单词可能是一种语言的名称,但如果我们想缩范围确定那种语言,我们需要从前面获取法国的背景。 相关信息和需要该信息的地方的距离变得非常大的情况是很可能的。
不幸的是,随着距离的增加,RNN无法有效的利用历史信息。
图4
在理论上,RNN绝对有能力处理这样的“长依赖”问题。人们可以仔细挑选参数来解决这种形式的问题。 可悲的是,在实践中,RNN似乎无法学习到这些特征。Hochreiter和Bengio,曾经深入的研究过这个问题,他们发现一些根本性的原因,能够解释RNN为什么不work。LSTM没有这个问题!
长短记忆神经网络——通常称作LSTM,是一种特殊的RNN,能够学习长的依赖关系。 他们由Hochreiter&Schmidhuber引入,并被许多人进行了改进和普及。
LSTM是为了避免长依赖问题而精心设计的。 记住较长的历史信息实际上是他们的默认行为,而不是他们努力学习的东西。
所有循环神经网络都具有神经网络的重复模块链的形式。 在标准的RNN中,该重复模块将具有非常简单的结构,例如单个tanh层。
图5 标准RNN中的重复模块的单层神经网络
LSTM也拥有这种链状结构,但是重复模块则拥有不同的结构。与神经网络的简单的一层相比,LSTM拥有四层,这四层以特殊的方式进行交互。
图6 LSTM中的重复模块包含的四层交互神经网络层
现在,让我们先熟悉一下我们将要使用的符号。
图7
在上图中,
LSTM的关键是细胞状态,表示细胞状态的这条线水平的穿过图的顶部。
细胞的状态类似于输送带,细胞的状态在整个链上运行,只有一些小的线性操作作用其上,信息很容易保持不变的流过整个链。
图8
LSTM确实具有删除或添加信息到细胞状态的能力,这个能力是由被称为门(Gate)的结构所赋予的。
门(Gate)是一种可选地让信息通过的方式。 它由一个Sigmoid神经网络层和一个点乘法运算组成。
图9 门(Gate)
Sigmoid神经网络层输出0和1之间的数字,这个数字描述每个组件有多少信息可以通过, 0表示不通过任何信息,1表示全部通过。
LSTM有三个门,用于保护和控制细胞的状态。
图10
LSTM的第一步是决定我们要从细胞状态中丢弃什么信息。 该决定由被称为“忘记门”的Sigmoid层实现。它查看(前一个输出)和(当前输入),并为单元格状态(上一个状态)中的每个数字输出0和1之间的数字。1代表完全保留,而0代表彻底删除。
让我们回到语言模型的例子,试图根据以前的语料来预测下一个单词。 在这样的问题中,细胞状态可能包括当前主语的性别,从而决定使用正确的代词。 当我们看到一个新主语时,我们想要忘记旧主语的性别。
图11
下一步是决定我们要在细胞状态中存储什么信息。 这部分分为两步。
在下一步中,我们将结合这两个向量来创建更新值。
在我们的语言模型的例子中,我们希望将新主语的性别添加到单元格状态,以替换我们忘记的旧主语。
图12
现在是时候去更新上一个状态值了,将其更新为。之前的步骤已经决定了应该做什么,我们只需实际执行即可。
我们将上一个状态值乘以,以此表达期待忘记的部分。之后我们将得到的值加上 。这个得到的是新的候选值, 按照我们决定更新每个状态值的多少来衡量。
在语言模型的例子中,对应着实际删除关于旧主语性别的信息,并添加新信息,正如在之前的步骤中描述的那样。
图13
最后,我们需要决定我们要输出什么。 此输出将基于我们的细胞状态,但将是一个过滤版本。 首先,我们运行一个sigmoid层,它决定了我们要输出的细胞状态的哪些部分。 然后,我们将单元格状态通过tanh(将值规范化到-1和1之间),并将其乘以Sigmoid门的输出,至此我们只输出了我们决定的那些部分。
对于语言模型的例子,由于只看到一个主语,考虑到后面可能出现的词,它可能需要输出与动词相关的信息。 例如,它可能会输出主题是单数还是复数,以便我们知道动词应该如何组合在一起。
到目前为止,所描述的是一个很正常的LSTM。 但并不是所有的LSTM都与上述相同。 事实上,似乎几乎每一篇涉及LSTM的论文都使用了一个略有不同的版本,差异很小,但有一些值得一看。
一个比较流行的LSTM变种是由Gers & Schmidhuber (2000)提出的,添加“peephole connections”。这意味着,我们允许gate层去看细胞的状态。
上面的图中所有的Sigmoid层都增加了窥视,门值不仅取决于 ,也可以偷窥一下。但许多论文实现不是针对所有都增加窥探,而是有针对性的增加。
图15
另一种变化是使用耦合的忘记和输入门,而不是单独决定要忘记什么、添加什么,这个决定需要一起做。 只有当需要输入某些信息的时候,我们才会忘记这个位置的历史信息。只有当我们忘记一些历史信息的时候,我们才在状态中添加新的信息。
门控循环单元(Gate Recurrent Unit,GRU)_意念回复的博客-CSDN博客
(a=c=h,u:更新门,r:复位门)
图16
zt:更新门
rt:重置门
LSTM的一个稍微更显着的变化是由Cho介绍的门控循环单元(或GRU)。 它将忘记和输入门组合成一个单一的“更新门”。它还将单元格状态和隐藏状态合并,并进行了一些其他更改。 所得到的模型比标准LSTM模型更简单,并且越来越受欢迎。
这些只是最显着的LSTM变体中的几个, 还有很多其他的,比如Depth Gated RNNs,还有一些完全不同的处理长期依赖的方法,例如Clockwork。哪些变体最好、差异的重要性等, Greff做一个很好的变体的比较,发现他们都差不多。 Jozefowicz测试了大量的RNN架构,发现一些RNN结构在某些任务上要比LSTM更好。
keras.layers.recurrent.LSTM(units, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0)
# units: Positive integer, dimensionality of the output space.
model = Sequential()
model.add(LSTM(32, return_sequences=True, stateful=True,batch_input_shape=(batch_size, timesteps, data_dim))) # 此处的32?
model.add(LSTM(32, return_sequences=True, stateful=True))
model.add(LSTM(32, stateful=True))
model.add(Dense(num_classes, activation='softmax'))
类似上述代码中,LSTM(32, return_sequences=True, stateful=True) 中的 “32” 的含义是说明?
问答:
(1)LSTM(units,input_shape(3,1)),这里的units指的是cell的个数么?
这里的units不是cell的个数。这里的units就是输出层的维度。
(2)按照LSTM原理这些cell之间应该是无连接的,那units的多少其意义是什么呢,是不是相当于MLP里面对应隐层的神经元个数,只是为了扩展系统的输出能力?
下面这个是Recurrent NN的结构图。
如果将每个time_step的那个网络简称为A,并且每个网络换成LSTM的gated cell, 则得到以下两个图的LSTM结构。
这里LSTM cell(包括深度学习框架中的LSTM cell)指的是一层cells,即A;而不是MLP中的一个节点。.
Num_units 指的是一层的output size(hidden size), 可不与X_{t}的dim 相等。因为LSTM cell还会有一个非线性变换,即里面W_{t}权重矩阵会变换 input dim 为 output size。故权重矩阵使得在 time_step_{t} 的 x 的 dim 变换为 output hidden size。
示例:
你有一段话,这段话有100个字,你经过一种embedding作用(e.g. Word2Vec),每个字都用一个300维的向量表示。那么这100个字是有先后顺序的,也就是时序信息的。所以,你现在相当于有一个[100,300]的矩阵,这就是你的input。现在,有一个神奇的DL层,经过这个层之后呢,你原来的[100, 300]矩阵,就会变成[100,128]的矩阵。这里的300维降到128维,可以想“全连接”层,也就是相当于过了一个隐含层,得到了隐含表达(hidden representation)。
上面提到的神奇的DL层就是LSTM!
假如现在处理第50个字:第50个字 (300维)以及前面49个字的隐状态,也就是别的答案里的cell的状态, (128维), 这两个会拼接在一起形成一个428维的输入。这个输入会在当前的cell中,分别经过那4个小黄框。每个小黄框的输出都被设定成为128维度(就是你赋给units的值), 所以后面的一些列操作都是在128维基础上进行相乘、相加(就是图里的红色的小圆圈)。一系列操作之后,你会产生一个 ,也是128维度的,如此进行下去...
详见:LSTM反向传播求导_意念回复的博客-CSDN博客_lstm反向求导
如果是多个时间步,就是多个类似公式的累乘。从这一步的结果中我们可以发现,对于普通的RNN,的最终要么总是大于1,要么总是在[0, 1]范围内,这将导致梯度消失或者梯度爆炸。其结果的取值范围并不一定局限在[0,1]中,而是有可能大于1的。而对于LSTM,在任何时间步,该值可以大于1,或者在[0, 1]范围内。
LSTM增加了更多回传梯度的路径,只要一条路径没有梯度消失,那么梯度消失的问题就得到了改善。
那么什么情况下大于1?
这个由LSTM自身的权值决定,那权值从何而来?当然是学习得到的,这便是LSTM牛逼之处,依靠学习得到权值去控制依赖的长度,这便是LSTM缓解梯度消失的真相。综上可以总结为两个事实:
1、cell state传播函数中的“加法”结构确实起了一定作用,它使得导数有可能大于1;
2、LSTM中逻辑门的参数可以一定程度控制不同时间步梯度消失的程度。
最后,LSTM依然不能完全解决梯度消失这个问题,有文献表示序列长度一般到了三百多仍然会出现梯度消失现象。如果想彻底规避这个问题,还是transformer好用。
[LSTM]时间序列预测存在的问题--滑动窗口是一把双刃剑【持续更新】:[LSTM]时间序列预测存在的问题--滑动窗口是一把双刃剑【持续更新】 - 百度文库
吴恩达视频:【中英字幕】吴恩达深度学习课程第五课 — 序列模型_哔哩哔哩_bilibili
如何简单的理解LSTM——其实没有那么复杂:如何简单的理解LSTM——其实没有那么复杂 - 简书
Understanding LSTM Networks:http://colah.github.io/posts/2015-08-Understanding-LSTMs/
用 LSTM 做时间序列预测的一个小例子:用 LSTM 做时间序列预测的一个小例子 - 简书