前言
不知道RNN的一定要先看看RNN的原理
在RNN中我们说了RNN的不足,也就是对较长的时间,或者较长的string,很多时候前面的数据对后面的数据影响就很小甚至没影响了,这是我们就要加强前面的数据的权值;或者数据不是很长,但是最开始的数据对很往后的数据基本没啥影响,但RNN记住了,并对后面的数据产生了影响,这时我们就要往往要增大近期数据的权值。
在本文中,我们将介绍一种改进之后的循环神经网络:长短时记忆网络(Long Short Term Memory Network, LSTM),它成功的解决了原始循环神经网络的缺陷,成为当前最流行的RNN,在语音识别、图片描述、自然语言处理等许多领域中成功应用。
但不幸的一面是,LSTM的结构很复杂,因此,我们需要花上一些力气,才能把LSTM以及它的训练算法弄明白。在搞清楚LSTM之后,我们再介绍一种LSTM的变体:GRU (Gated Recurrent Unit)。 它的结构比LSTM简单,而效果却和LSTM一样好,因此,它正在逐渐流行起来。最后,我们仍然会动手实现一个LSTM。
LSTM长短期记忆神经网络
网络结构
首先我们可以看下普通RNN和LSTM两种网络的区别:
RNN
传统RNN每个模块内只是一个简单的tanh层,这种简单的网络结构决定了他对短期记忆的效果不错,但对长期记忆效果就很不好。
LSTM
与RNN 结构相似,但是重复的模块拥有一个不同的结构。不同于单一神经网络层,这里是有四个,以一种非常特殊的方式进行交互。下面我们具体来看这种结构。
这是图标的含义。
这里我们可以看到一共有四个函数,其中三个sigm代表三个sigmiod函数,还有一个hanh函数。
⨂ \bigotimes ⨂可以理解为乘法操作,若结果为1,则门完全打开,若结果为零,则完全闭合, ⨁ \bigoplus ⨁可以理解为加法,打开闭合原理一样。
LSTM很重要的一点就是引入了门,主要是通过一个 sigmoid 的神经层和一个逐点相乘的操作来实现的,是一种让信息选择式通过的方法 ,即选择性记忆和选择性遗忘。
门的输出是 0到1 之间的实数向量,当门输出为 0 时,任何向量与之相乘都会得到 0 向量,这就相当于什么都不能通过;输出为 1 时,任何向量与之相乘都不会有任何改变,这就相当于什么都可以通过。
实现原理
LSTM核心思想
LSTM的关键在于细胞的状态整个(绿色的图表示的是一个cell),和穿过细胞的那条水平线。
细胞状态类似于传送带。直接在整个链上运行,遇到一个细胞就会与其交互,并不断更新。当然,这一个细胞的输出,下一个细胞的输入都与C密不可分。
若只有上面的那条水平线是没办法实现添加或者删除信息的。这里门就起作用了。
遗忘门层
在我们 LSTM 中的第一步是决定我们会从细胞状态中丢弃什么信息。这个决定通过一个称为忘记门层完成。
该门会读取上一层的输出 h t − 1 h_{t−1} ht−1 和这一层的输入 x t x_t xt,二者融合后经sigmoid函数与 C t − 1 C_{t-1} Ct−1计算,输出一个在 0到 1之间的数值。1 表示“完全保留”,0 表示“完全舍弃”。
它决定了上一时刻的单元状态 C t − 1 C_{t-1} Ct−1有多少保留到当前时刻 C t C_t Ct
输入门层
这一层决定让多少新的信息加入到 cell 状态中来。实现这个需要包括两个步骤:首先,一个sigmoid 层决定哪些信息需要更新;一个 tanh 层生成一个向量,也就是备选的用来更新的内容, C t C_t Ct。
再下一步,我们把这两部分联合起来与第一层输出的C进行交互,这样这个细胞的 C t C_t Ct就更新完了。
这一层决定了当前时刻网络的输入 x t x_t xt 有多少保存到单元状态 C t C_t Ct
输出门层
最终,我们需要确定输出什么值。这个输出将会基于我们的细胞状态,同时也是一个过滤后的版本。首先,我们运行一个 sigmoid 层来确定细胞状态的哪个部分将输出出去。接着,我们把细胞状态 C t C_t Ct通过 tanh 进行处理(得到一个在 -1 到 1 之间的值)并将它和 sigmoid 门的输出相乘,最终我们仅仅会输出我们确定输出的那部分。
这里 h t h_t ht一是作为结果输出,二是作为这一个细胞的输出,传递给下一个细胞。
控制单元状态 C t C_t Ct有多少输出到 LSTM 的当前输出值 h t h_t ht