循环神经网络以及 LSTM
一、循环神经网络
1.1 RNN 简介概述
- 在前面讲到的 DNN 以及 CNN 等算法都是前向反馈的网络,即给一个输入,得到一个输出,而不考虑输入的序列间的关系,而本节我们要讨论的 RNN(Recurrent Neural Networks) 它不仅依赖于当前的输入,而且还依赖于之前的输入。
- 此外,值得注意的是,之前在 DNN 和 CNN 中,训练样本的输入和输出是确定的。但对于 RNN 所擅长的序列型,它训练样本输入是连续的序列,且序列的长短不一,比如基于时间的序列:一段段连续的语音,一段段连续的手写文字。这些序列比较长,且长度不一,很难像 DNN/CNN 那样通过将输入直接拆分成一个个独立的样本来解决。
- RNN假设我们的样本是基于序列的。比如是从序列索引1到序列索引 τ 的。对于这其中的任意序列索引号 t,它对应的输入是对应的样本序列中的 。而模型在序列索引号 t 位置的隐藏状态 ,则由 和在 t−1 位置的隐藏状态 共同决定。在任意序列索引号 t,我们也有对应的模型预测输出 。通过预测输出 和训练序列真实输出 , 以及损失函数 ,这样可以用DNN类似的方法来训练模型,接着用来预测测试序列中的一些位置的输出。
1.2 RNN 的图示讲解
- RNN 的变种有很多,这里我们就从下面这种较为典型的 RNN 说起,结构如下:
- 图中左边是 RNN 没有按照时间展开的图,而右边是按照时间序列展开的,这里我们重点讨论一下右边的图。它主要描述了在序列索引号 t 附近的 RNN 的模型。其中:
- 代表在序列索引号 t 时训练样本的输入。同样的, 和 代表在序列索引号 t−1 和 t+1 时训练样本的输入。
- 代表在序列索引号t时模型的隐藏状态。 由 和 共同决定。
- 代表在序列索引号t时模型的输出。 只由模型当前的隐藏状态 决定。
- 代表在序列索引号t时模型的损失函数。
- 代表在序列索引号t时训练样本序列的真实输出。
- U,W,V这三个矩阵是我们的模型的线性关系参数,它在整个RNN网络中是共享的,这点和DNN很不相同。 也正因为是共享了,它体现了RNN的模型的“循环反馈”的思想。
1.3 RNN 的前向传播
- 对于任意一个序列索引号t,我们隐藏状态
由
和
得到:
- 其中 σ 为 RNN 的激活函数,一般为 tanh, b为线性关系的偏倚。
- 序列索引号t时模型的输出
的表达式比较简单:
- 在最终在序列索引号t时我们的预测输出为:
- 通常由于RNN是识别类的分类模型,所以上面这个激活函数一般是softmax。
- 通过损失函数 ,比如对数似然损失函数,我们可以量化模型在当前位置的损失,即 和 的差距。
- RNN虽然理论上可以很漂亮的解决序列数据的训练,但是它也像DNN一样有梯度消失时的问题,当序列很长的时候问题尤其严重。因此,上面的RNN模型一般不能直接用于应用领域。在语音识别,手写书别以及机器翻译等NLP领域实际应用比较广泛的是基于RNN模型的一个特例LSTM,下面我们就来讨论一下 LSTM:
二、LSTM ( Long Short-Term Memory)
2.1 LSTM 概述
- 由于RNN也有梯度消失的问题,因此很难处理长序列的数据,而改进后的 LSTM 可以处理常规的梯度消失。
- 如果,我们将上面的 RNN 的结构中的 则 RNN 的模型可以简化成如下图的形式,其实所有 RNN 都具有一种重复神经网络模块(下图中的 A,注意每个单元内的参数是一样,这也是 RNN 的特征)的链式的形式。在标准的 RNN 中,这个重复的模块只有一个非常简单的结构,例如一个 tanh 层。:
- 图中可以很清晰看出在隐藏状态 由 和 得到。得到 后一方面用于当前层的模型损失计算,另一方面用于计算下一层的 。
- 为了避免梯度消失问题,大牛们将索引位置 t 的隐藏结构做了改进。这种特殊的 RNN 便是我们常见的 LSTM,如下:
- 先不考虑这图细节。下面会一步一步地剖析 LSTM。现在,我们先来熟悉一下图中使用的各种元素的图标。
- 在上面的图例中,每一条黑线传输着一整个向量,从一个节点的输出到其他节点的输入。粉色的圈代表 pointwise 的操作,诸如向量的和,而黄色的矩阵就是学习到的神经网络层。合在一起的线表示向量的连接,分开的线表示内容被复制,然后分发到不同的位置。
- 在深入了解 LSTM 的内部结构之前,我们先来了解电路中控制论中的门电路的说法。因为最初 LSTM 的发明便是大佬们参考了控制论中的门电路而发明的。
- 故 LSTM 也是通过精心设计的 “门”的结构来去除或者增加信息的细胞状态的能力。门是一种让信息选择式通过的方法。他们包含一个 sigmoid 神经网络层和一个 pointwise 乘法操作。如下图:
- Sigmoid 层输出 0 到 1 之间的数值,描述每个部分有多少量可以通过。0 代表“不许任何量通过”,1 就指“允许任意量通过”。 LSTM 拥有三个门,来保护和控制细胞状态。
- 从上面的 LSTM 的结构图中可以看出,在每个序列索引位置t时刻向前传播的除了和RNN一样的隐藏状态 ,还多了另一个隐藏状态,如图中上面的长横线。这个隐藏状态我们一般称为细胞状态(Cell State),记为 ,也正是因为它具有记忆能力,这些单元状态有点像是个传送带。它贯穿整个链条,只有一些线性相互作用。这很容易让信息以不变的方式向下流动。如下图;
- LSTM有能力向单元状态中移除或添加信息,通过门结构来管理,包括“遗忘门”,“输出门”,“输入门”。通过门让信息选择性通过,来去除或增加信息到细胞状态. 模块中sigmoid层输出0到1之间的数字,描述了每个成分应该通过门限的程度。0表示“不让任何成分通过”,而1表示“让所有成分通过!”,下面就开始介绍 LSTM 的遗忘门,输入门和细胞状态更新以及输出门。
2.2 LSTM 的内部结构介绍
- 遗忘门
- 遗忘门(forget gate)顾名思义,是控制是否遗忘的,在LSTM中即以一定的概率控制是否遗忘上一层的隐藏细胞状态。
- 上图是遗忘门的展示,首先将上一时刻的输出h(t-1)和这一时刻的输入进x(t)行拼接(concat),然后判断以多大的程度来保留这部分信息(得到概率值)。
- 输入门
- 输入门(input gate)负责处理当前序列位置的输入,它的子结构如下图:
- 上图是输入门结构,i(t)等式表达的是我们以多大概率来更新信息,
表示现在的全部信息。
- LSTM 细胞状态更新
- 在研究LSTM输出门之前,我们要先看看LSTM之细胞状态。前面的遗忘门和输入门的结果都会作用于细胞状态
- 输出门
- 解释一下,为何 LSTM 为何能解决长时依赖问题,以及避免梯度消失。
- 在传统的 RNN 中,当前状态 S(t)= tanh(x(t) * U + W * S(t-1)),当利用梯度下降算法链式求导时是连乘的形式,若其中只要有一个是接近零的,那么总体值就容易为0,导致梯度消失,不能解决长时依赖问题。
- 而 LSTM 更新状态值为:
- 是相加的形式,所以当连乘时,不容易出现状态值逐渐接近 0 的情况。
2.3 LSTM 的变体
- Peephole connections - 中文直译:窥视连接
- 它是一个流形的 LSTM 变体,增加了 “peephole connection”。是说,我们让 门层 也会接受细胞状态的输入。即增加了 peephole 到每个门上,但是许多论文会加入部分的 peephole 而非所有都加。
2. Coupled forget and input gates - 中文直译:耦合遗忘和输入单元
- 原始的RNN的遗忘和新记忆的过程是分开的,Coupled forget and input gates则将两个过程进行耦合,即只遗忘那些有新元素来填充的元素。即通过使用 coupled 忘记和输入门。不同于之前是分开确定什么忘记和需要添加什么新的信息,这里是一同做出决定。我们仅仅会当我们将要输入在当前位置时忘记。我们仅仅输入新的值到那些我们已经忘记旧的信息的那些状态。
3. GRU - Gated Recurrent Unit - 中文直译:门控循环单元
- 还有一种RNN变种干脆将单元状态去除,直接通过输出存储信息,由于这种结构比LSTM更加简单,因此逐渐变得流行起来。它将忘记门和输入门合成了一个单一的 更新门。同样还混合了细胞状态和隐藏状态,和其他一些改动。最终的模型比标准的 LSTM 模型要简单,也是非常流行的变体。
这里只是部分流行的 LSTM 变体。当然还有很多其他的,如Yao, et al. (2015) 提出的 Depth Gated RNN。还有用一些完全不同的观点来解决长期依赖的问题,如Koutnik, et al. (2014) 提出的 Clockwork RNN,如果读者感兴趣,可以自行探讨。
关于代码实践部分,请听下回分解,未完待续 ~ ~ ~ ~ ~ ~
参考文献:(在此致敬这些优秀的博主,分享的知识):
1、 http://www.cnblogs.com/pinard/p/6519110.html
2、 http://colah.github.io/posts/2015-08-Understanding-LSTMs/
3、 https://www.jianshu.com/p/9dc9f41f0b29
4、 https://www.jianshu.com/p/75eeaee7f67d