LSTM入门介绍
我们先来看看基本的LSTM示意图:
为了解决记忆只是基于naive的线性相加造成学习能力弱,引入了input gate和output gate,控制不同时序记忆的影响因子。
下面来看看具体的LSTM前向传导过程:
输入信息前向传播
(以下图片内容出自“Understanding LSTM Networks”)
LSTM的第一步是决定我们要从细胞状态中丢弃什么信息。 该决定由被称为“忘记门”的Sigmoid层实现。它查看ht-1(前一个输出)和xt(当前输入),并为单元格状态Ct-1(上一个状态)中的每个数字输出0和1之间的数字。1代表完全保留,而0代表彻底删除。
让我们回到语言模型的例子,试图根据以前的语料来预测下一个单词。 在这样的问题中,细胞状态可能包括当前主题的性别,从而决定使用正确的代词。 当我们看到一个新主题时,我们想要忘记旧主题的性别。
下一步是决定我们要在细胞状态中存储什么信息。 这部分分为两步。 首先,称为“输入门层”的Sigmoid层决定了我们将更新哪些值。 接下来一个tanh层创建候选向量Ct,该向量将会被加到细胞的状态中。 在下一步中,我们将结合这两个向量来创建更新值。
(门的**函数使用Sigmoid是为了将输出映射为[0,1],来控制门的打开程度,而输入的**函数使用tanh,一种说法是让信息映射到[-1,1],使得均值接近0,方便后续处理)
在我们的语言模型的例子中,我们希望将新主题的性别添加到单元格状态,以替换我们忘记的旧对象。
现在是时候去更新上一个状态值Ct−1了,将其更新为Ct。前面的步骤已经决定了应该做什么,我们只需实际执行即可。
我们将上一个状态值乘以ft,以此表达期待忘记的部分。之后我们将得到的值加上 it∗C̃ t。这个得到的是新的候选值, 按照我们决定更新每个状态值的多少来衡量.
在语言模型的例子中,对应着实际删除关于旧主题性别的信息,并添加新信息,正如在之前的步骤中描述的那样。
最后,我们需要决定我们要输出什么。 此输出将基于我们的细胞状态,但将是一个过滤版本。 首先,我们运行一个sigmoid层,它决定了我们要输出的细胞状态的哪些部分。 然后,我们将单元格状态通过tanh(将值规范化到-1和1之间),并将其乘以Sigmoid门的输出,至此我们只输出了我们决定的那些部分。
对于语言模型的例子,由于只看到一个主题,考虑到后面可能出现的词,它可能需要输出与动词相关的信息。 例如,它可能会输出主题是单数还是复数,以便我们知道动词应该如何组合在一起。
LSTM的变种
到目前为止,所描述的是一个很正常的LSTM。 但并不是所有的LSTM都与上述相同。 事实上,似乎几乎每一篇涉及LSTM的论文都使用了一个略有不同的版本,差异很小,但有一些值得一看。
一个比较流行的LSTM变种是由Gers & Schmidhuber (2000)提出的,添加“peephole connections”。这意味着,我们允许gate层去看细胞的状态。
上面的图中所有的Sigmoid层都增加了窥视,但许多论文实现不是针对所有都增加窥探,而是有针对性的增加。
另一种变化是使用耦合的忘记和输入门,而不是单独决定要忘记什么、添加什么,这个决定需要一起做。 只有当需要输入某些信息的时候,我们才会忘记这个位置的历史信息。只有当我们忘记一些历史信息的时候,我们才在状态中添加新的信息。
LSTM的一个稍微更显着的变化是由Cho介绍的门控循环单元(或GRU)。 它将忘记和输入门组合成一个单一的“更新门”。它还将单元格状态和隐藏状态合并,并进行了一些其他更改。 所得到的模型比标准LSTM模型更简单,并且越来越受欢迎。
这些只是最显着的LSTM变体中的几个, 还有很多其他的,比如Depth Gated RNNs,还有一些完全不同的处理长期依赖的方法,例如Clockwork。哪些变体最好、差异的重要性等, Greff做一个很好的变体的比较,发现他们都差不多。 Jozefowicz测试了大量的RNN架构,发现一些RNN结构在某些任务上要比LSTM更好。