Bootstrap

RNN的大家族啊~~

1 基本RNN单元及其变体

1.1 RNN模型形象化理解

  现实中很多数据具有时间、空间等方面的序列特征,数据序列的前后部分具有逻辑上的关系,神经网络的研究者针对这类数据设计了RNN(循环神经网络)模型。对于经常使用手机和上网的我们来说,RNN其实无时无刻不存在我们身边,因为RNN已经被用于语音识别,机器翻译,股票预测,智能问答等领域,甚至图像识别的某些方面也会用到RNN,例如图像文本检测识别,以及视频检测。第一次打电话订餐与一位智能机器人对话时还有一点兴奋和紧张,不过默认接通机器人有时很不方便,想接通人工服务也是很有意思,因为目前机器人的应答还不是很智能,只要有一次知道了接通人工服务的“暗号”,下一次只要说这句话就可以触发真人接通服务了,?~
  接下来通俗理解主要来自如何深度理解RNN?——看图就好!,这一部分基本上没有公式,用形象化的表示展现了RNN涉及的几个问题,序列结构,网络形式,梯度消失,对后面公式形式推导的理解有很大的帮助。

1.1.1 序列数据

  RNN 是一种层内神经元之间形成有向环连接的神经网络模型,擅长对序列数据进行建模处理。序列数据有很多种形式,音频是一种自然的序列,如下图,可以将音频频谱图分成块并将其馈入RNN.文本也是一种形式的序列,英语根据语法将单词组合成有意义的句子,说明不同的单词序列得到的信息是不同的

在这里插入图片描述

1.1.2 递归神经网络及用例

  RNN有顺序存储的概念,就像我们的大脑能够自然而然记住已经练习过的序列,RNN也是如此。我们需要知道RNN是如何学习顺序存储的。首先一个传统的神经网络如下左图,也称为前馈神经网络,它包含输入层,隐藏层和输出层。如果在神经网络中添加一个传递先前信息的循环,以便以前的信息能够影响以后的信息,就会变成如下中图。

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

  这基本上就是一个递归神经网络了,RNN让循环机制充当高速公路以允许信息从一个步骤流到下一个步骤。hidden state是先前输入的表示,也会对输出有影响。

机器人翻译用例

  假设我们想要构建一个聊天机器人,该聊天机器人可以根据用户输入的文本对意图进行分类。

在这里插入图片描述

  为了解决这个问题。首先,我们将使用RNN对文本序列进行编码。然后,我们将RNN输出馈送到前馈神经网络中,该网络将对用户输入意图进行分类。
  假设用户输入:what time is it?首先,我们将句子分解为单个单词。RNN按顺序工作,所以我们一次只能输入一个字。

在这里插入图片描述
将句子分成单词序列

  第一步是将“What”输入RNN,RNN编码“what”并产生输出

在这里插入图片描述

  对于下一步,我们提供单词“time”和上一步中的隐藏状态。RNN现在有关于“what”和“time”这两个词的信息。

在这里插入图片描述
  我们重复这个过程,直到最后一步。你可以通过最后一步看到RNN编码了前面步骤中所有单词的信息。
在这里插入图片描述

  由于最终输出是从序列的部分创建的,因此我们应该能够获取最终输出并将其传递给前馈层以对意图进行分类。

在这里插入图片描述

  对于那些喜欢在这里查看代码的人来说,使用python展示了控制流程应该是最好的方式。

在这里插入图片描述

  首先,初始化网络层和初始隐藏状态。隐藏状态的形状和维度将取决于你的递归神经网络的形状和维度。然后循环输入,将单词和隐藏状态传递给RNN。RNN返回输出和修改的隐藏状态,接着就继续循环。最后,将输出传递给前馈层,然后返回预测。整个过程就是这样!进行递归神经网络的正向传递的控制流程是for循环。

1.1.3 梯度消失形象化解释

  我们看到隐藏状态到最后颜色分布很奇怪,这是为了说明RNN短时记忆的问题。

在这里插入图片描述

  短期记忆问题是由臭名昭着的梯度消失问题引起的,这在其他神经网络架构中也很普遍。由于RNN处理很多步骤,因此难以保留先前步骤中的信息。正如你所看到的,在最后的时间步骤中,“what”和“time”这个词的信息几乎不存在。短期记忆和梯度消失是由于反向传播的性质引起的,反向传播是用于训练和优化神经网络的算法。为了理解这是为什么,让我们来看看反向传播对深度前馈神经网络的影响。
  训练神经网络有三个主要步骤,如下左图所示。首先,它进行前向传递并进行预测。然后,它使用损失函数将预测与基础事实进行比较。损失函数输出一个错误值,该错误值是对网络执行得有多糟糕的估计。最后,它使用该误差值计算网络中每个节点的梯度,进行反向传播,调整网络参数。

在这里插入图片描述 在这里插入图片描述

  梯度是用于调整网络内部权重的值,以便能更新整个网络。梯度越大,调整越大,反之亦然,这也就是问题所在。在进行反向传播时,图层中的每个节点都会根据渐变效果计算它在其前面的图层中的渐变。因此,如果在它之前对层的调整很小,那么对当前层的调整将更小。
  这会导致渐变在向后传播时呈指数级收缩。由于梯度极小,内部权重几乎没有调整,因此较早的层无法进行任何学习。这就是消失的梯度问题。
  循环神经网络中这种梯度消失是什么样的呢?可以将循环神经网络中的每个时间步骤视为一个层。为了训练一个递归神经网络,你使用了一种称为通过时间反向传播的方法。这样梯度值在每个时间步长传播时将呈指数级收缩。

在这里插入图片描述

  同样,梯度值将用于在神经网络权重中进行调整,从而允许其学习。小的渐变意味着小的调整。这将导致最前面的层没有优化。由于梯度消失,RNN不会跨时间步骤学习远程依赖性。这意味着在尝试预测用户的意图时,有可能不考虑“what”和“time”这两个词。然后网络就可能作出的猜测是“is it?”。这很模糊,即使是人类也很难辨认这到底是什么意思。因此,无法在较早的时间步骤上学习会导致网络具有短期记忆。

1.2 RNN基本模型

  RNN模型不属于前馈神经网络,主要特点是隐藏层的输出不仅连接到下一层,而且还连接到自身,这种连接到自身的特点构成了数据的循环。通常RNN模型的输入和输出都具有“时序性”。为了表达RNN模型的“循环”特性,可以将其按照输入序列的长度展开。展开后,RNN可以看作由一系列核心模块(RNN单元)形成的二维阵列,在该阵列中,前一时刻与后一时刻的RNN单元相互连接,上一层与下一层的RNN单元相互连接。在RNN单元内部,我们可以设计出各种复杂的计算流程,从而构造出不同的模型,满足不同场景需求。

1.2.1 RNN网络模型

  假设一个普通的全连接网络如图1.1左图所示,输入为 N N N个节点,即 x = ( x 1 , x 2 , ⋯   , x N ) {{x}}=({{x}_{1}},{{x}_{2}},\cdots ,{{x}_{N}}) x=(x1,x2,,xN),隐藏层有 M M M个节点,即 h = ( h 1 , h 2 , ⋯   , h M ) {{h}}=({{h}_{1}},{{h}_{2}},\cdots ,{{h}_{M}}) h=(h1,h2,,hM),输出层有 k k k个节点,那么经过一个隐藏层 h h h之后,得到 h = f ( U x ) h = f(Ux) h=f(Ux),然后经过下一层到达输出层 o o o,即 o = f ( V s ) o = f(Vs) o=f(Vs)。这是一个完整的全连接网络,将节点隐藏就会变成图1.1右图黄色框框中的样子,RNN网络模型多了一个循环隐藏层,用于学习之前序列对输出的影响。
  简单RNN有三层:输入层、循环隐藏层和输出层,如图1.1右图所示。图1.1右图左侧是RNN模型的抽象表示,将时间维度进行了压缩,其中 x x x是输入,将输入单元与隐藏层中的隐藏单元全连接,该连接由权重矩阵 U U U控制,根据输入单元与权重矩阵 U U U得到隐含层的值; W W W则是上个时刻隐含层的值作为这个时刻输入对应的权重; V V V是隐含层到输出层的权重, o o o是输出。
  将时间维度展开以后,更能方便理解,这时输入 x x x、隐层值 s s s和输出 o o o都有了下标 t t t x x x是一系列沿时间 t t t的向量   ​​ { ​​   ⋯ x t − 1 , x t , x t + 1 , ⋯   ​​ } ​​   \text{ }\!\!\{\!\!\text{ }\cdots {{\text{x}}_{t-1}}\text{,}{{\text{x}}_{t}}\text{,}{{\text{x}}_{t+1}}\text{,}\cdots \text{ }\!\!\}\!\!\text{ }  { xt1,xt,xt+1, }  ,其中 x t = ( x 1 , x 2 , ⋯   , x N ) {{x}_{t}}=({{x}_{1}},{{x}_{2}},\cdots ,{{x}_{N}}) xt=(x1,x2,,xN) ,隐藏层有 M M M个隐藏单元 h t = ( h 1 , h 2 , ⋯   , h M ) {{h}_{t}}=({{h}_{1}},{{h}_{2}},\cdots ,{{h}_{M}}) ht=(h1,h2,,hM),这个 t t t表示时刻, t − 1 t-1 t1是上一时刻, t + 1 t+1 t+1则是下一时刻。不同时刻输入对应不同的输出,而且上一时刻的隐含层会影响当前时刻的输出。它们通过网络定义的循环结构沿时间彼此连接。使用较小非零元素的隐藏单元初始化能够提升网络的整体性能和稳定性。

