拆解长短期记忆网络LSTM-其实并不难懂
写在前面
本文绝大部分内容翻译自Understanding LSTM Networks,这是一篇相当清晰的讲解LSTM的文章,文章做到了避开了复杂公式的同时还讲清楚了这一较为复杂的RNN网络。
本文在翻译的过程中并未逐字逐句翻译,但求易读,同时还结合了一些自己的理解和Andrew Ng课程中的笔记,力求清楚准确地理解LSTM及其变体。
循环神经网络
我相信你在阅读这篇文章时,对每句话的理解都是建立在前文的基础上。你不会完全抛开所有的前置信息去孤立思考,因为思考是有连贯性的。
就像在看电影肖申克的救赎一样,不沉浸于故事发展带来的窒息感之中又怎能体会故事结尾带来自由感?但我们似乎无法理解传统的神经网络怎样能利用前置的事件去对后续的场景进行推理。显然,无数的实践也告诉我们,传统的神经网络并不能做到这一点,这也是其一个显著的短板。
循环神经网络则不然,其网络结构中包含了循环结构,允许信息在网络前后结构中得以保留,从而能够很好地解决这一问题。
如上图,一个神经网络A,接收\(x_t\)并输出值\(h_t\)。循环结构使得信息可以从一个步骤传递到下一步中。
这些循环结构使得RNN网络看起来有一点神秘。然而,如果能更进一步思考,你就能发现RNN和普通的神经网络也没有完全不一样。一个RNN网络通常可以看成是多个相同结构的堆叠,每一个子结构都将传递一部分信息到下一个子结构。我们不如将循环结构展开来观察一下到底发生了什么:
这样链状的结构天然地揭示了RNN网络与序列等结构是相关的。从直接上判断,这毫无疑问是一种天然地适合处理序列问题的神经网络结构。
这种网络结构也确实得到了应用!在过去的几年里,RNN网络已经在语音识别、语言模型、机器翻译、图像字幕处理等一系列问题上取得了难以置信的成功。关于具体的成就,我们这里不做讨论,关于使用RNN可以实现的惊人壮举的相关讨论在Andrej Karpathy的优秀博文The Unreasonable Effectiveness of Recurrent Neural Networks中可以看到。
LSTM在这一系列的成功中有着至关重要的地位。这是一种非常特别且在很多任务上都有效的RNN网络,其效果比标准的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却似乎的确无法应对这些问题。Hochreiter和Bengio,曾经深入的研究过这个问题,他们发现一些关于为什么RNN难以应对这种问题的根本性原因。
如上图讲义所示,基础的RNN无法有效处理相关问题的根本原因在于Vanishing gradients with RNNs,即序列过长导致的在反向更新时发生了梯度消失的问题,这也就直接导致了序列模型的前后输入无法有效地相互影响。
令人振奋的是,LSTM不存在这样的短板。
LSTM网络
长短期记忆网络,通常又被称为LSTM,是一种能够学习到长期依赖的特殊的RNN模型。LSTM由Hochreiter&Schmidhuber提出,被后来人进行了改进和普及。LSTM及其变体在各种各样的问题上表现非常好,现在已经得到了广泛使用。
LSTM在设计之初就是为了解决长期依赖的问题。对于LSTM而言,记住长期的信息是一种直接的设定,而并非是需要专门去学习到能力。
所有的RNN网络都有着链式的重复神经网络结构。对于标准的RNN网络,重复组件通常只是非常简单的结构,比如一个单层的tanh
层。
LSTM模型也有这种链式结构,但是这种重复组件有着不同的结构。区别于简单的神经网络层,LSTM的重复组件通常有4个以非常特别的方式交织在一起的网络层。
不用过早担心细节问题,我们将一步一步讲解LSTM模型图。这里先熟悉我们将会用到的标记。
在上图中,每一行都带有一整个向量,该向量从一个节点输出到其他节点作为输入。粉红色圆圈表示按位相乘,而黄色框是学习神经网络层。线的合并表示连接,而线的交叉表示内容复制,且副本将转到不同的位置。
LSTM背后的核心思想
LSTM的关键在于细胞状态(记忆细胞, Memory Cell),细胞状态在图中表示为顶部的一条贯穿水平线。
细胞状态就像是一条传送条,运行在整个链条上,只进行一些线性操作。因此,很容易使得流动信息保持不变。
LSTM有往细胞状态上添加和移除信息的能力,这个能力是被网络结构的门(gate)机制控制的。
门可以选择性控制信息流通。门值由一个sigmoid层和逐点乘运算得到。
sigmoid层的输出值域在0到1之间,描述了每一个组件有多少信息能够通过(由于sigmoid函数的特性,可以使得计算结果通常聚集到0/1两侧)。门值为0则代表不让任何信息通过,而1则代表让全部的信息通过。
一个LSTM模型中有三个这样的用来保护和控制细胞状态的门。[遗忘门
、更新门
、输出门
]
一步一步拆解LSTM
LSTM的第一步即决定将要从细胞状态中移除掉哪些信息,这是由sigmoid层的“遗忘门”所决定的。它的输入为\(h_{t-1}\)(前一个步隐藏层输出)和\(x_t\)(当前元素输入),并为细胞状态\(C_{t-1}\)(上一个状态)中的每个数字计算0和1之间的状态数值。1代表完全保留,而0代表彻底删除。
让我们回到语言模型的例子,试图基于以前的语料来预测下一个单词。在这样的问题中,细胞状态可能包括当前主语的性别,从而决定使用正确的代词。当我们看到一个新主语时,我们想要忘记旧主语的性别。
下一步需要做的是决定在细胞状态中保存哪些信息。这涉及了两个部分。首先,被称为“输入门层”的sigmoid层决定了我们将更新什么值。随后,一个tanh层创建了一个新的候选值向量\(\overline C_t\),这个值将会加到细胞状态上。接下来,我们将结合这两部分信息去更新细胞状态。
在我们的语言模型例子中,我们想要将新主语的性别加到细胞状态中,同时替代掉我们想要遗忘的旧信息。
是时候需要更新旧的细胞状态\(\overline C_{t-1}\)为新的细胞状态\(\overline C_{t}\)。先前的步骤中已经决定了需要做哪些调整,接下来我们就需要切实去实现。
我们将上一时刻的细胞状态信息乘以\(f_t\)(按位相乘),移除掉我们决定遗忘的信息,然后加上\(i_t\) * \(\overline C_t\),就这就是我们新的候选值。
在语言模型的例子中,这对应了我们丢弃的旧主语性别信息和加上新的信息的操作,这些都是我们在上述的步骤中决定的。
最后,需要决定我们将要输出哪些信息。输出将基于细胞状态,但将会是一个过滤版本。首先,我们运行一个sigmoid层,这决定了哪些部分的状态信息将要输出。随后,我们对细胞状态做tanh运算(将数值映射到-1和1之间),并将计算结果与输出sigmoid层相乘,因此我们可以得到我们只想输出的部分。
对于语言模型例子来说,由于只看到一个主语,考虑到后面可能出现的词,它可能需要输出与动词相关的信息。例如,它可能会输出主语数还是复数,以便我们知道动词应该如何组合在一起。
上图中的一些公式变量符号与文章中的变量符号不同,但都是有一一对应。贴上这张图,以便与后续的LSTM变体相互比对,可以明显看到GRU、"peehole connections"以及"耦合遗忘门与更新门"改进后与改进前的区别(个人感觉GRU明显是集大成者)。
LSTM的变种
目前为止,我们所描述的都是正常的LSTM。但也并不是所有的LSTM结构都与上述完全相同。事实上,几乎每一篇涉及LSTM的论文都使用了一个略用不同的差异很小的版本,但有些也都还值得一看。
一个比较流行的LSTM变种是Gers & Schmidhuber (2000)提出的,添加了"peephole connections"。这也意味着,我们允许gate层去“偷窥“状态细胞,即同时考量了上一层的状态细胞信息来做决策(这一操作在GRU中直接得到了更进一步的简化)。
上面的图中的所有sigmoid层都增加了窥视,但是很多论文实现并不是针对所有层都增加窥视,而是有针对性的增加。
另一种变体是使用耦合的遗忘和输入门,而不仅仅是单独要忘记或者添加上面,这样的决策需要一起作出。只有当需要输入某些信息的时候,我们才会忘记这个位置的历史信息。也只有当选择忘记一些历史信息的时候,才会在状态中添加新的信息。
LSTM的一个有着显著变异的版本是由Cho提出的门控制单元(GRU)。GRU将遗忘门和输入门组合为一个单一的更新门。它还将细胞状态和隐藏状态合并为了一个变量(即\(a^{<t>}\) = \(c^{<t>}\)),并做了一些其他的改进。所得到的模型比标准LSTM更加简单,且越来越受欢迎,更容易用作组件来堆叠一个大型的网络结构(但LSTM的复杂结构保证了其强大且灵活的特质,也使得其往往成为实践中的首选)。
这些只是最显着的LSTM变体中的几个, 还有很多其他的,比如Depth Gated RNNs,还有一些完全不同的处理长期依赖的方法,例如Clockwork。为了得到哪些变体最好,判断差异的重要性等, Greff做一个很好的变体的比较,发现他们都差不多。 Jozefowicz测试了大量的RNN架构,也发现一些特定的RNN结构在某些任务上要比LSTM表现更好。
结论
此前,我提到人们通过RNN实现了显着的成果。基本上所有这些都是使用LSTM实现的,对于大多数任务而言LSTM很有效。
一般介绍LSTM的文章大部分会写一大组方程式,这使得LSTM看起来很吓人。 希望通过这篇文章的逐步讲解,帮助读者更好的理解LSTM。
LSTM是我们使用RNN的一个巨大进步。 很自然的想法:还能更大的进步吗? 研究人员的共同观点是——有,那就是注意力模型。这个想法是让RNN的每一步挑选信息的过程都参照上层的主题信息,关于Attention模型后面我会再进行详尽的描述,这里不再讨论。
希望通过本文让想了解和使用LSTM的人能够了解其工作原理,能更好的使用,不被大量的数学公式和推导所阻碍。
写在后面
偶然看到这篇文章,短小精悍, 但也算是讲清楚了,建议食用。