理解 LSTM 网络

作者:Christopher Olah   翻译:Yangyu Chen
原文:Understanding LSTM Networks

循环神经网络

人类在思考问题的时候并不总是从头开始的。当你在读这篇短文时,你对当前读到的每个字的理解,是建立在对之前内容理解的基础上的。你并不是把所有的东西扔掉然后从头开始思考。换句话说,你的思考具有延续性。

传统的神经网络无法模拟人的这一行为,这似乎是一个巨大的缺陷。例如,假设你想要对电影中发生的每一个事件进行分类,我们不知道如何让传统的神经网络去利用先前的推断结果作出下一个推断。

循环神经网络(Recurrent neural networks,RNN)解决了这个问题。它们是具有循环结构的网络,这使得它们能够保存信息。

循环神经网络具有循环结构。

在上面这幅图中,一个神经网络$A$,以$x_{t}$为输入,然后输出$h_{t}$。循环结构使得信息能够一步一步地在网络中传递。

这些循环使得 RNN 看起来有点难以理解。然而,如果仔细思考一下,就会发现它和通常的神经网络没有什么不同。一个循环神经网络可以被看成是同一个网络经过多次复制得到,每一个部分都往下一个部分传递消息。考虑一下当我们把循环展开之后会发生什么:

一个展开的循环神经网络。

这种链式的结构自然地揭示了循环神经网络与序列和列表紧密相关。这是处理序列数据的神经网络的天然结构。

而且它们毫无疑问是有用的!在过去的几年中,在许多问题上使用 RNN 都取得了令人难以置信的成功,比如:语音识别,语言建模,翻译,图像描述…这个清单还在增长。想要知道我们能够用 RNN 做出什么样的惊艳工作,可以参考Andrej Karpathy 所写的精彩博文The Unreasonable Effectiveness of Recurrent Neural Networks。不得不说这真是太令人惊讶了。

这些成功的关键是使用了“LSTM”,一种非常特殊的循环神经网络,它在许多任务上都比标准的 RNN 更有效。几乎所有基于 RNN 取得的良好结果都用到了 LSTM。 LSTM 就是我们这篇文章的主角。

长期依赖的问题

RNN 设计理念的一个吸引人之处是,它能够把当前的任务和先前的信息连接起来,比如利用前一段时间的视频帧来理解当前帧的内容。如果 RNN 真的能够做到这个,那将会是非常有效的。但确实能做到吗?这得看情况。

有时候,我们只需要知道近期的信息就能处理当前的任务。比如,考虑一个基于前几个单词来预测后一个单词的语言模型。如果我们想预测句子“the clouds are in the sky”的最后一个单词,我们不需要更多的信息——很显然最后一个单词就是“sky”。在这种情况下,被预测信息和其相关信息之间的间隔是很小的,RNN 可以学会如何使用过去的信息。

但是有时候我们也会需要更多的上下文信息。考虑预测句子“I grew up in France… I speak fluent French”的最后一个单词。短期的信息提示我们最后一个单词很可能是一种语言的名字,但是如果我们想确定是哪种语言,我们需要再往回走一点,找到“France”这个线索。被预测信息和其相关信息之间的间隔非常大是完全有可能的。

非常不幸,随着信息间隔的扩大,RNN变得越来越难以学会如何去连接相关的信息。

理论上,RNN 完全具有处理这种“长期依赖”的能力。人们可以精心挑选参数来解决上述形式的简单问题。可惜,在实践中,RNN 似乎无法学会远距离的信息连接1Hochreiter (1991)[German]Bengio等人(1994)深入地研究了这个问题,并且指出了问题难以被解决的原因。

幸运的是,LSTM 能解决这个问题!

LSTM 网络

长短期记忆网络(Long Short Term Memory networks)——常被简称为“LSTM”——是一种特殊的 RNN,能够用来学习长期依赖。它由Hochreiter和Schmidhuber(1997)提出,并在之后的工作中被优化和推广开来2。它在许多问题上有着非常好的效果,并且现在已经被广泛使用了。

LSTM 是为了解决长期依赖的问题而设计的。长时间地记住一段信息是它的默认的行为,而不是需要努力去学习才能做到。

所有的循环神经网络都能够用一串重复的神经网络模块来表示。对于普通的神经网络,被重复的模块具有简单的结构,比如单层的 tanh 层。

RNN 的循环模块具有一个层。

LSTM 同样也有着这种链式结构,但是其中的模块具有不同的构造。不同于只有一个神经网络层,LSTM 的模块中有四个网络层,并且通过一种特别的方式进行数据传输。