在这里插入图片描述 在这里插入图片描述
图1.1 RNN基本结构

  从公式上来说,原来 h = f ( U x ) h = f(Ux) h=f(Ux),但是现在如果要求当前时刻的输出 h t h_t ht,还要加上上一时刻 h t − 1 h_{t-1} ht1输出的影响 W h t − 1 Wh_{t-1} Wht1,再加上当前时刻偏置 b t b_t bt【偏置在神经网络中的作用】,状态空间的记忆单元就可以被隐藏层定义为:
h t = f ( s t ) ( 1 − 1 ) h_t = f(s_t)\quad\quad (1-1) ht=f(st)(11) s t = U x t + W h t − 1 + b t ( 1 − 2 ) {{s}_{t}}=U{{x}_{t}}+W{{h}_{t-1}}\text{+}{{b}_{t}}\quad\quad (1-2) st=Uxt+Wht1+bt(12)   其中 f f f是激活函数, h t {{h}_{t}} ht是隐含层的输入, W W W为隐藏单元的权重矩阵, b t {{b}_{t}} bt为隐藏单元的偏置向量。
  设输出层的输入为 y t {{y}_{t}} yt,则很容易可以得到输出:
y t = V h t + b o ( 1 − 3 ) {{y}_{t}}=V{h}_{t}\text{+}{{b}_{o}}\quad\quad (1-3) yt=Vht+bo(13) o t = f ( y t ) ( 1 − 4 ) {{o}_{t}}=f({{y}_{t}})\quad\quad (1-4) ot=f(yt)(14)  其中 f f f是激活函数, b o {{b}_{o}} bo是输出层的偏置向量, y t o y_{t}^{o} yto是网络的输出。由于“输入-目标对”是沿时间的序列,因此上述步骤随着时间 t = ( 1 , 2 , ⋯   , T ) t=(1,2,\cdots ,T) t=(1,2,,T)重复。公式(1-1)和(1-3)显示了RNN由特定非线性状态公式构成,该公式沿时间迭代。在每个时间步中,隐藏状态根据输入向量预测输出。RNN的隐藏状态是一组值的集合(除去任何外部因素的影响),该集合总结了与该网络在之前很多时间步上的状态相关的必要信息。这个集合可定义该网络的未来行为,作出准确的输出预测。虽然RNN在每个单元中仅仅使用一个简单的非线性激活函数。但是,如果此类简单结构沿时间步经过良好训练,则它能够建模丰富的动态关系,可以学习到前面很久的序列信息: h t = f ( s t ) = f ( U x t + W f ( U x t − 1 + W h t − 2 + b t − 1 ) + b t ) ⋯ ( 1 − 5 ) h_{t}=f\left(s_{t}\right)=f\left(U x_{t}+W f\left(U x_{t-1}+Wh_{t-2}+b_{t-1}\right)+b_t\right)\cdots \quad\quad (1-5) ht=f(st)=f(Uxt+Wf(Uxt1+Wht2+bt1)+bt)(15)

机器人翻译用例对应公式理解

  上述机器人翻译的例子中,是对“What time is it?”进行翻译,首先,我们将句子分解为单个单词。RNN按顺序工作,所以我们一次只能输入一个字。第一步是将“What”对应的原始特征向量 x 1 x_1 x1(可能是词向量)输入RNN,RNN编码“what”并产生输出,其中隐藏状态为 h 1 = f ( U x 1 + b h 1 ) h_1 = f(Ux_1+bh_1) h1=f(Ux1+bh1),输出为 o 1 = f ( V h 1 + b o 1 ) o_1 = f(Vh_1+bo_1) o1=f(Vh1+bo1).
  对于下一步,我们提供单词“time”对应的原始特征向量 x 2 x_2 x2和上一步中的隐藏状态 h 1 h_1 h1。RNN现在有关于“what”和“time”这两个词的信息,隐藏层状态为 h 2 = f ( U x 2 + W h 1 + b h 2 ) h_2 = f(Ux_2+Wh_1+bh_2) h2=f(Ux2+Wh1+bh2),输出层状态为 o 2 = f ( V h 2 + b o 2 ) o_2 = f(Vh_2+bo_2) o2=f(Vh2+bo2)
  我们重复这个过程,直到最后一步。通过最后一步看到RNN编码了前面步骤中所有单词的信息。

1.2.2 激活函数

  非线性函数比线性函数强大,因为它们可以绘制非线性边界。RNN中一个或多个连续隐藏层中的非线性是学习“输入-目标关系”的关键。
  Sigmoid函数是常用的激活函数,它将真值归一化到[0,1]区间。该激活函数主要用于输出层;Tanh激活函数实际上是缩放的Sigmoid函数;ReLU是另一个常用激活函数,向正输入值开放。
  激活函数的选择主要取决于具体问题和数据本身。
  sigmoid函数仅适合输出区间为[0,1]的网络,且存在两个缺点,第一,sigmoid函数会使神经元快速饱和,导致梯度消失问题;第二,sigmoid的输出不以零为中心会导致不稳定的权重梯度更新。tanh也存在上述缺点。
  与Sigmoid函数和tanh函数相比,ReLU激活有两个优点:第一,ReLU函数导致更加稀疏的梯度,并大幅加快随机梯度下降(SGD)的收敛速度;第二,因其可通过将激活值二值化为零,所以ReLU函数的计算成本低廉;但是,ReLU无法抵抗大型梯度流(gradient flow),随着权重矩阵增大,神经元可能在训练过程中保持未激活状态。

1.2.3 损失函数

  损失函数的挑选因具体问题而异,一般比较流行的损失函数包括预测实数值的欧几里德距离和 Hamming距离,和用于分类问题的交叉熵损失函数。
  设某时刻的损失函数 E t = 1 2 ( y d − y t o ) 2 E_{t}=\frac{1}{2}\left(y_{d}-y_{t}^{o}\right)^{2} Et=21(ydyto)2,通过对比输出 y t o y_{t}^{o} yto和目标 y d y_{d} yd之间的差距而评估了神经网络的性能,则最终损失函数为对每一个时间步上的损失进行求和: E = ∑ t = 1 T E t ( 1 − 6 ) E=\sum_{t=1}^{T} E_{t}\quad\quad (1-6) E=t=1TEt(16)

