LSTM

Posted on By Jason Hao

宏观理解

LSTM是长短期记忆的简称,用于处理有时序信息的文本。它的诞生旨在解决RNN的梯度爆炸和梯度消失问题。在RNN的隐含层中由于随着句子的长度变长,梯度会产生各种问题, 例如如果梯度小于1时,n多个隐含层连乘会导致趋向于0;大于1是会导致趋向于正无穷。所以在RNN中解决这个问题的途径比如说我们随机的drop out掉某些隐含层的值,这样在 梯度会大大减缓爆炸或者消失的问题。但是有人就想,我们可不可以让模型自己学出来,该在哪里drop out掉哪些隐含层呢?LSTM的诞生就解决了这个问题。

可以看出,在从RNN到LSTM的变化,其实只是把原来的一个去线性层复杂化了一点,下面我们会分析一下到底复杂在了哪里。

微观分析

我们看到下面是一个LSTM的cell

看起来很复杂但是我们一点一点拆开来看。

我要去遗忘什么?

首先我们看一下forget gate layer遗忘门,他的目的是来控制“我要去遗忘什么?”

每一个时刻的input xt要和上一层传来的隐含层做一个sigmoid,我们知道sigmoid的结果无非是0/1,那么我们就可以把0当成是“遗忘”,把1当成是“记住”。所以在 模型学习的过程中,如果此刻的结果变成了f_t = 0,那么也就意味着再和上一层进来了C点乘,那也还是0。

我要写入什么?

接下来我们看input gate layer输入门,他的目的是来控制“我要去写入什么?”

和遗忘门相同的原理,我们用i来作为要不要写入的判断,然后我们新引入一个C值来控制我们要写的东西的内容。

遗忘什么并且写入什么?

接下来我们有了之前的遗忘的内容和要写入的内容,我们就可以做一个整合,叫做long term memory长久记忆区,用来整合“遗忘什么并且写入什么?”

从长久记忆区拿出什么作为输出?

最后我们有一个output gate输出门,用来掌控“从长久记忆区拿出什么作为输出?”

像前面的遗忘门和输入门一样,我们先要一个控制器来判断我们要不要拿出来一些记忆,所以我们的o用来判断拿还是不拿。然后我们要输出的内容肯定是在记忆区C的里面,所以 我们用tanh过一下记忆区来找一下我们应该输出哪些记忆。

一整个隐含层的计算流程

多种变体

很多LSTM的应用并不会使用最基本的结构,会在基础上加一些变体。我们一起来看另外的3种变体:

Peephole connections

唯一的区别就是在三种门的计算中,加入了之前的长久记忆。

Coupled forget and input gates

唯一的区别在于原本的LSTM的遗忘门和输入门是独立存在的个体,互不影响。现在我们想让他们一起来做决定。

Gated Recurrent Unit

也算是大名鼎鼎的LSTM变体GRU了,为了省略LSTM中臃肿的参数,提出了一种只包含两个门的变种,把遗忘门和输入门结合为一个“更新门 update gate”利用了更少的参数计算,但是效果有时未必有LSTM好。

双向LSTM

双向的LSTM我们可以认为他就是两个单向的LSTM组合在一起。

有时候我们需要从上下文来考虑问题,所有从一句话的前到后和后到前我们都想要考虑到。 下面的这个图可视化了三种模型对句子中每个词学习到的重要程度,可以发现如果我们用单向的LSTM它可以把前面的单词学习的很好,但是越往后学习能力越不够,所以这个时候如果还有另一个LSTM从句尾往前学习一遍就可以弥补这个不足。