8.7 通过时间反向传播
我们已经反复提到梯度爆炸或者梯度消失,以及需要对循环神经网络分离梯度,在8.5节中,我们在序列上调用了detach函数,为了能够快速构建模型并了解其工作原理,上面所说的这些概念需要进行充分的解释。更深入的探讨序列模型反向传播的细节以及相关的数学原理。
当我们首次实现循环神经网络时,遇到了梯度爆炸的问题,如果做了练习题,就会发现梯度截断对于确保模型收敛至关重要,为了更好的理解此问题,本节将回顾序列模型梯度的计算方式,工作原理不涉及新概念,毕竟我们仍然使用链式法则来计算梯度。
我们在4.7节中描述了多层感知机中的前向传播与反向传播以及相关的计算图。循环神经网络中的前向传播相对简单。通过时间反向传播 BPTT实际上是循环神经网络中反向传播技术一个特定应用。要求我们将循环神经网络的计算图一次展开一个时间步,以获得模型变量和参数之间的依赖关系,基于链式法则,应用反向传播来计算和存储梯度,由于序列可能相当长,因此依赖关系链也可能相当长。某个1000个字符的序列,其第一个词元可能会对最后位置的词元产生重大影响。计算上是不可行的,并且还需要超过1000个矩阵的乘积才能得到非常难以捕捉的梯度。这个过程充满了计算与统计的不确定性,我们将阐述会发生什么以及如何在实践中解决它们。
8.7.1 循环神经网络的梯度分析
我们从一个描述循环神经网络工作原理的简化模型开始,忽略了隐状态以及更新方式的细节,这里的数学表示没有像原先那样明确的区分标量,向量和矩阵,因为i这些细节对于分析并不重要,反而会使得本节中的符号变得混乱。
这个简化模型中,我们可以将时间同步t的隐状态表示为h,输入表示为Xt,输出表示为Ot,回想一下我们在8.4.2节中的讨论,输入的隐状态可以拼接后与隐藏层中的一个权重变量相乘,我们使用Wk和Wo来分别表示隐藏层和输出层的权重,时间步的隐状态和输出可以写为
h1 = f(xt,ht-1,wk)
Ol = g(ht,wk)
f和g分别是隐藏层和输出层的变换,我们有一个链,通过循环计算彼此的依赖,前向床薄相当简单,一次一个时间步遍历三元组(Xn,Hn,Ot),然后通过一个目标函数L在所有T个时间步内评估输出Ot和对应的标签Yt之间的差距
反向传播,特别是当前计算目标函数L对于参数Wk的梯度时,具体来说,按照链式法则。
式8.28中乘积的第一项和第二项很容易计算,第三项ht/wh是使问题棘手的地方。因为我们需要循环的计算参数Wh 对Ht的影响,根据式中的递归计算,ht即依赖ht-1,又依赖wh, 其中ht-1的计算也依赖Wk, 因此,使用链式法则产生。
Ht/Wh
为了导出上述梯度,假设我们有3个序列{at},{bt} {ct} 序列满足a0=0而且at = ht + cat-1,
虽然我们可以使用链式法则递归的计算sigmaHt/sigmaWk,当t很大的时候这个链就会变得很长,我们需要想办法处理这一问题。
1 完整计算
我们可以计算式中的全部总和,这样的计算非常缓慢,并且可能发生梯度爆炸,初始条件的微小变化就可能会对结果产生巨大的影响,我们可以观察到类似蝴蝶效应的现象。对于我们想要估计的模型是非常不可取的,毕竟,我们正在寻找的是能够很好的泛化高稳定性模型的估计器,在实践中,这种方法几乎从未使用过。
2 截断时间步
我们可以在r步后截断式中的求和计算,这是我们到目前为止一直在讨论的内容,例如8.5 节中的分离梯度,这回带来真实梯度的近似,只需将求和终止到Ht-1/Wk 在实践中,这种方式工作得很好,通常被称为截断的通过时间反向传播,这样做导致该模型主要侧重于短期影响,而不是长期影响,这在现实中是可取的,会将估计值偏向更简单和更稳定的模型。
3 随机截断
我们可以用一个随机变量替换sigmaht/sigmaWk, 该随机变量在预期中是正确的,但是会截断序列,这个随机变量是通过使用序列sigma来实现的,序列与定义了0 < Xt <1,
4 比较策略
图8-6说明了当基于循环神经网络使用通过时间反向传播分析时间机器数据集中前几个字符的3种策略。
第一行 采样随机截断,方法时将文本拆分为不同的长度的片段
第二行 采用常规截断,方法是将文本拆分为相同长度的子序列,这也是我们在循环神经网络中一直采用的。
第三行采用通过时间的完全反向传播,结果是产生了在计算上不可行的表达式。
遗憾的是,虽然随机截断在理论上具有吸引力,由于多种时间步经过反向传播后,观测结果足以捕获实际的依赖关系,第二,增加的方差抵消了时间步数越多梯度越精确的效果,第三,我们真正想要的是只在小范围交互的模型。因此,模型需要的正是截断的通过时间反向传播方法所具备的轻度正则化效果。
8.7.2 通过的时间反向传播的细节
在讨论一般性原则之后,看一下通过时间反向传播问题的细节。与8.7.1节中的分析不同,下面我们将展示如何计算目标函数对于所有分解模型参数的梯度,位了保持简单,我们考虑一个没有偏置参数的循环神经网络,其在隐层中的激活函数使用恒等函数。对于时间步t,设单个样本的输入及其对应的标签分别为Xt属于Rd和y,计算隐状态Ht属于Rk和输出sigma 属于Rk的公式为
Ht = WhxXt + EkhHt-1
Sigma t = WqhHt
权重参数为Whx属于RhxdmWhk属于Rh-k和Wqh属于Rqxh。用l(Ot, Yt)表示时间步t处的损失函数,我们的目标函数的总体损失是
L = 1/T Sigma(Ot, Yt)
为了在循环神经网络的计算过程中可视化模型变量和参数之间的依赖关系,我们可以为模型绘制一个计算图,如图所示,时间步3的隐状态h3的计算取决于模型参数Wh和Whk,以及最终时间步的隐状态h2 以及当前时间步的输入Xt。
X3, ->Wh3 <- h2
X2, ->Wh2 <- h1
X1 ->Wh1 <- h0
图8-7 具有3个时间步的循环神经网络模型依赖关系的计算图
如上面所述,图8-7种的模型参数时Whx,Whh和Wqh通常, 训练该模型需要对这些参数分别进行梯度计算L/W,L/Whh和L/Wqh.根据图8-7中的依赖关系,我们可以沿着箭头所指的反向遍历计算图,依次计算和存储梯度,位了灵活地表示链式法则中不同形状的矩阵,向量和标量的乘法,我们继续使用4.7 节中所述的prod运算符。
在任意时间步t,目标函数关于模型输出的微分计算时相当简单的
我们可以计算目标函数对于输出层参数Wqh的梯度,L/W, 基于图8-7.目标函数L通过O1,...Ot依赖Wqh,依据链式法则。
L/Wqh = Sigmaprod()
图8-7所示,在最后的时间步T,目标函数L仅仅通过Ot依赖隐状态Ht,我们通过使用链式法则可以很容易得到L/Ht = Rh
当目标函数L通过Ht+1和Ot依赖Ht时,任意时间步t<T来说更加棘手,根据链式法则,隐状态的梯度L/Ht属于Rh 在任何时间步t<T时都可以递归的计算为。
位了进行分析,对于任何时间步l<=t<=T展开递归计算得到。
L/Ht
我们从式中可以看到,简单的线性例子已经展现了长序列模型的一些关键问题,陷入了Whk的潜在的非常大的幂,小于1的特征值将会消失,大于1的特征值将会发散,这在数值上是不稳定的,表现形式为梯度消失或梯度爆炸,解决此问题的一种方法时根据计算方便的需要截断时间步的尺寸,实际上,这种截断时通过在给定数量的时间步之后分离梯度来实现的,我们将学习更复杂的序列模型是如何进一步缓解这一问题的。
目标函数L通过隐状态h1,...ht,依赖隐层中的模型参数Whk,和Whh 为了计算对于这些参数的梯度。我们应用链式法则得到
L/H,由式递归计算得到的,是影响数值稳定性的关键量。
正如我们4.7节中所解释 的那样,由于通过时间反向传播的循环神经网络中的应用方式,训练循环神经网络时交替使用前向传播和通过时间反向传播,通过时间反向传播依次计算并存储上梯度,具体而言,存储的中间值会被重复使用,以免重复计算。
小结:
通过时间反向传播,仅适用于反向传播具有隐状态的序列模型
截断时计算方便性和数值稳定性的需要,截断包括,常规截断和随机截断
矩阵的高次幂可能导致神经网络特征值的发散或者消失,将以梯度爆炸或者梯度消失的形式表现。
为了确保计算的效率,通过时间反向传播 在计算期间会缓存中间值。