1.2.4 RNN的训练

  RNN使用BPTT方法训练,BPTT实质上就是朴素的BP算法,采的“链式法则”求解参数梯度,唯一的不同在于每一个time和step上参数共享。从数学的角度来讲,BP算法是一个单变量求导过程,而BPTT算法是一个复合函数求导过程。BPTT通过三个主要步骤进行求解:

  1. 得到误差项
       前向计算每个神经元的输出值,模型架构中给出了前向传播的表达式,根据网络前向传播得到时刻 t t t的整个传输过程为 o t = f ( V f ( U x t + W h t − 1 + b t ) + b 0 ) o_t = f(V f(Ux_t+Wh_{t-1}+b_t)+b_0) ot=f(Vf(Uxt+Wht1+bt)+b0),其中 y t = V f ( U x t + W h t − 1 + b t ) + b 0 y_t = V f(Ux_t+Wh_{t-1}+b_t)+b_0 yt=Vf(Uxt+Wht1+bt)+b0, h t = f ( U x t + W h t − 1 + b t ) h_t = f(Ux_t+Wh_{t-1}+b_t) ht=f(Uxt+Wht1+bt)
      反向计算每个神经元的误差项值,它是误差函数 E E E对神经元 j j j的加权输入的偏导数;损失函数为 E E E,在 t t t时刻,根据误差反向传播和公式(1-3)(1-4),可以得到误差项: ∂ E t ∂ y t = ∂ E t ∂ o t ∂ o t ∂ y t = E ′ ( o t ) f ′ ( y t ) ( 1 − 7 ) \frac{\partial E_{t}}{\partial y_{t}}=\frac{\partial E_{t}}{\partial o_{t}} \frac{\partial o_{t}}{\partial y_{t}}=E^{\prime}\left(o_{t}\right) f^{\prime}\left(y_{t}\right)\quad\quad (1-7) ytEt=otEtytot=E(ot)f(yt)(17)
  2. 计算每个权重的梯度
      对于隐藏神经元到输出的权重矩阵 V V V ,每个时刻 t t t的误差只与当前时刻的误差相关,类似于普通神经网络中的误差反向传播,根据(1-3) y t y_t yt V V V的关系,得到: ∂ E t ∂ V = ∂ E t ∂ y t ∂ y t ∂ V = ∂ E t ∂ y t h t ( 1 − 8 ) \frac{\partial E_{t}}{\partial V}=\frac{\partial E_{t}}{\partial y_{t}} \frac{\partial y_{t}}{\partial V}=\frac{\partial E_{t}}{\partial y_{t}} h_{t}\quad\quad(1-8) VEt=ytEtVyt=ytEtht(18)  隐藏层与输入层之间的权重矩阵 W W W则涉及到序列数据之间的联系,具体传播过程展开如下图所示,某个样本的误差需要将所有时刻的误差加起来,在时刻 t t t W W W求偏导为:在这里插入图片描述 ∂ E t ∂ W = ∂ E t ∂ y t ∂ y t ∂ h t ∂ h t ∂ W ( 1 − 9 ) \frac{\partial E_{t}}{\partial W}=\frac{\partial E_{t}}{\partial y_{t}} \frac{\partial y_{t}}{\partial h_{t}} \frac{\partial h_{t}}{\partial W}\quad\quad(1-9) WEt=ytEthtytWht(19)  由于 h t = f ( U x t + W h t − 1 + b t ) = f ( U x t + W ( f ( U x t − 1 + W h t − 2 + b t − 2 ) ) + b t ) h_t = f(Ux_t+Wh_{t-1}+b_t) = f(Ux_t+W(f(Ux_{t-1}+Wh_{t-2}+b_{t-2}))+b_t) ht=f(Uxt+Wht1+bt)=f(Uxt+W(f(Uxt1+Wht2+bt2))+bt)一直依赖上一时刻,所以某个样本的误差总是所有时刻误差的累加和,不断对每个时刻求偏导,误差一直反向传播到 t t t为0的时刻,即: ∂ E ∂ W = ∑ t ∂ E t ∂ W = ∑ k = 1 t ∂ E t ∂ y t ∂ y t ∂ h t ∂ h t ∂ h k ∂ h k ∂ W = ∑ k = 1 t ∂ E t ∂ y t ∂ y t ∂ h t ( ∏ j = k + 1 t ∂ h j ∂ h j − 1 ) ∂ h k ∂ W ( 1 − 10 ) \frac{\partial E}{\partial W}=\sum_{t} \frac{\partial E_{t}}{\partial W}=\sum_{k=1}^{t} \frac{\partial E_{t}}{\partial y_{t}} \frac{\partial y_{t}}{\partial h_{t}}\frac{\partial h_t}{\partial h_k} \frac{\partial h_{k}}{\partial W}=\sum_{k=1}^{t} \frac{\partial E_{t}}{\partial y_{t}} \frac{\partial y_{t}}{\partial h_{t}}\left(\prod_{j=k+1}^{t} \frac{\partial h_{j}}{\partial h_{j-1}}\right) \frac{\partial h_{k}}{\partial W}\quad\quad(1-10) WE=tWEt=k=1tytEthtythkhtWhk=k=1tytEthtytj=k+1thj1hjWhk(110)  其中 ∂ s t ∂ s k \frac{\partial s_{t}}{\partial s_{k}} skst根据链式法则是会一直乘到 k k k时刻, k k k可以是1,2,……
      输入与隐藏层之间的权重矩阵为 U U U,对 U U U进行求导: ∂ E t ∂ U = ∂ E t ∂ h t ∂ h t ∂ U = ∂ E t ∂ h t x t ( 1 − 12 ) \frac{\partial E_{t}}{\partial U}=\frac{\partial E_{t}}{\partial h_{t}} \frac{\partial h_{t}}{\partial U}=\frac{\partial E_{t}}{\partial h_{t}} x_{t}\quad\quad(1-12) UEt=htEtUht=htEtxt(112)
  3. 迭代更新
       最后针对每个权重参数的梯度通过随机梯度下降算法,对参数进行更新。
1.2.5 梯度爆炸和梯度消失

   通过上述公式可以看到在对权重矩阵W求导的时候,因为要追溯到之前时刻的状态,所以会产生连乘操作,当W的值很小时,连乘可能会导致梯度消失,当W很大时,连乘会造成梯度爆炸。
解决方法:

  1. 对于RNN,可以通过梯度截断,避免梯度爆炸
  2. 可以通过添加正则项,避免梯度爆炸
  3. 使用LSTM等自循环和门控制机制,避免梯度消失
  4. 优化激活函数,譬如将sigmold改为relu,避免梯度消失

1.3 LSTM单元

1.3.1 LSTM网络模型结构

   LSTM即Long Short Memory Network,长短时记忆网络,是RNN网络的一种变体,可以说它克服了RNN无法很好处理远距离依赖问题。
   LSTM通过累加的形式改变了使用链式求导法则会导致梯度变为连乘的问题,从而增加网络记忆长度。但是其重复网络模块的结构则复杂很多,它实现了三个门计算,即遗忘门、输入门和输出门。实际上简单来说可以看作LSTM增加了一个状态 c c c来保持长期的状态,成为单元状态。

在这里插入图片描述
图 1-2

   这时就有一个关键问题,如何控制长期状态 c c c,实现的方法就是刚刚提到的LSTM实现了三个门做控制开关,第一个是遗忘门控开关,控制继续保持长期状态 c c c,因此遗忘门负责决定保留多少上一时刻的单元状态到当前时刻的单元状态。第二个门是输入门开关,负责控制把当前时刻的状态输入到长期状态 c c c,因此输入门负责决定保留多少当前时刻的输入到当前时刻的单元状态。第三个门是输出门,负责控制是否把长期状态 c c c作为当前LSTM的输出,所以输出门负责决定当前时刻的单元状态有多少输出。
  那么门是什么呢,我认为就与神经元的激活函数道理是一样的,看后面公式我们可以知道,gate就是一个全连接层, g ( x ) = σ ( W x + b ) g(x) = \sigma(Wx+b) g(x)=σ(Wx+b),输入是一个向量,输出经过sigmoid处理后是0-1之间的实数向量,1 表示全部保留,0表示全部忘记。

在这里插入图片描述
图1-3
在这里插入图片描述
图1.4 LSTM 基本结构1

   每个LSTM包含了三个输入,即上一时刻的单元状态 c t − 1 c_{t-1} ct1、上一时刻LSTM的输出 h t − 1 h_{t-1} ht1和当前时刻输入 x t x_t xt

在这里插入图片描述 在这里插入图片描述
图 1.5 LSTM基本结构2

