理解LSTM网络

理解LSTM网络

循环神经网络(RNN)

人们不会每时每刻都在冥思苦想一些事情,比如当你看到这篇短文时,你会很自然的理解其中的每一个句子,每一个字,因为我们在之前(小时候)就理解了中文。你不会每次都学了马上忘,导致下次看到又得重新学。简单来说,我们的思想,记忆是持续存在的。

传统的神经网络就不能做到这一点,这看起来是一个很致命的缺点。举个例子,当你想要分类电影中的事件时,目前还不清楚如何利用传统神经网络对电影中之前事件的描述来推理后来的事件。

循环神经网络可以处理这个问题。循环神经网络中有内在循环,使得信息可以持续存在。

RNN-rolled.png

在上面的示意图中, /A/表示一块神经网络, /x/和/h/分别代表输入和输出。循环允许信息从当前的网络传到下一个网络

这些循环让循环神经网络看起来有点神秘,其实,如果你仔细看的话,你会发现他们和普通神经网络也没什么大的区别。循环神经网络可以看成是一个网络的多个副本,每一个副本都会把信息传到下一个副本。想象一下把循环展开的样子

RNN-unrolled.png

这条链接本质上展现了循环神经网络是和序列密切相关的。对于这种数据(序列,列表等),神经网络就自然的被设计成这种结构体系。

在过去几年,人们用循环神经网络在很多应用取得巨大成功,比如语言识别,语言建模,翻译,图像描述等。以后我将讨论Andrej Karpathy的优秀博客文章“循环神经网络的不合理有效性”所获得的惊人成就,真的很棒。

特别的,取得的成功中很大一部分是应用了LSTM,一种循环神经网络的特别版本,对于很多任务,LSTM的表现都要比普通版本的要好得多。几乎所有用循环神经网络取得的重大成果都是用LSTM实现的。接下来我们就来探索LSTM。

长期依赖的问题

RNN一个很吸引人的地方是,它可以将以前的信息与当前的任务相关联,例如使用先前的视频帧可以促进对当前帧的理解。如果RNN可以做到这一点,他们会非常有用。但他们可以吗?这得看情况。

有时候,我们仅仅只需要周围临近的信息。想象有这么一个语言模型,它会根据输入的词语或者句子来预测接下来的字。比如,我们输入 /云飘在/ ,它可能就会预测出 /天空/。我们不需要知道更多,更远的内容,很明显下一个词会是天空。这种情况下,相关的信息彼此的间隔和空间只需要很小,RNN可以学习这样传递信息。

RNN-shorttermdepdencies.png

但是也有很多情况我们需要更多的内容。想象在这边长文里”我在法国长大,………,我经常讲 (法语)。” 临近的信息会认为接下来的词语会是语言,但是如果我们想要知道是哪种语言,那就得通读全文才知道。所以在这种情况下,相关的信息彼此的间隔和空间就会变得很大。

不幸运的是, 随着间隔慢慢变大时,RNN会越来越没有能力去连接彼此的信息。

RNN-longtermdependencies.png

理论上,RNN绝对有能力解决这种长期依赖的问题。我们可以针对不同问题特定的调整参数。但是很遗憾,在实践中,RNN却没办法学习较远的信息。Hochreiter(1991)[德文]和Bengio等人深入探讨了这个问题。 他们发现了一些根本原因,但可能很难解决。

谢天谢地,LSTM没有这个问题。

LSTM 神经网络

长短期依赖记忆网络 (Long Short Term Memory networks) ,简称LSTM,一种特别的RNN,可以解决长期依赖的问题。LSTM 是由Hochreiter&Schmidhuber 提出的,并且被许多人改进和推广. 他们在各种各样的问题上表现得非常好,现在被广泛使用。LSTM 就是专门设计来解决长期依赖问题的。存储长期信息是LSTM默认的行为或者功能,而不是难以实现的事情。

所有循环神经网络都有神经网络中循环的链式结构。在标准的RNN中,循环模块只是具有非常简单的结构,比如单个tanh 层

LSTM3-SimpleRNN.png

LSTM 同样也有这样的链式结构,但是循环模块却和RNN的不一样。相比于单个简单的神经网络层,LSTM有多达四层,以十分特别的方式交互着。

