动手学PyTorch | (33) 通过时间反向传播

在前⾯两节中,如果不裁剪梯度,模型将⽆法正常训练。为了深刻理解这一现象,本节将介绍循环神经⽹络中梯度的计算和存储⽅法,即通过时间反向传播(back-propagation through time)。

我们在(正向传播、反向传播和计算图)中介绍了神经⽹络中梯度计算与存储的⼀般思路,并强调正向传播和反向传播相互依赖。正向传播在循环神经⽹络中⽐较直观,而通过时间反向传播其实是反向传播在循环神经网络中的具体应用。我们需要将循环神经⽹络按时间步展开,从而得到模型变量和参数之间的依赖关系,并依据链式法则应⽤反向传播计算并存储梯度。

目录

1. 定义模型

2. 模型计算图

3. 方法

4. 小结


1. 定义模型

简单起见,我们考虑⼀个⽆偏差项的循环神经网络,且**函数为恒等映射动手学PyTorch | (33) 通过时间反向传播.设时间步t的输⼊为单样本动手学PyTorch | (33) 通过时间反向传播,标签为动手学PyTorch | (33) 通过时间反向传播,那么隐藏状态动手学PyTorch | (33) 通过时间反向传播的计算表达式为:

动手学PyTorch | (33) 通过时间反向传播

其中动手学PyTorch | (33) 通过时间反向传播是隐藏层权????重参数。设输出层权????重参数动手学PyTorch | (33) 通过时间反向传播,时间步t的输出层变量动手学PyTorch | (33) 通过时间反向传播的计算为:

动手学PyTorch | (33) 通过时间反向传播

设时间步t的损失为 动手学PyTorch | (33) 通过时间反向传播.时间步数为T的损失函数L定义为:

动手学PyTorch | (33) 通过时间反向传播

我们将L称为有关给定时间步的数据样本的⽬标函数,并在本节后续讨论中简称为目标函数。

 

2. 模型计算图

为了可视化循环神经网络中模型变量和参数在计算中的依赖关系,我们可以绘制模型计算图,如下图所示。例如,时间步3的隐藏状态动手学PyTorch | (33) 通过时间反向传播的计算依赖模型参数动手学PyTorch | (33) 通过时间反向传播、上⼀时间步隐藏状态动手学PyTorch | (33) 通过时间反向传播以及当前时间步输⼊动手学PyTorch | (33) 通过时间反向传播.

动手学PyTorch | (33) 通过时间反向传播

 

3. 方法

刚刚提到,上图中的模型的参数是动手学PyTorch | (33) 通过时间反向传播.与(正向传播、反向传播和计算图) 中的类似,训练模型通常需要模型参数的梯度动手学PyTorch | (33) 通过时间反向传播.根据上图中的依赖关系,我们可以按照其中箭头所指的反方向依次计算并存储梯度。为了表述⽅便,我们依然采⽤表达链式法则的运算符prod。

⾸先,⽬标函数有关各时间步输出层变量的梯度动手学PyTorch | (33) 通过时间反向传播很容易计算:

动手学PyTorch | (33) 通过时间反向传播

下面,我们可以计算目标函数有关模型参数动手学PyTorch | (33) 通过时间反向传播的梯度动手学PyTorch | (33) 通过时间反向传播.根据上图,L通过动手学PyTorch | (33) 通过时间反向传播依赖动手学PyTorch | (33) 通过时间反向传播。依据链式法则:

动手学PyTorch | (33) 通过时间反向传播

其次,我们注意到隐藏状态之间也存在依赖关系。 在上图中,L只通过动手学PyTorch | (33) 通过时间反向传播依赖最终时间步T的隐藏状态动手学PyTorch | (33) 通过时间反向传播.因此,我们先计算目标函数有关最终时间步隐藏状态的梯度动手学PyTorch | (33) 通过时间反向传播.依据链式法则,我们得到:

动手学PyTorch | (33) 通过时间反向传播

接下来对于时间步动手学PyTorch | (33) 通过时间反向传播,在上图中,L通过动手学PyTorch | (33) 通过时间反向传播动手学PyTorch | (33) 通过时间反向传播依赖动手学PyTorch | (33) 通过时间反向传播。依据链式法则, ⽬标函数有关时间步动手学PyTorch | (33) 通过时间反向传播的隐藏状态的梯度动手学PyTorch | (33) 通过时间反向传播需要按照时间步从⼤到小依次计算:

动手学PyTorch | (33) 通过时间反向传播

将上面的递归公式展开,对任意时间步动手学PyTorch | (33) 通过时间反向传播,我们可以得到目标函数有关隐藏状态梯度的通项公式:

动手学PyTorch | (33) 通过时间反向传播

由上式中的指数项可见,当时间步数T较大或者时间步t较⼩时,目标函数有关隐藏状态的梯度较容易出现衰减和爆炸。这也会影响其他包含动手学PyTorch | (33) 通过时间反向传播项的梯度,例如隐藏层中模型参数的梯度动手学PyTorch | (33) 通过时间反向传播动手学PyTorch | (33) 通过时间反向传播。在上图中,L通过动手学PyTorch | (33) 通过时间反向传播

依赖这些模型参数。 依据链式法则,我们有:

动手学PyTorch | (33) 通过时间反向传播

我们已在之前的内容里解释过,每次迭代中,我们在依次计算完以上各个梯度后,会将它们存储起来,从⽽避免????复计算。例如,由于隐藏状态梯度动手学PyTorch | (33) 通过时间反向传播被计算和存储,之后的模型参数梯度动手学PyTorch | (33) 通过时间反向传播动手学PyTorch | (33) 通过时间反向传播的计算可以直接读取动手学PyTorch | (33) 通过时间反向传播的值,⽽⽆须????重复计算它们。此外,反向传播中的梯度计算可能会依赖变量的当前值。它们正是通过正向传播计算出来的。 举例来说,参数梯度动手学PyTorch | (33) 通过时间反向传播的计算需要依赖隐藏状态在时间步动手学PyTorch | (33) 通过时间反向传播的当前值动手学PyTorch | (33) 通过时间反向传播动手学PyTorch | (33) 通过时间反向传播是初始化得到的)。这些值是通过从输⼊层到输出层的正向传播计算并存储得到的(缓存正向传播的中间结果,可以方便反向传播的计算)。

 

4. 小结

1)通过时间反向传播是反向传播在循环神经⽹络中的具体应用。

2)当总的时间步数T较⼤或者当前时间步t较小时(网络初期),循环神经⽹络的梯度较容易出现衰减或爆炸。