遗忘门:
   用来计算上一时刻输出 h t − 1 h_{t-1} ht1和这一时刻输入 x t x_t xt中哪些信息需要忘记。于是有 f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) = σ ( W f h h t − 1 + W f x x t + b f ) = σ ( n e t f , t ) ( 1 − 13 ) f_{t}=\sigma\left(W_{f} \cdot\left[h_{t-1}, x_{t}\right]+b_{f}\right) = \sigma(W_{f h} \mathbf{h}_{t-1}+W_{f x} \mathbf{x}_{t}+\mathbf{b}_{f})=\sigma(\mathbf{n e t}_{f, t})\quad\quad(1-13) ft=σ(Wf[ht1,xt]+bf)=σ(Wfhht1+Wfxxt+bf)=σ(netf,t)(113)  其中,中括号表示两个向量相连合并, W f W_f Wf表示遗忘门的权重矩阵, σ \sigma σ为sigmoid函数, b f b_f bf为遗忘门的偏置项。设输入层的维度为 d x d_x dx,隐藏层维度为 d h d_h dh,上一时刻的单元状态 c t − 1 c_{t-1} ct1维度为 d c d_c dc,则 W f W_f Wf维度为 d e × ( d h + d x ) d_{e} \times\left(d_{h}+d_{x}\right) de×(dh+dx) n e t f , t \mathbf{n e t}_{f, t} netf,t表示遗忘门的输入。
输入门:
  用来计算哪些信息保存都状态单元中,看图1.5的划分可以看到,输入门分成两部分,第一部分可以看作当前输入有多少保存到单元状态之中,表示为:

i t = σ ( W i ⋅ [ h t − 1 , x t ] + b i ) = σ ( W i h h t − 1 + W i x x t + b i ) = σ ( n e t i , t ) ( 1 − 14 ) {{i}_{t}}=\sigma ({{W}_{i}}\cdot [{{h}_{t-1}},{{x}_{t}}]+{{b}_{i}})= \sigma(W_{i h} \mathbf{h}_{t-1}+W_{i x} \mathbf{x}_{t}+\mathbf{b}_{i})=\sigma(\mathbf{n e t}_{i, t})\quad\quad(1-14) it=σ(Wi[ht1,xt]+bi)=σ(Wihht1+Wixxt+bi)=σ(neti,t)(114)

  另一部分可以看作当前输入产生多少新信息添加到单元状态之中,表示为:

c ‾ t = tanh ⁡ ( W c ‾ ⋅ [ h t − 1 , x t ] + b c ‾ ) = σ ( W c ‾ h h t − 1 + W c ‾ x x t + b c ‾ ) = σ ( n e t c ‾ , t ) ( 1 − 15 ) \overline{c}_{t}=\tanh \left(W_{\overline{c}} \cdot\left[h_{t-1}, x_{t}\right]+b_{\overline{c}}\right)= \sigma(W_{\overline{c} h} \mathbf{h}_{t-1}+W_{\overline{c} x} \mathbf{x}_{t}+\mathbf{b}_{\overline{c}})=\sigma(\mathbf{n e t}_{\overline{c}, t})\quad\quad(1-15) ct=tanh(Wc[ht1,xt]+bc)=σ(Wchht1+Wcxxt+bc)=σ(netc,t)(115)

  结合这两部分来创建一个新记忆。当前时刻的单元状态由遗忘门输出和上一时刻状态的积加上输入门两部分的积,即 c t = f t ∗ c t − 1 + i t ∗ c ‾ t ( 1 − 16 ) c_{t}=f_{t}^{*} c_{t-1}+i_{t} * \overline{c}_{t}\quad\quad(1-16) ct=ftct1+itct(116)输出门:
  通过sigmoid函数计算需要输出哪些信息,再乘以当前单元状态通过tanh函数的值,得到输出。

o t = σ ( W o ⋅ [ h t − 1 , x t ] + b o ) = σ ( W o h h t − 1 + W o x x t + b o ) = σ ( n e t o , t ) ( 1 − 17 ) o_{t}=\sigma\left(W_{o} \cdot\left[h_{t-1}, x_{t}\right]+b_{o}\right)= \sigma(W_{o h} \mathbf{h}_{t-1}+W_{o x} \mathbf{x}_{t}+\mathbf{b}_{o})=\sigma(\mathbf{n e t}_{o, t})\quad\quad(1-17) ot=σ(Wo[ht1,xt]+bo)=σ(Wohht1+Woxxt+bo)=σ(neto,t)(117) h t = o t ∗ tanh ⁡ ( c t ) ( 1 − 18 ) h_{t}=o_{t}{*} \tanh \left(c_{t}\right)\quad\quad(1-18) ht=ottanh(ct)(118)

  最后,输出层的输入 y t i = W y i h t y_{t}^{i}={{W}_{yi}}{{h}_{t}} yti=Wyiht ,输出为 y t o = σ ( y t i ) y_{t}^{o}=\sigma (y_{t}^{i}) yto=σ(yti)
  设某时刻的损失函数为 E t = 1 2 ( y d − y t 0 ) 2 E_{t}=\frac{1}{2}\left(y_{d}-y_{t}^{0}\right)^{2} Et=21(ydyt0)2,则某样本的损失为:

E = ∑ t = 1 T E t ( 1 − 20 ) E=\sum_{t=1}^{T} E_{t}\quad\quad(1-20) E=t=1TEt(120)

1.3.2 LSTM训练

  LSTM使用BPTT算法进行训练,与普通RNN训练方法相同。

  1. 前向计算每个神经元的输出值,一共有五个量需要计算,即 f t , i i , c ‾ t , o t , h t , c t f_t,i_i,\overline{c}_t,o_t,h_t,c_t ft,ii,ct,ot,ht,ct,计算方法在模型结构中进行了推导。
  2. 反向计算每个神经元的误差值,与RNN一样,LSTM误差项发想传播也是包括两个方向,一个是沿时间的反向传播,即从当前时刻 t t t开始,计算每个时刻的误差项,一个是将误差项向上一层传播

  从LSTM的前向传播可以看到,需要学习很多权重参数,同时也可以看到LSTM的输出 h t h_t ht有四个输入分量加权影响,即三个门相关的 f t , i t , c ˉ t , o t {{f}_{t}},{{i}_{t}},{{\bar{c}}_{t}},{{o}_{t}} ft,it,cˉt,ot ,而且其中权重 W W W都是拼接的,所以在学习时需要分割出来,即:

W f = W f x + W f h W i = W i x + W i h W c ‾ = W c ‾ x + W c ‾ h W o = W o x + W o h ( 1 − 19 ) \begin{aligned} W_{f} &=W_{f x}+W_{f h} \\ W_{i} &=W_{i x}+W_{i h} \\ W_{\overline{c}} &=W_{\overline{c} x}+W_{\overline{c} h} \\ W_{o} &=W_{o x}+W_{o h} \end{aligned} \quad\quad(1-19) WfWiWcWo=Wfx+Wfh=Wix+Wih=Wcx+Wch=Wox+Woh(119)

  这时可以明确要学习的参数有,分割出来的八个权重矩阵以及 f t , i t , c ˉ t , o t {{f}_{t}},{{i}_{t}},{{\bar{c}}_{t}},{{o}_{t}} ft,it,cˉt,ot对应的偏置向量 b f , b i , b c ‾ , b o b_f,b_i,b_{\overline {c}},b_o bf,bi,bc,bo,以及最后输出层的权重矩阵 W y i W_{yi} Wyi,所以要根据输出得到与他们相关的误差项。

将误差沿时间反向传递
  设当前时刻 t t t的误差项 δ t = ∂ E ∂ h t \delta_{t}=\frac{\partial E}{\partial h_{t}} δt=htE,那么误差沿时间反向传递就需要计算 t − 1 t-1 t1时刻的误差项 δ t − 1 \delta_{t-1} δt1,则

δ t − 1 = ∂ E ∂ h t − 1 = ∂ E ∂ h t ∂ h t ∂ h t − 1 = δ t ∂ h t ∂ h t − 1 ( 1 − 20 ) \delta_{t-1}=\frac{\partial E}{\partial h_{t-1}}=\frac{\partial E}{\partial h_{t}} \frac{\partial h_{t}}{\partial h_{t-1}}=\delta_{t} \frac{\partial h_{t}}{\partial h_{t-1}}\quad\quad(1-20) δt1=ht1E=htEht1ht=δtht1ht(120)

   ∂ h t ∂ h t − 1 \frac{\partial h_{t}}{\partial h_{t-1}} ht1ht是一个Jacobian矩阵。如果隐藏层h的维度是N的话,那么它就是一个 N × N N\times N N×N矩阵。LSTM的数输出 h t h_t ht可以看成是一个复合函数, f [ f t ( h t − 1 ) , i t ( h t − 1 ) , c ‾ t ( h t − 1 ) , o t ( h − 1 ) ] f\left[f_{t}\left(h_{t-1}\right), i_{t}\left(h_{t-1}\right), \overline{c}_{t}\left(h_{t-1}\right), o_{t}\left(h_{-1}\right)\right] f[ft(ht1),it(ht1),ct(ht1),ot(h1)],因为 f t , i t , c ˉ t , o t {{f}_{t}},{{i}_{t}},{{\bar{c}}_{t}},{{o}_{t}} ft,it,cˉt,ot都是 h t − 1 h_{t-1} ht1的函数, 由全导数公式