LSTM3-chain.png

不用担心看不懂,接下来我们会一步一步来讲解LSTM模型。首先,让我们先来学习一些会用到的记号

LSTM2-notation.png

在上面的图中,黄格表示一个层神经网络。粉红色的圆圈代表对位运算,比如向量加法。每一条黑线都表示一个完整的向量,从输出的节点到输入的节点。线的汇合表示向量的合并,而线的分叉指的是向量和向量的副本去了不同的地方。

在LSTM背后的代码智慧

LSTM的关键点在于神经元的状态,在下面的图中,一条水平线穿过图像的最上方。

神经元的状态有点类似于传送带。它笔直地穿过整个链,而且只进行了较少的线性运算。这对于只需要流动传输未改变的信息来说是非常简单的实现。

LSTM3-C-line.png

LSTM 可以删除或者添加信息进神经元的状态,是由称为的结构仔细调控的

可以控制信息的流动。门是由sigmoid神经网络层和一次点乘运算组成的。

LSTM3-gate.png

sigmoid层的输出值范围是0-1,表示着每一个数据应该过去多少。0 表示什么都别想通过,而 1 表示所有的都通过。

一个LSTM 有着三个这样的门来保护和控制神经元的状态。

循序渐进的LSTM

LSTM的第一步决定着什么信息应该被神经元舍弃。这一步是由被称为”忘记门”的sigmoid层决定的。输入是/ht-1/ 和/xt/,且输出值区间为0-1。1代表完全保留,0代表完全舍弃。

回到一开始的例子,我们试图通过上下文预测词语。比如,神经元储存着当前主语(人)的性别,这样我们可以预测出正确的代词(他或她)。但如果有新的主语时,我们自然的就会忘记旧的主语的性别(忘记门决定的)

LSTM3-focus-f.png

第一步是忘记,那么很自然的,LSTM的第二步就是决定什么信息该被存储到神经元中。这一步分为两部分:第一,一个被称为输入门的sigmoid层决定什么信息应该被更新;第二,tanh层创建一个可以添加进神经元状态的新候选向量 /~Ct/ 。最后,我们结合这两部分来对神经元状态进行更新。

回到前面的例子,我们添加新主语的性别来代替被忘记的旧主语的性别

LSTM3-focus-i.png

现在我们将神经元状态 /Ct-1/ ,更新为/Ct/。了解了大概的思路,现在就来动手操作一下。

将旧状态乘以/ft/,忘记一些信息。然后加上/it * ~Ct/。/it * ~Ct/是新的候选值,取决于我们想对状态做多少更新。

LSTM3-focus-C.png

最终,我们需要决定该输出什么。输出得基于当前神经元的状态,但不是随意输出,我们会对输出过滤。首先,我们会用一个sigmoid层决定在旧状态和当前输入中,什么应该被输出,然后我们将当前的神经元状态通过tanh函数处理,再乘以sigmoid层的输出,就可以得到最终的输出了。

LSTM3-focus-o.png

这样我们就明白了LSTM的内部构造和实现原理了

LSTM的不同版本

上面我们描述的是一个很普通的LSTM的版本。不一定所有的LSTM都像上面那样。事实上,几乎每篇论文中使用的LSTM都是和普通版本有点不同。虽然区别不大,但是还是很值得去了解当中的细节的

(译者:很抱歉,这章节不翻译,如果有兴趣的话建议阅读英文原文

结论

早些时候,我提到了人们用RNN实现的显著成就,几乎都是运用的LSTM。LSTM在大多数情况下表现真的很出色。这边文章由浅到深的介绍LSTM,希望能让LSTM更加通俗易懂,而不是一大堆复杂的公式推导。

LSTM 是在RNN上迈出的一大步。自然的,还有没有其他在RNN上的卓越成就呢?答案是有的。这个想法是让RNN的每一步都从更大的信息集合中挑选信息。例如,如果您使用RNN创建描述图像的标题,则可能会选取图像的一部分来查看其内容。事实上,Xu等人做到了这一点 – 如果你想探索注意力模型,这可能是一个有趣的开始!有一些令人兴奋的结果使用了注意力,而且似乎还有更多的事情正在……