LSTM 的循环模块具有四个交互层。

不用担心其中的细节。我们接下来会一步步地讨论 LSTM 的每一个步骤。现在,让我们先熟悉一下将要用到的标记符号。

在上面这幅图中,每一条线都表示一整个向量,并且从流出的节点被送到流入的节点。粉红色的圆圈表示对向量进行逐元素的运算,比如向量加法。黄色的方框是学出来的神经网络层。汇聚的线条表示数据的串联,而分叉的线条表示数据被拷贝然后分发到不同的位置。

LSTM的核心思想

LSTM 的关键是细胞(cell)状态,由横穿示意图上部的水平直线所表示。

细胞状态的更迭有点儿像传送带的运行,它随着整个模块链延伸下去,偶尔进行一些小型的线性交互。可以很容易地让信息利用细胞状态行传递而不发生改变。

在一种叫做门(gate)的结构的精心控制下,LSTM 具有往细胞状态中添加或者移除信息的能力。

门是一种控制信息传递的通道。它由一个 sigmoid 神经网络层和逐元素乘法运算构成。

sigmoid 层的输出在0到1之间,用来描述每一个部分被传递的情况。0意味着“禁止通行”,而1意味着“完全放行!”

在一个 LSTM 模块中三个这样的门,用来保护和控制细胞状态。

LSTM 的运行步骤

LSTM 的第一步是决定需要从之前的细胞状态中剔除多少信息。这个决定由一个被称为“遗忘门层”的 sigmoid 层作出3。它考虑$h_{t-1}$$x_{t}$,然后为细胞状态$C_{t-1}$的每一位输出相应的0到1之间的数字。输出1表示“完全保持这部分信息”,而输出0表示“剔除这部分的信息”。

让我们回到语言模型的例子,通过输入的上一个单词来预测下一个单词。在这个问题中,细胞状态需要保持当前主语的性别信息,这样就能确定该用哪个代词。当我们看见一个新的主语时,就要把旧主语的性别信息遗忘掉。

下一步是确定哪些新信息需要被存储到细胞状态中。这由两部分组成。首先,一个被称为“输入门层”的 sigmoid 层决定哪些信息需要被更新。然后,一个tanh层产生一个新的候选值向量$\tilde{C_{t}}$,它能够被加入到细胞状态中。接下来,我们把上面两部分的结果合并,然后去更新细胞状态。

在我们的语言模型例子中,我们想要把新主语的性别信息加入到细胞状态中,去取代要被遗忘掉的旧主语的性别信息。

是时候把旧的细胞状态$\tilde{C_{t-1}}$更新到新状态$\tilde{C_{t}}$了。上面的步骤已经确定了该做什么,我们要做的就是去执行它。

我们让旧的细胞状态与$f_{t}$逐元素相乘,以此把之前决定要遗忘的东西遗忘掉。然后再加上$i_{t}*\tilde{C_{t}}$,即根据每一个状态分量的通过系数进行调整后的候选向量。4

在语言模型的例子中,上述的过程就是把旧的性别信息换成新的性别信息的过程。

最后,我们需要确定将会输出什么内容。输出将会根据细胞状态,但是会进行一些过滤。首先,我们使用一个 sigmoid 层来决定哪部分的细胞状态将要被输出。然后,我们把细胞状态送入tanh(把数值范围变到-1到1之间)函数。最后把上面两部分的输出逐点相乘,这样我们就能只输出想输出的内容5

对于语言模型的例子,由于模型刚刚看见了一个主语,它可能会输出与动词有关的信息,以便在需要的时候产生正确的动词。例如,它可能会输出主语是单数还是复数,所以如果接下来要产生一个动词,那么就知道该选择什么样的词形。

长短期记忆的变种

上面我所描述的是最通常的 LSTM。并不是所有 LSTM 的结构都是如此。实际上,好像几乎所有的论文里所用的 LSTM 都会做一些小改动。不同之处一般是很细微的,但是有一些改动还是值得一说的。

Gers和Schmidhuber(2000)提出了一种常用的 LSTM 变种,它加入了“窥视孔连接”(peephole connections),这使得各个门的神经网络层能够看见细胞状态6

上图中为所有的门加入了窥视孔,但是在许多论文中只会为部分的门增加窥视孔。

另外一个变种是把遗忘门和输入门合并。不同于分别决定哪些部分要被遗忘,哪些部分需要加入新信息,我们现在同时作出决定。我们只遗忘那些需要被更新的部分,(或者说)我们只更新那些被遗忘掉的部分。