δ t ∂ h t ∂ h t − 1 = δ t ∂ h t ∂ c t ∂ c t ∂ f t ∂ f t ∂ n e t f t ∂ n e t f t ∂ h t − 1 + δ t ∂ h t ∂ c t ∂ c t ∂ i t ∂ i t ∂ n e t i t ∂ n e t i t ∂ h t − 1 + δ t ∂ h t ∂ c t ∂ c t ∂ c ‾ t ∂ c ‾ t ∂ n e t c ‾ t ∂ n e t c ‾ t ∂ h t − 1 + δ t ∂ h t ∂ o t ∂ o t ∂ n e t o t ∂ n e t o t ∂ h t − 1 ( 1 − 21 ) \delta_{t} \frac{\partial h_{t}}{\partial h_{t-1}}=\delta_{t} \frac{\partial h_{t}}{\partial c_{t}} \frac{\partial c_{t}}{\partial f_{t}} \frac{\partial f_{t}}{\partial n e t_{f t}} \frac{\partial n e t_{f t}}{\partial h_{t-1}}+\delta_{t} \frac{\partial h_{t}}{\partial c_{t}} \frac{\partial c_{t}}{\partial i_{t}} \frac{\partial i_{t}}{\partial n e t_{i t}} \frac{\partial n e t_{it}}{\partial h_{t-1}}\\ \quad\quad\quad\quad\quad\quad\quad\quad +\delta_{t} \frac{\partial h_{t}}{\partial c_{t}} \frac{\partial c_{t}}{\partial \overline{c}_{t}} \frac{\partial \overline{c}_{t}}{\partial n e t_{ \overline{c} t}} \frac{\partial n e t_{ \overline{c}t}}{\partial h_{t-1}}+\delta_{t} \frac{\partial h_{t}}{\partial o_{t}} \frac{\partial o_{t}}{\partial n e t_{o t}} \frac{\partial n e t_{ot}}{\partial h_{t-1}}\quad\quad(1-21) δtht1ht=δtcthtftctnetftftht1netft+δtcthtitctnetititht1netit+δtcthtctctnetctctht1netct+δtothtnetototht1netot(121)

  将上述所有偏导都求出来【注:函数: f ( z ) = t a n h ( z ) f(z) = tanh(z) f(z)=tanh(z) 导数: f ( z ) ′ = 1 − ( f ( z ) ) 2 f(z)' = 1 − (f(z))^2 f(z)=1(f(z))2】:

∂ h t ∂ o t = t a n h ( c t ) ∂ h t ∂ c t = o t ∗ ( 1 − tanh ⁡ ( c t ) 2 ) ∂ c t ∂ f t = c t − 1 ∂ f t ∂ n e t f , t = f t ∗ ( 1 − f t ) ∂ n e t f , t ∂ h t − 1 = W f h ∂ c t ∂ i t = c ‾ t ∂ i t ∂ n e t i , t = i t ∗ ( 1 − i t ) ∂ n e t i , t ∂ h t − 1 = W i h ∂ c t ∂ c ‾ t = i t ∂ c ‾ t ∂ n e t c ‾ , t = ( 1 − c ‾ t 2 ) ∂ n e t c ‾ , t ∂ h t − 1 = W c ‾ h ∂ o t ∂ n e t o t = o t ∗ ( 1 − o t ) ∂ n e t o , t ∂ h t − 1 = W o h ( 1 − 22 ) \begin{array}{l} {\frac{\partial \mathbf{h}_{\mathrm{t}}}{\partial \mathbf{o}_{t}} = tanh(c_t)\quad\quad \frac{\partial h_{t}}{\partial c_{t}}=o_{t} *\left(1-\tanh \left(c_{t}\right)^{2}\right)} \\ { \frac{\partial c_{t}}{\partial f_{t}}=c_{t-1} \quad\quad \frac{\partial f_{t}}{\partial n e t_{f, t}}=f_{t}{*}\left(1-f_{t}\right) \quad\quad \frac{\partial n e t_{f, t}}{\partial h_{t-1}}=W_{f h} }\\ { \frac{\partial c_{t}}{\partial i_{t}}=\overline{c}_{t} \quad\quad \frac{\partial i_{t}}{\partial n e t_{i, t}}=i_{t}{*}\left(1-i_{t}\right) \quad\quad \frac{\partial n e t_{i, t}}{\partial h_{t-1}}=W_{i h}}\\ { \frac{\partial c_{t}}{\partial \overline{c}_{t}}=i_{t} \quad\quad \frac{\partial \overline{c}_{t}}{\partial n e t_{\overline{c}, t}}=(1-\overline{c}_t^2) \quad\quad \frac{\partial n e t_{\overline{c}, t}}{\partial h_{t-1}}=W_{\overline{c} h}}\\ { \frac{\partial o_{t}}{\partial net_{o t}}=o_{t}{*}\left(1-o_{t}\right) \quad\quad \frac{\partial n e t_{o, t}}{\partial h_{t-1}}=W_{o h}}\end{array} \quad\quad(1-22) otht=tanh(ct)ctht=ot(1tanh(ct)2)ftct=ct1netf,tft=ft(1ft)ht1netf,t=Wfhitct=ctneti,tit=it(1it)ht1neti,t=Wihctct=itnetc,tct=(1ct2)ht1netc,t=Wchnetotot=ot(1ot)ht1neto,t=Woh(122)

  再设:

δ f , t = ∂ E ∂ n e t f , t , δ i , t = ∂ E ∂ n e t i , t , δ c ‾ , t = ∂ E ∂ n e t c ‾ , t , δ o , t = ∂ E ∂ n e t o , t \delta_{f, t}=\frac{\partial E}{\partial n e t_{f, t}} ,\quad \delta_{i, t}=\frac{\partial E}{\partial n e t_{i, t}} ,\quad \delta_{\overline{c}, t}=\frac{\partial E}{\partial n e t_{\overline{c}, t}} ,\quad \delta_{o, t}=\frac{\partial E}{\partial n e t_{o, t}} δf,t=netf,tE,δi,t=neti,tE,δc,t=netc,tE,δo,t=neto,tE

  根据求出来的所有偏导可以知道 δ o , t = δ t × tanh ⁡ ( c t ) × o t × ( 1 − o t ) δ f , t = δ t × o t × ( 1 − tanh ⁡ ( c t ) 2 ) × c t − 1 × f t × ( 1 − f t ) δ i , t = δ t × o t × ( 1 − tanh ⁡ ( c t ) 2 ) × c ‾ t × i t × ( 1 − i t ) δ c ‾ , t = δ t × o t × ( 1 − tanh ⁡ ( c t ) 2 ) × i t × ( 1 − c ‾ t 2 ) ( 1 − 23 ) \begin{array}{l} {\delta_{o, t}=\delta_{t} \times \tanh \left(\mathbf{c}_{t}\right) \times \mathbf{o}_{t} \times\left(1-\mathbf{o}_{t}\right)} \\ {\delta_{f, t}=\delta_{t} \times \mathbf{o}_{t} \times \left(1-\tanh \left(\mathbf{c}_{t}\right)^{2}\right) \times \mathbf{c}_{t-1} \times \mathbf{f}_{t} \times \left(1-\mathbf{f}_{t}\right)} \\{ \delta_{i, t}=\delta_{t} \times \mathbf{o}_{t} \times \left(1-\tanh \left(\mathbf{c}_{t}\right)^{2}\right) \times \overline{c}_t \times \mathbf{i}_{t} \times \left(1-\mathbf{i}_{t}\right)} \\{ \delta_{\overline{c}, t}=\delta_{t} \times \mathbf{o}_{t} \times \left(1-\tanh \left(\mathbf{c}_{t}\right)^{2}\right) \times \mathbf{i}_{t} \times\left(1-\overline{c}_t^{2}\right)}\end{array} \quad\quad(1-23) δo,t=δt×tanh(ct)×ot×(1ot)δf,t=δt×ot×(1tanh(ct)2)×ct1×ft×(1ft)δi,t=δt×ot×(1tanh(ct)2)×ct×it×(1it)δc,t=δt×ot×(1tanh(ct)2)×it×(1ct2)(123)

  将式(1-22)(1-23)带入(1-21)得到:
