循环神经网络(RNN)知识入门
原创:方云
一. RNN的发展历史
1986年,Elman等人提出了用于处理序列数据的循环神经网络(Recurrent Neural Networks)。如同卷积神经网络专门用于处理二维数据信息(如图像)的神经网络,循环神经网络是专用于处理序列信息的神经网络。循环网络可以扩展到更长的序列,大多数循环神经网络可以处理可变长度的序列,循环神经网络的诞生解决了传统神经网络在处理序列信息方面的局限性。
1997年,Hochreiter和Schmidhuber提出了**长短时记忆单元(Long Short Term Memory, LSTM)**用于解决标准循环神经网络时间维度的梯度消失问题(vanishing gradient problem)。标准的循环神经网络结构存储的上下文信息的范围有限,限制了RNN的应用。LSTM型RNN用LSTM单元替换标准结构中的神经元节点,LSTM单元使用输入门、输出门和遗忘门控制序列信息的传输,从而实现较大范围的上下文信息的保存与传输。
1998年,Williams和Zipser提出**随时间反向传播(Backpropagation Through Time,BPTT)**的循环神经网络训练算法。BPTT算法的本质是按照时间序列将循环神经网络展开,展开后的网络包含N(时间步长)个隐含单元和一个输出单元,然后采用反向误差传播方式对神经网络的连接权值进行更新。
2001年,Gers和Schmidhuber提出了具有重大意义的LSTM型RNN优化模型,在传统的LSTM单元中加入了窥视孔连接(peephole connections)。具有窥视孔连接的LSTM型RNN模型是循环神经网络最流行的模型之一,窥视孔连接进一步提高了LSTM单元对具有长时间间隔相关性特点的序列信息的处理能力。2005年,Graves成功将LSTM型RNN应用于语音处理;2007年,Hochreiter将LSTM型RNN应用于生物信息学研究。
二. 什么是RNN?
RNN背后的想法是利用顺序信息。 在传统的神经网络中,我们假设所有输入(和输出)彼此独立。 但对于许多任务而言,这是一个非常糟糕的想法。 如果你想预测句子中的下一个单词,那你最好知道它前面有哪些单词。 RNN被称为*循环,*因为它们对序列的每个元素执行相同的任务,输出取决于先前的计算。 考虑RNN的另一种方式是它们有一个“记忆”,它可以捕获到目前为止计算的信息。 理论上,RNN可以利用任意长序列中的信息,但实际上它们仅限于回顾几个步骤(稍后将详细介绍)。 这是典型的RNN的样子:
展开的网络在t 时刻, x t x_t xt是输入层的输入,f是隐藏层激活函数,通常是非线性的,如tanh函数或ReLU函数; s t s_t st是隐藏层的输出,其中 s 0 s_0 s0是计算第一个隐藏层所需要的,通常初始化为全零; g 是输出层激活函数,可以是softmax函数, o t o_t ot 是输出层的输出。关键一点是, s t s_t st的值不仅取决于 x t x_t xt,还取决于 s t − 1 s_{t-1} st−1 。循环神经网络的前向计算过程用公式表示如下:
o t = g ( V ⋅ s t + b 2 ) o_t=g(V \cdot s_t + b_2) ot=g(V⋅st+b2) (1)
s t = f ( U ⋅ x t + W ⋅ s t − 1 + b 1 ) s_t=f(U \cdot x_t + W \cdot s_{t-1} + b_1) st=f(U⋅xt+W⋅st−1+b1) (2)
通过两个公式的循环迭代,有以下推导:
o t = g ( V ⋅ s t + b 2 ) o_t=g(V \cdot s_t + b_2) ot=g(V⋅st+b2)
= g ( V ⋅ f ( U ⋅ x t + W ⋅ s t − 1 + b 1 ) + b 2 ) =g(V \cdot f(U \cdot x_t+W \cdot s_{t-1}+b_1)+b_2) =g(V⋅f(U⋅xt+W⋅st−1+b1)+b2)
= g ( V ⋅ f ( U ⋅ x t + W ⋅ f ( U ⋅ x t − 1 + W ⋅ s t − 2 + b 1 ) + b 1 ) + b 2 ) =g(V \cdot f(U \cdot x_t+W \cdot f(U \cdot x_{t-1}+W \cdot s_{t-2}+b1)+b1)+b2) =g(V⋅f(U⋅xt+W⋅f(U⋅xt−1+W⋅st−2+b1)+b1)+b2)
= g ( V ⋅ f ( U ⋅ x t + W ⋅ f ( U ⋅ x t − 1 + W ⋅ f ( U ⋅ x t − 2 + . . . . ) ) ) + b 2 ) =g(V \cdot f(U \cdot x_t+W \cdot f(U \cdot x_{t-1}+W \cdot f(U \cdot x_{t-2}+....)))+b2) =g(V⋅f(U⋅xt+W⋅f(U⋅xt−1+W⋅f(U⋅xt−2+....)))+b2)
可以看到,当前时刻包含了历史信息,这说明循环神经网络能够记忆历史信息。
这里有几点需要注意:
- 你可以看到隐藏的状态 s t s_t st 作为网络的记忆。 s t s_t st 捕获有关所有先前时间步骤中发生的事件的信息。 步骤输出 o t o_t ot 仅根据时间 t t t的记忆计算。 正如上面简要提到的,它在实践中有点复杂,因为 s t s_t st 通常无法从太多时间步骤中捕获信息。
- 与在每层使用不同参数的传统深度神经网络不同,RNN共享相同的参数(所有步骤的U,V,W)。 这反映了我们在每个步骤执行相同任务的事实,只是使用不同的输入。 这大大减少了我们需要学习的参数总数。
- 上图在每个时间步都有输出,但根据任务,这可能不是必需的。 例如,在预测句子的情绪时,我们可能只关心最终的输出,而不是每个单词之后的情绪。 同样,我们可能不需要在每个时间步骤输入。具体组合有:
- 编程术语中,RNN可以解释为运行具有某些输入和一些内部变量的固定程序。 从这个角度来看,RNN基本上描述了程序。 实际上,众所周知, RNN具有图灵完备性,因为它们可以模拟任意程序(具有适当的权重)。
三. RNN能做什么?
RNN在NLP的许多任务上取得巨大成功。主要的应用领域有:
-
语言建模与生成文本(本文示例重点介绍)
- 给定一系列单词,我们想要预测给定下一单词的概率
- 能够预测下一个单词的副作用是我们得到一个生成模型,它允许我们通过从输出概率中抽样来生成新文本
- 应用模式many to one
-
机器翻译
- 机器翻译类似于语言建模,因为我们的输入是源语言中的一系列单词(例如德语)。 我们希望以目标语言输出一系列单词(例如英语)
- 应用模式many to many
-
语音识别
- 给定来自声波的声学信号的输入序列,我们可以预测一系列语音片段及其概率。
- 应用模式many to many
-
生成图像描述
-
与卷积神经网络一起,RNN已被用作模型的一部分,以生成未标记图像的描述 。
-
应用模式one to many
!
-
四. BPTT公式推导与RNN梯度消失问题
假设我们的时间序列只有三段,假设在t=3时刻,损失函数为 L 3 = 1 2 ( Y 3 − O 3 ) 2 L_{3}=\frac{1}{2}(Y_{3}-O_{3})^{2} L3=21(Y3−O3)2,
则对于一次训练任务的损失函数为 L = ∑ t = 1 T L t L=\sum_{t=1}^{T}{L_{t}} L=∑t=1TLt ,即每一时刻损失值的累加。
使用随机梯度下降法训练RNN其实就是对 W x W_{x} Wx 、 W s W_{s} Ws 、 W o W_{o} Wo 以及 b 1 b_{1} b1、 b 2 b_{2} b2 求偏导,并不断调整它们以使L尽可能达到最小的过程。(注意此处把上文中的UVW参数替换为 W x W_{x} Wx 、 W s W_{s} Ws 、 W o W_{o} Wo,以保持和引用的文章一致。)
现在假设我们我们的时间序列只有三段,t1,t2,t3。
我们只对t3时刻的 W x W_{x} Wx、 W s W_{s} Ws、 W 0 W_{0} W0 求偏导(其他时刻类似):
∂ L 3 ∂ W 0 = ∂ L 3 ∂ O 3 ∂ O 3 ∂ W o \frac{\partial{L_{3}}}{\partial{W_{0}}}=\frac{\partial{L_{3}}}{\partial{O_{3}}}\frac{\partial{O_{3}}}{\partial{W_{o}}} ∂W0∂L3=∂O3∂L3∂Wo∂O3
∂ L 3 ∂ W x = ∂ L 3 ∂ O 3 ∂ O 3 ∂ S 3 ∂ S 3 ∂ W x + ∂ L 3 ∂ O 3 ∂ O 3 ∂ S 3 ∂ S 3 ∂ S 2 ∂ S 2 ∂ W x + ∂ L 3 ∂ O 3 ∂ O 3 ∂ S 3 ∂ S 3 ∂ S 2 ∂ S 2 ∂ S 1 ∂ S 1 ∂ W x \frac{\partial{L_{3}}}{\partial{W_{x}}}=\frac{\partial{L_{3}}}{\partial{O_{3}}}\frac{\partial{O_{3}}}{\partial{S_{3}}}\frac{\partial{S_{3}}}{\partial{W_{x}}}+\frac{\partial{L_{3}}}{\partial{O_{3}}}\frac{\partial{O_{3}}}{\partial{S_{3}}}\frac{\partial{S_{3}}}{\partial{S_{2}}}\frac{\partial{S_{2}}}{\partial{W_{x}}}+\frac{\partial{L_{3}}}{\partial{O_{3}}}\frac{\partial{O_{3}}}{\partial{S_{3}}}\frac{\partial{S_{3}}}{\partial{S_{2}}}\frac{\partial{S_{2}}}{\partial{S_{1}}}\frac{\partial{S_{1}}}{\partial{W_{x}}} ∂Wx∂L3=∂O3∂L3∂S3∂O3∂Wx∂S3+∂O3∂L3∂S3∂O3∂S2∂