Cho等人(2014)提出了一种改动较大的 LSTM 是门循环单元(Gated Recurrent Unit),也被简称为 GRU。它把遗忘门和输入门 合并成一个“更新门”(updategate)。它还把细胞状态和隐层状态合并,然后有一些其它改动。最终的模型比标准的 LSTM 简单,并且变得越来越流行。

上面提到的只是一些 LSTM 的著名变种。除此之外还有一些,比如 Yao等人(2015) 提出的带有深度门的 RNN(Depth Gated RNNs)。还存在着一些处理长期依赖的不同方法,比如Koutnik等人(2014) 提出的发条 RNN(Clockwork RNNs)。

哪一种变种是最好的呢?这些改动有什么用处吗?Gref等人(2015) 对流行的变种做了一个很好的比较,发现它们其实是一样的7Jozefowicz等人(2015)对超过一万种 RNN 结构进行测试,发现有一些结构在某个任务下会比 LSTM 效果好些。

总结

之前我曾提过人们使用 RNN 作出的惊艳结果。实际上他们所用的几乎都是 LSTM。LSTM 确实在大部分任务上都比原始的 RNN 更有效。

用一大堆公式来定义的 LSTM 看起来挺唬人的。希望本文中对它的一步步介绍能够让 LSTM 显得平易近人一些。

LSTM 的提出是使用 RNN 的一大进步。很自然地,我们会想:还可以再进一步吗?研究界的共识是:“当然!下一个突破口就是注意力(attention)机制!”核心思想就是让 RNN 的每一步都从一个大的信息集合中挑选一部分信息。比如,如果要用 RNN 来对一张图片产生一句话的描述,可以让它在生成每一个单词的时候都只关注图片的某一部分。实际上,Xu等人(2015)就是这么做的——如果你想研究注意力机制,这可能是一个有趣的起点!还有许多已有的工作是从注意力的角度考虑的,而且似乎有更多的工作与注意力机制有关…

注意力机制并不是 RNN 研究的唯一分支。例如,Kalchbrenner等人(2015) 提出的网格 LSTM(Grid LSTMs)也是一个很有前途的工作。把 RNN 用于产生式模型8——例如Gregor等人(2015)Chung等人(2015),和Bayer与Osendorfer(2015) 的工作看起来都很有趣。过去的几年是循环神经网络发展的黄金时期,而接下来的几年很有可能更是如此!

致谢

我要感谢许多帮助我更好地理解 LSTM,对可视化结果进行评论,以及对这篇文章作出反馈的人。

非常感谢我在Google的同事的有益反馈,特别要感谢Oriol VinyalsGreg CorradoJon ShlensLuke VilnisIlya Sutskever。我还要感谢许多花费时间帮助我的朋友和同事,包括Dario AmodeiJacob Steinhardt。特别要感谢Kyunghyun Cho为我的示意图和我进行的细致讨论。

在写这篇文章之前,我曾在两个研讨课程中讲解神经网络,并且尝试解释 LSTM。感谢每一位课程参与者对我的耐心和反馈。


  1. 1.原文为:Sadly, in practice, RNNs don’t seem to be able to learn them.
  2. 2.除了原文作者,许多人为 LSTM 的发展作出了贡献。一个不完整的名单包括:Felix Gers, Fred Cummins, Santiago Fernandez, Justin Bayer, Daan Wierstra, Julian Togelius, Faustian Gomez, Matteo Gagliolo, 和 Alex Graves。
  3. 3.译者注:sigmoid 层的工作机制可以分成两部分,首先是对输入做一个仿射变换($z=Wx+b$),然后把变换的结果传入 sigmoid 函数中($o=sigmoid(z)$),得到输出结果。
  4. 4.译者注:$*$表示逐元素相乘。
  5. 5.译者注:其实细胞状态的输入和输出机制是很像的,都是用一个 sigmoid 门来控制要输出的部分,同时用 tanh 把原有的信息进行数值压缩。使用 tanh 的好处是它的导数是$1-(\tanh(x))^{2}$,范围在[0,1]。而使用 sigmoid 使得输出范围为[0,1],正好可以用来表示数据通过的程度。
  6. 6.译者注:即把细胞状态也作为各个门的神经网络层的输入的一部分。
  7. 7.原文为:finding that they’re all about the same
  8. 8.原文为:Work using RNNs in generative models
本文总阅读量:

转载请保留以上信息。