δ t − 1 = δ t ∂ h t ∂ h t − 1 = δ o , t ∂ n e t o , t ∂ h t − 1 + δ f , t ∂ n e t f , t ∂ h t − 1 + δ i , t ∂ n e t i , t ∂ h t − 1 + δ c ‾ , t ∂ n e t c ‾ , t ∂ h t − 1 = δ f , t W f h + δ i , t W i h + δ c ‾ , t W c ‾ h + δ o , t W o h ( 1 − 24 ) \delta_{t-1}=\delta_{t} \frac{\partial h_{t}}{\partial h_{t-1}}\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\\= \delta_{o, t}\frac{\partial \mathbf{n} e t_{o, t}}{\partial \mathbf{h}_{\mathrm{t}-1}}+\delta_{f, t}\frac{\partial \mathbf{n} e t_{f, t}}{\partial \mathbf{h}_{\mathrm{t}-1}}+\delta_{i, t}\frac{\partial \mathbf{n} e t_{i, t}}{\partial \mathbf{h}_{\mathrm{t}-1}}+\delta_{\overline{c}, t}\frac{\partial \mathbf{n} e t_{\overline{c}, t}}{\partial \mathbf{h}_{\mathrm{t}-1}}\\ =\delta_{f, t} W_{f h}+\delta_{i, t} W_{i h}+\delta_{\overline{c}, t} W_{\overline{c} h}+\delta_{o, t} W_{o h}\quad\quad(1-24) δt1=δtht1ht=δo,tht1neto,t+δf,tht1netf,t+δi,tht1neti,t+δc,tht1netc,t=δf,tWfh+δi,tWih+δc,tWch+δo,tWoh(124)

  式(1-23)(1-24)就是将误差沿时间反向传播一个时刻的公式。有了它,我们可以写出将误差项向前传递到任意 k k k时刻的公式:

δ k = ∏ j = k t − 1 δ o , j W o h + δ f , j W f h + δ i , j W i h + δ c ‾ , j W c ‾ h ( 1 − 25 ) \delta_{k}=\prod_{j=k}^{t-1} \delta_{o, j}W_{o h}+\delta_{f, j}W_{f h}+\delta_{i, j} W_{i h}+\delta_{\overline{c}, j}W_{\overline{c} h}\quad\quad(1-25) δk=j=kt1δo,jWoh+δf,jWfh+δi,jWih+δc,jWch(125)

将误差项传递到上一层
  我们假设当前为第 l l l层,定义 l − 1 l-1 l1层的误差项是误差函数对 l − 1 l-1 l1层加权输入的导数,即:

δ t l − 1 = ∂ E net ⁡ t l − 1 ( 1 − 26 ) \delta_{t}^{l-1} = \frac{\partial E}{\operatorname{net}_{t}^{l-1}}\quad\quad(1-26) δtl1=nettl1E(126)
  本次LSTM的输入 x t x_t xt由下面的公式计算:

x t l = f l − 1 ( n e t t l − 1 ) ( 1 − 27 ) \mathbf{x}_{t}^{l}=f^{l-1}\left(\mathbf{n e t}_{t}^{l-1}\right)\quad\quad(1-27) xtl=fl1(nettl1)(127)

  其中 f l − 1 f^{l-1} fl1为第 l − 1 l-1 l1层的激活函数。因为 n e t f , t l , net_{f, t}^{l}, netf,tl, net i , t l , _{i, t}^{l}, i,tl, net c ~ , t l , _{\tilde{c}, t}^{l}, c~,tl, net o , t l _{o, t}^{l} o,tl都是 x t x_t xt的函数, x t x_t xt又是 n e t t l − 1 net_t^{l-1} nettl1的函数,因此,要求出E对 n e t t l − 1 net_t^{l-1} nettl1的导数,就需要使用全导数公式:
∂ E ∂ n e t t l − 1 = ∂ E ∂ n e t f , t 1 ∂ n e t f , t 1 ∂ x t l ∂ x t l ∂ n e t t 1 − 1 + ∂ E ∂ n e t i , t 1 ∂ n e t i , t 1 ∂ x t l ∂ x t l ∂ n e t t 1 − 1 + ∂ E ∂ n e t c ‾ , t 1 ∂ n e t c ‾ , t 1 ∂ x t l ∂ x t l ∂ n e t t 1 − 1 + ∂ E ∂ n e t o , t 1 ∂ n e t o , t 1 ∂ x t l ∂ x t l ∂ n e t t 1 − 1 = δ f , t W f h × f ′ ( n e t t l − 1 ) + δ i , t W i h × f ′ ( n e t t l − 1 ) + δ c ‾ , t W c ‾ h × f ′ ( n e t t l − 1 ) + δ o , t W o h × f ′ ( n e t t l − 1 ) = ( δ f , t W f h + δ i , t W i h + δ c ‾ , t W c ‾ h + δ o , t W o h ) × f ′ ( n e t t l − 1 ) ( 1 − 28 ) \frac{\partial E}{\partial \mathbf{n e t}_{t}^{l-1}}= \frac{\partial E}{\partial \mathbf{n e t}_{\mathrm{f}, \mathrm{t}}^{1}} \frac{\partial \mathbf{n e t}_{\mathrm{f}, \mathrm{t}}^{1}}{\partial \mathbf{x}_{t}^{l}} \frac{\partial \mathbf{x}_{t}^{l}}{\partial \mathbf{n e t}_{t}^{1-1}}+ \frac{\partial E}{\partial \mathbf{n e t}_{\mathrm{i}, \mathrm{t}}^{1}} \frac{\partial \mathbf{n e t}_{\mathrm{i}, \mathrm{t}}^{1}}{\partial \mathbf{x}_{t}^{l}} \frac{\partial \mathbf{x}_{t}^{l}}{\partial \mathbf{n e t}_{\mathrm{t}}^{1-1}}\\\quad\quad\quad\quad\quad\quad+ \frac{\partial E}{\partial \mathbf{n e t}_{\mathrm{\overline{c}}, \mathrm{t}}^{1}} \frac{\partial \mathbf{n e t}_{\mathrm{\overline{c}}, \mathrm{t}}^{1}}{\partial \mathbf{x}_{t}^{l}} \frac{\partial \mathbf{x}_{t}^{l}}{\partial \mathbf{n e t}_{\mathrm{t}}^{1-1}} +\frac{\partial E}{\partial \mathbf{n e t}_{\mathrm{o}, \mathrm{t}}^{1}} \frac{\partial \mathbf{n e t}_{\mathrm{o}, \mathrm{t}}^{1}}{\partial \mathbf{x}_{t}^{l}} \frac{\partial \mathbf{x}_{t}^{l}}{\partial \mathbf{n e t}_{\mathrm{t}}^{1-1}}\\ =\delta_{f, t} W_{f h}\times f^{\prime}\left(\mathbf{n} e t_{t}^{l-1}\right)+\delta_{i, t} W_{i h}\times f^{\prime}\left(\mathbf{n} e t_{t}^{l-1}\right)\\ \quad\quad\quad\quad+\delta_{\overline{c}, t} W_{\overline{c} h}\times f^{\prime}\left(\mathbf{n} e t_{t}^{l-1}\right)+\delta_{o, t} W_{o h}\times f^{\prime}\left(\mathbf{n} e t_{t}^{l-1}\right)\\ \quad\quad\quad\quad= (\delta_{f, t} W_{f h}+\delta_{i, t} W_{i h}+\delta_{\overline{c}, t} W_{\overline{c} h}+\delta_{o, t} W_{o h})\times f^{\prime}\left(\mathbf{n} e t_{t}^{l-1}\right)\quad\quad(1-28) nettl1E=netf,t1Extlnetf,t1nett11xtl+neti,t1Extlneti,t1nett11xtl+netc,t1Extlnetc,t1nett11xtl+neto,t1Extlneto,t1nett11xtl=δf,tWfh×f(nettl1)+δi,tWih×f(nettl1)+δc,tWch×f(nettl1)+δo,tWoh×f(nettl1)=(δf,tWfh+δi,tWih+δc,tWch+δo,tWoh)×f(nettl1)(128)

要求所有参数和偏置的误差项,我们首先根据式(1-13,14,15,17)对某时刻 t t t的所有权重求偏导,很容易求出 t t t时刻的 W f h W i h W c ‾ h W o h W_{fh} W_{ih} W_{\overline{c}h} W_{oh} WfhWihWchWoh的偏导数,即误差项:

∂ E ∂ W f h , t = ∂ E ∂ n e t f , t ∂ n e t f , t ∂ W f h , t = δ f , t h t − 1 ∂ E ∂ W i h , t = ∂ E ∂ n e t i , t ∂ n e t i t ∂ W i h t = δ i , t h t − 1 ∂ E ∂ W c ‾ h , t = ∂ E ∂ n e t c ‾ , t ∂ n e t c ‾ , t ∂ W c ‾ h , t = δ c ‾ , t h t − 1 ∂ E ∂ W o h , t = ∂ E ∂ n e t o , t ∂ n e t o , t ∂ W o h , t = δ o , t h t − 1 ( 1 − 29 ) \begin{array}{l} {\frac{\partial E}{\partial W_{f h, t}}=\frac{\partial E}{\partial n e t_{f, t}} \frac{\partial n e t_{f, t}}{\partial W_{f h, t}}=\delta_{f, t} h_{t-1}} \\{\frac{\partial E}{\partial W_{i h, t}}=\frac{\partial E}{\partial n e t_{i, t}} \frac{\partial n e t_{i t}}{\partial W_{i h t}}=\delta_{i, t} h_{t-1}} \\{\frac{\partial E}{\partial W_{\overline{c} h, t}}=\frac{\partial E}{\partial n e t_{\overline{c}, t}} \frac{\partial n e t_{\overline{c}, t}}{\partial W_{\overline{c} h, t}}=\delta_{\overline{c}, t} h_{t-1}} \\ {\frac{\partial E}{\partial W_{o h, t}}=\frac{\partial E}{\partial n e t_{o, t}} \frac{\partial n e t_{o, t}}{\partial W_{o h, t}}=\delta_{o, t} h_{t-1}}\end{array} \quad\quad(1-29) Wfh,tE=netf,tEWfh,tnetf,t=δf,tht1Wih,tE=neti,tEWihtnetit=δi,tht1Wch,tE=netc,tEWch,tnetc,t=δc,tht1Woh,tE=neto,tEWoh,tneto,t=δo,tht1(129)  对于整个样本,它的误差是所有时刻的误差之和,最终得到:

∂ E ∂ W f h = ∑ j = 1 t δ f , j h j − 1 ∂ E ∂ W i h = ∑ j = 1 t δ i , j h j − 1 ∂ E ∂ W c h ‾ = ∑ j = 1 t δ τ ‾ , j h j − 1 ∂ E ∂ W o h = ∑ j = 1 t δ o , j h j − 1 ( 1 − 30 ) \begin{array}{l}{ \frac{\partial E}{\partial W_{f h}}=\sum_{j=1}^{t} \delta_{f, j} h_{j-1}} \\ {\frac{\partial E}{\partial W_{i h}}=\sum_{j=1}^{t} \delta_{i, j} h_{j-1} }\\ {\frac{\partial E}{\partial W_{\overline{c h}}}=\sum_{j=1}^{t} \delta_{\overline{\tau}, j} h_{j-1}}\\ {\frac{\partial E}{\partial W_{o h}}=\sum_{j=1}^{t} \delta_{o, j} h_{j-1} }\end{array}\quad\quad(1-30) WfhE=j=1tδf,jhj1WihE=j=1tδi,jhj1WchE=j=1tδτ,jhj1WohE=j=1tδo,jhj1(130)

  对于偏置项 b f , b i , b c , b o \mathbf{b}_{f}, \mathbf{b}_{i}, \mathbf{b}_{c}, \mathbf{b}_{o} bf,bi,bc,bo的梯度,也是将各个时刻的梯度加在一起。下面是各个时刻的偏置项梯度:

∂ E ∂ b f , t = ∂ E ∂ n e t f , t ∂ n e t f , t ∂ b f , t = δ f , t ∂ E ∂ b i , t = ∂ E ∂ n e t i , t ∂ n e t i , t ∂ b i , t = δ i , t ∂ E ∂ b c ‾ , t = ∂ E ∂ n e t c ‾ , t ∂ n e t c ‾ , t ∂ b c ‾ , t = δ c ‾ , t ∂ E ∂ b o , t = ∂ E ∂ n e t o , t ∂ n e t o , t ∂ b o , t = δ o , t ( 1 − 31 ) \begin{array}{l}{ \frac{\partial E}{\partial b_{f, t}}=\frac{\partial E}{\partial n e t_{f, t}} \frac{\partial n e t_{f, t}}{\partial b_{f, t}}=\delta_{f, t}}\\ {\frac{\partial E}{\partial b_{i, t}}=\frac{\partial E}{\partial n e t_{i, t}} \frac{\partial n e t_{i, t}}{\partial b_{i, t}}=\delta_{i, t}}\\ {\frac{\partial E}{\partial b_{\overline{c}, t}}=\frac{\partial E}{\partial n e t_{\overline{c}, t}} \frac{\partial n e t_{\overline{c}, t}}{\partial b_{\overline{c}, t}}=\delta_{\overline{c}, t}}\\ {\frac{\partial E}{\partial b_{o, t}}=\frac{\partial E}{\partial n e t_{o, t}} \frac{\partial n e t_{o, t}}{\partial b_{o, t}}=\delta_{o, t} }\end{array}\quad\quad(1-31) bf,tE=netf,tEbf,tnetf,t=δf,tbi,tE=neti,tEbi,tneti,t=δi,tbc,tE=netc,tEbc,tnetc,t=δc,tbo,tE=neto,tEbo,tneto,t=δo,t(131)
  偏差累加和为:
∂ E ∂ b f = ∑ j = 1 t δ f , j ∂ E ∂ b i = ∑ j = 1 t δ i , j ∂ E ∂ b c ‾ = ∑ j = 1 t δ c ‾ , j ∂ E ∂ b o = ∑ j = 1 t δ o , j ( 1 − 32 ) \begin{array}{l}{ \frac{\partial E}{\partial b_{f}}=\sum_{j=1}^{t} \delta_{f, j}} \\ {\frac{\partial E}{\partial b_{i}}=\sum_{j=1}^{t} \delta_{i, j}} \\ {\frac{\partial E}{\partial b_{\overline{c}}}=\sum_{j=1}^{t} \delta_{\overline{c}, j}} \\ {\frac{\partial E}{\partial b_{o}}=\sum_{j=1}^{t} \delta_{o, j} }\end{array}\quad\quad(1-32) bfE=j=1tδf,jbiE=j=1tδi,jbcE=j=1tδc,jboE=j=1tδo,j(132)
  对于 W f x . W i x . W c x . W o x W_{f x} . W_{i x} . W_{c x .} W_{o x} Wfx.Wix.Wcx.Wox的权重梯度,与时间没有关系,只需要根据相应的误差项直接计算即可:
∂ E ∂ W f x = ∂ E ∂ n e t f , t ∂ n e t f , t ∂ W f x = δ f , t x t ∂ E ∂ W i x = ∂ E ∂ n e t i , t ∂ n e t i , t ∂ W i x = δ i , t x t ∂ E ∂ W c ‾ x = ∂ E ∂ n e t c ‾ t ∂ n e t c ‾ , t ∂ W c ‾ x = δ c ‾ , t x t ∂ E ∂ W o x = ∂ E ∂ n e t o t ∂ n e t o , t ∂ W o x = δ o t x t ( 1 − 33 ) \begin{array}{l} {\frac{\partial E}{\partial W_{\mathscr{fx}}}=\frac{\partial E}{\partial n e t_{f, t}} \frac{\partial n e t_{f, t}}{\partial W_{fx}}=\delta_{f, t} x_{t}}\\ {\frac{\partial E}{\partial W_{i x}}=\frac{\partial E}{\partial n e t_{i, t}} \frac{\partial n e t_{i, t}}{\partial W_{i x}}=\delta_{i, t} x_{t}}\\ {\frac{\partial E}{\partial W_{\overline{c} x}}=\frac{\partial E}{\partial n e t_{\overline{c} t}} \frac{\partial n e t_{\overline{c} , t}}{\partial W_{\overline{c} x}}=\delta_{\overline{c}, t} x_{t}}\\ {\frac{\partial E}{\partial W_{o x}}=\frac{\partial E}{\partial n e t_{o t}} \frac{\partial n e t_{o, t}}{\partial W_{o x}}=\delta_{o t} x_{t}}\end{array}\quad\quad(1-33) WfxE=netf,tEWfxnetf,t=δf,txtWixE=neti,tEWixneti,t=δi,txtWcxE=netctEWcxnetc,t=δc,txtWoxE=netotEWoxneto,t=δotxt(133)
W y i W_{yi} Wyi的误差项直接求导即可。
∂ E ∂ W y i = σ ′ ( W y i h t ) h t ( 1 − 34 ) \frac{\partial E}{\partial W_{yi}} = \sigma'(W_{yi}h_t)h_t\quad\quad(1-34) WyiE=σ(Wyiht)ht(134)

  1. 根据相应的误差项,计算需要学习的参数的梯度,根据该梯度进行随机梯度下降法学习参数。
      以上就是LSTM的训练算法的全部公式,根据我们得到的误差项,加上学习率反向传播用随机梯度下降等优化方法优化参数即可。因为这里面存在很多重复的模式,仔细看看,会发觉并不是太复杂。

1.4 GRU单元

  GRU即Gated Recurrent Unit ,是LSTM的一个变体。GRU保持了LSTM的效果同时又使结构更加简单,使用的参数更少,应用十分广泛。
  GRU模型如下,它只有两个门了,分别为更新门和重置门,即图中的 z t z_t zt r t r_t rt 。更新门用于控制前一时刻的状态信息保留到当前状态中的程度,更新门的值越大说明前一时刻的状态信息保留得越多。重置门用于控制忽略前一时刻的状态信息的程度,重置门的值越小说明忽略得越多。

在这里插入图片描述
图1-6 GRU单元基本结构

  根据图1.6可以得到GRU的传播过程为:
r t = σ ( W r ⋅ [ h t − 1 , x t ] + b r ) z t = σ ( W z ⋅ [ h t − 1 , x t ] + b z ) h ‾ t = tanh ⁡ ( W h ‾ ⋅ [ r t h t − 1 , x t ] + b h ‾ ) h t = z t ∗ h t − 1 + ( 1 − z t ) ∗ h ‾ t y t = σ ( W o ⋅ h t ) \begin{aligned} r_{t} &=\sigma\left(W_{r} \cdot\left[h_{t-1}, x_{t}\right]+b_r\right) \\ z_{t} &=\sigma\left(W_{z} \cdot\left[h_{t-1}, x_{t}\right]+b_z\right) \\ \overline{h}_{t} &=\tanh \left(W_{ \overline{h}} \cdot\left[r_{t} h_{t-1}, x_{t}\right]+b_{\overline{h}}\right) \\ h_{t} &=z_{t}* h_{t-1}+(1-z_{t}){*} \overline{h}_{t} \\ y_{t} &=\sigma\left(W_{o} \cdot h_{t}\right) \end{aligned} rtzththtyt=σ(Wr[ht1,xt]+br)=σ(Wz[ht1,xt]+bz)=tanh(Wh[rtht1,xt]+bh)=ztht1+1ztht=σ(Woht)
  其中[ ]表示两个向量的连接,*表示两个矩阵元素相乘。GRU的训练同LSTM类似,但是比LSTM的权重矩阵参数更容易,GRU需要学习的参数只有 W r , W z , W h ‾ , W o W_{r}, W_{z}, W_{\overline{h}}, W_{o} Wr,Wz,Wh,Wo,其中前三个参数LSTM中权重矩阵是一样的,都是拼接矩阵,在求解的时候也需要分割开来。
  概括来说,LSTM和CRU都是通过各种门函数来将重要特征保留下来,这样就保证了在long-term传播的时候也不会丢失。此外GRU相对于LSTM少了一个门函数,因此在参数的数量上也是要少于LSTM的,所以整体上GRU的训练速度要快于LSTM的。不过对于两个网络的好坏还是得看具体的应用场景。

GRU和LSTM的区别和联系

1.5 双向RNN

  Bidirectional RNN(双向RNN)假设当前t的输出不仅仅和之前的序列有关,并且还与之后的序列有关,例如:预测一个语句中缺失的词语那么需要根据上下文进 行预测;Bidirectional RNN是一个相对简单的RNNs,由两个RNNs上下叠加在 一起组成。输出由这两个RNNs的隐藏层的状态决定。
在这里插入图片描述
如下图:
在这里插入图片描述
代码如下:

    # 开始网络构建
    # 1. 输入的数据格式转换
    # X格式:[batch_size, time_steps, input_size]
    X = tf.reshape(_X, shape=[-1, timestep_size, input_size])

    # 单层LSTM RNN
    # 2. 定义Cell
    lstm_cell_fw = tf.nn.rnn_cell.LSTMCell(num_units=hidden_size, reuse=tf.get_variable_scope().reuse)
    gru_cell_bw = tf.nn.rnn_cell.GRUCell(num_units=hidden_size, reuse=tf.get_variable_scope().reuse)

    # 3. 单层的RNN网络应用
    init_state_fw = lstm_cell_fw.zero_state(batch_size, dtype=tf.float32)
    init_state_bw = gru_cell_bw.zero_state(batch_size, dtype=tf.float32)

    # 3. 动态构建双向的RNN网络
    """
    bidirectional_dynamic_rnn(
        cell_fw: 前向的rnn cell
        , cell_bw:反向的rnn cell
        , inputs:输入的序列
        , sequence_length=None
        , initial_state_fw=None:前向rnn_cell的初始状态
        , initial_state_bw=None:反向rnn_cell的初始状态
        , dtype=None
        , parallel_iterations=None
        , swap_memory=False, time_major=False, scope=None)
    API返回值:(outputs, output_states) => outputs存储网络的输出信息,output_states存储网络的细胞状态信息
    outputs: 是一个二元组, (output_fw, output_bw)构成,output_fw对应前向的rnn_cell的执行结果,结构为:[batch_size, time_steps, output_size];output_bw对应反向的rnn_cell的执行结果,结果和output_bw一样
    output_states:是一个二元组,(output_state_fw, output_state_bw) 构成,output_state_fw和output_state_bw是dynamic_rnn API输出的状态值信息
    """
    outputs, states = tf.nn.bidirectional_dynamic_rnn(
        cell_fw=lstm_cell_fw, cell_bw=gru_cell_bw, inputs=X,
        initial_state_fw=init_state_fw, initial_state_bw=init_state_bw)
    output_fw = outputs[0][:, -1, :]
    output_bw = outputs[1][:, -1, :]
    output = tf.concat([output_fw, output_bw], 1)

深度RNN
Deep Bidirectional RNN(深度双向RNN)类似Bidirectional RNN,区别在于每 个每一步的输入有多层网络,这样的话该网络便具有更加强大的表达能力和学习 能力,但是复杂性也提高了,同时需要训练更多的数据。
在这里插入图片描述

#多层
    def lstm_call():
        cell = tf.nn.rnn_cell.LSTMCell(num_units=hidden_size,reuse=tf.get_variable_scope().reuse)
        return tf.nn.rnn_cell.DropoutWrapper(cell,output_keep_prob=keep_prob)
    mlstm_cell = tf.nn.rnn_cell.MultiRNNCell(cells=[lstm_call() for i in range(layer_num)])
    inint_state = mlstm_cell.zero_state(batch_size,tf.float32)
    output,state = tf.nn.dynamic_rnn(mlstm_cell,inputs=X,initial_state=inint_state)
    output = output[:,-1,:]

1.6 带有其他特性的RNN单元

本节整理自《深入理解TensorFlow》,基本的RN单元,LSTM单元,GRU单元等还可以结合其他特性,从而形成新的RNN单元变种。tensorflow文件中定义的DropoutWrapper,ResidualWrapper,DeviceWrapper,MultiRNNCell等包装器或工具类都继承自RNNCell类,他们分别提供不同的特性。DeviceWrapper比较简单,主要是使某个具体的RNN单元运行在指定的设备上。

1.6.1 DropoutWrapper

该类提供Dropout

2 RNN模型

2.1 PTB-LSTM语言模型

2.2 Seq2Seq模型

2.3 Relational-RNN(attention)

2.4 CRNN

;