🎨
Bible-DeepLearning
  • Introduction
  • 第6章 深度前馈网络
    • 6.1 例子:学习XOR
    • 6.2 基于梯度的学习
      • 6.2.1 代价函数
        • 6.2.1.1 使用最大似然学习条件分布
        • 6.2.1.2 学习条件统计量
      • 6.2.2 输出单元
        • 6.2.2.1 用于高斯输出分布的线性神单元
        • 6.2.2.2 用于Bernoulli输出分布的sigmoid单元
        • 6.2.2.3 用于Multinoulli输出分布的softmax单元
    • 6.3 隐藏单元
      • 6.3.1 ReLU及其扩展
      • 6.3.2 logistic sigmoid与双曲正切函数
      • 6.3.3 其他隐藏单元
      • 李宏毅补充 SELU
    • 6.4 架构设计
    • 6.5 反向传播和其他的微分算法
      • 6.5.1 计算图
      • 6.5.2 微积分中的链式法则
      • 6.5.3 递归地使用链式法则来实现反向传播
      • 6.5.4 全连接MLP中的反向传播计算
      • 6.5.5 符号到符号的导数
      • 6.5.6 一般化的反向传播
      • 6.5.7 实例:用于MLP 训练的反向传播
      • 6.5.8 复杂化
  • 第7章 深度学习中的正则化
    • 7.1 参数范数惩罚
      • 7.1.1 L2参数正则化
      • 7.1.2 L1参数正则化
    • 7.2 作为约束的范数惩罚
    • 7.3 正则化和欠约束问题
    • 7.4 数据集增强
    • 7.5 噪声鲁棒性
    • 7.6 半监督学习
    • 7.7 多任务学习
    • 7.8 提前终止
    • 7.9 参数绑定和参数共享
    • 7.10 稀疏表示
    • 7.11 Bagging 和其他集成方法
    • 7.12 Dropout
    • 7.13 对抗训练
    • 7.14 切面距离、正切传播和流形正切分类器
    • Ag补充 一些能用于提升比赛成绩的方法
  • 第8章 深度模型中的优化
    • 8.1 学习和纯优化有什么不同
      • 8.1.1 经验风险最小化
      • 8.1.2 代理损失函数和提前终止
      • 8.1.3 批量算法和小批量算法
    • 8.2 神经网络优化中的挑战
      • 8.2.1 病态
      • 8.2.2 局部极小值
      • 8.2.3 8.2.3 高原、鞍点和其他平坦区域
      • 8.2.4 悬崖和梯度爆炸
      • 8.2.5 长期依赖
      • 8.2.6 非精确梯度
    • 8.3 基本算法
      • 8.3.1 随机梯度下降
      • 8.3.2 动量
      • 8.3.3 Nesterov 动量
    • 8.4 参数初始化策略
    • 8.5 自适应学习率算法
      • 8.5.1 AdaGrad
      • 8.5.2 RMSProp
      • 8.5.3 Adam
      • 8.5.4 选择正确的优化算法
    • 8.6 二阶近似方法
      • 8.6.1 牛顿法
      • 8.6.2 共轭梯度
      • 8.6.3 BFGS
    • 8.7 优化策略和元算法
      • 8.7.1 批标准化
      • 8.7.2 坐标下降
      • 8.7.3 Polyak 平均
      • 8.7.4 监督预训练
      • 8.7.5 设计有助于优化的模型
  • 第9章 卷积网络
    • 9.1 卷积运算
    • 9.2 动机
    • 9.3 池化
    • 9.4 卷积与池化作为一种无限强的先验
    • 9.5 基本卷积函数的变体
    • 9.6 结构化输出
    • 9.7 数据类型
  • 第10章 序列建模:循环和递归网络
    • 10.1 展开计算图
    • 10.2 循环神经网络
      • 10.2.1 导师驱动过程和输出循环网络
      • 10.2.2 计算循环神经网络的梯度
      • 10.2.3 作为有向图模型的循环网络
      • 10.2.4 基于上下文的RNN序列建模
    • 10.3 双向RNN
    • 10.4 基于编码 - 解码的序列到序列架构
    • 10.5 深度循环网络
    • 10.6 递归神经网络
    • 10.7 长期依赖的挑战
    • 10.9 渗漏单元和其他多时间尺度的策略
    • 10.10 长短期记忆和其他门控RNN
      • 10.10.1 LSTM
      • 10.10.2 其他门控RNN
    • 10.11 优化长期依赖
      • 10.11.1 梯度截断
      • 10.11.2 引导信息流的正则化
    • 10.12 外显记忆
  • 第11章 实践方法论
    • 11.1 性能度量
    • 11.2 默认的基准模型
    • 11.3 决定是否收集更多数据
    • 11.4 选择超参数
      • 11.4.1 手动选择超参数
      • 11.4.3 网络搜索
      • 11.4.4 随机搜索
    • 11.5 调试策略
Powered by GitBook
On this page

Was this helpful?

  1. 第10章 序列建模:循环和递归网络
  2. 10.2 循环神经网络

10.2.2 计算循环神经网络的梯度

计算循环神经网络的梯度是容易的。 我们可以简单地将\sec?中的推广反向传播算法应用于展开的计算图,而不需要特殊化的算法。 由反向传播计算得到的梯度,并结合任何通用的基于梯度的技术就可以训练RNN。

为了获得BPTT算法行为的一些直观理解,我们举例说明如何通过BPTT计算上述RNN公式(\eqn?和\eqn?)的梯度。 计算图的节点包括参数$U,V,W, b$和$c$,以及以$t$为索引的节点序列$x^{(t)}, h^{(t)},o^{(t)}$和$L^{(t)}$。 对于每一个节点$N$,我们需要基于$N$后面的节点的梯度,递归地计算梯度$\nabla_{N} L$。 我们从紧接着最终损失的节点开始递归:

∂L∂L(t)=1.\begin{aligned} \frac{\partial L}{\partial L^{(t)}} = 1. \end{aligned}∂L(t)∂L​=1.​

[warning] 这个公式不知道怎么推出来的?

在这个导数中,我们假设输出$o^{(t)}$作为softmax函数的参数,我们可以从softmax函数可以获得关于输出概率的向量$\hat{y}$。 我们也假设损失是迄今为止给定了输入后的真实目标$y^{(t)}$的负对数似然。

[success] 以下公式推导中: t代表任意一个时刻,不是某个具体的时刻。 $\tau$代表当前时刻。

对于所有$i,t$,关于时间步$t$输出的梯度$\nabla_{o^{(t)}} L$如下:

(∇o(t)L)i=∂L∂oi(t)=∂L∂L(t)∂L(t)∂oi(t)=y^i(t)−1i,y(t).\begin{aligned} (\nabla_{o^{(t)}} L)_i = \frac{\partial L}{\partial o_i^{(t)}} = \frac{\partial L}{\partial L^{(t)}} \frac{\partial L^{(t)}}{\partial o_i^{(t)}} = \hat y_i^{(t)} - \mathbf{1}_{i,y^{(t)}}. \end{aligned}(∇o(t)​L)i​=∂oi(t)​∂L​=∂L(t)∂L​∂oi(t)​∂L(t)​=y^​i(t)​−1i,y(t)​.​

我们从序列的末尾开始,反向进行计算。 在最后的时间步$\tau$, $h^{(\tau)}$只有$o^{(\tau)}$作为后续节点,因此这个梯度很简单:

∇h(τ)L=V⊤∇o(τ)L.\begin{aligned} \nabla_{h^{(\tau)}} L = V^\top \nabla_{o^{(\tau)}} L. \end{aligned}∇h(τ)​L=V⊤∇o(τ)​L.​

然后,我们可以从时刻$t=\tau-1$到$t=1$反向迭代, 通过时间反向传播梯度,注意$h^{(t)}(t < \tau)$同时具有$o^{(t)}$和$h^{(t+1)}$两个后续节点。 因此,它的梯度由下式计算

∇h(t)L=(∂h(t+1)∂h(t))⊤(∇h(t+1)L)+(∂o(t)∂h(t))⊤(∇o(t)L)=W⊤(∇h(t+1)L)diag(1−(h(t+1))2)+V⊤(∇o(t)L),\begin{aligned} \nabla_{h^{(t)}} L = \Big( \frac{\partial h^{(t+1)}}{ \partial h^{(t)}} \Big)^\top(\nabla_{h^{(t+1)}} L) + \Big( \frac{\partial o^{(t)}}{ \partial h^{(t)}} \Big)^\top (\nabla_{o^{(t)}} L) \\ = W^\top (\nabla_{h^{(t+1)}} L) \text{diag} \Big( 1 - (h^{(t+1)})^2 \Big) + V^\top ( \nabla_{o^{(t)}} L ), \end{aligned}∇h(t)​L=(∂h(t)∂h(t+1)​)⊤(∇h(t+1)​L)+(∂h(t)∂o(t)​)⊤(∇o(t)​L)=W⊤(∇h(t+1)​L)diag(1−(h(t+1))2)+V⊤(∇o(t)​L),​

[warning] 这个公式怎么推出来的?

(∂h(t+1)∂h(t))⊤=W⊤(∇h(t+1)L)还是(∇h(t+1)L)diag(1−(h(t+1))2)这是哪来的?\begin{aligned} \Big( \frac{\partial h^{(t+1)}}{ \partial h^{(t)}} \Big)^\top = W^\top \\ (\nabla_{h^{(t+1)}} L) \text{还是} (\nabla_{h^{(t+1)}} L) \\ \text{diag} \Big( 1 - (h^{(t+1)})^2 \Big) \text{这是哪来的}? \end{aligned}(∂h(t)∂h(t+1)​)⊤=W⊤(∇h(t+1)​L)还是(∇h(t+1)​L)diag(1−(h(t+1))2)这是哪来的?​

其中$\text{diag} \Big( 1 - (h^{(t+1)})^2 \Big) $ 表示包含元素$1 - (h_i^{(t+1)})^2$的对角矩阵。 这是关于时刻$t+1$与隐藏单元$i$关联的双曲正切的Jacobian。

[warning] 双曲正切的Jacobian?

一旦获得了计算图内部节点的梯度,我们就可以得到关于参数节点的梯度。 因为参数在许多时间步共享,我们必须在表示这些变量的微积分操作时谨慎对待。 我们希望实现的等式使用\sec?中的{\tt bprop}方法计算计算图中单一边对梯度的贡献。 然而微积分中的$\nabla{W} f$算子,计算$W$对于$f$的贡献时将计算图中的\emph{所有}边都考虑进去了。 为了消除这种歧义,我们定义只在$t$时刻使用的虚拟变量$W^{(t)}$作为$W$的副本。 然后,我们可以使用$\nabla{W^{(t)}}$表示权重在时间步$t$对梯度的贡献。

使用这个表示,关于剩下参数的梯度可以由下式给出:

∇cL=∑t(∂o(t)∂c)⊤∇o(t)L=∑t∇o(t)L,∇bL=∑t(∂h(t)∂b(t))⊤∇h(t)L=∑tdiag(1−(h(t))2)∇h(t)L,∇VL=∑t∑i(∂L∂oi(t))∇Voi(t)=∑t(∇o(t)L)h(t)⊤,∇WL=∑t∑i(∂L∂hi(t))∇W(t)hi(t)=∑tdiag(1−(h(t))2)(∇h(t)L)h(t−1)⊤,∇UL=∑t∑i(∂L∂hi(t))∇U(t)hi(t)=∑tdiag(1−(h(t))2)(∇h(t)L)x(t)⊤,\begin{aligned} \nabla_{c} L &= \sum_t \Big( \frac{\partial o^{(t)}}{\partial c} \Big)^\top \nabla_{o^{(t)}} L = \sum_t \nabla_{o^{(t)}} L ,\\ \nabla_{b} L &= \sum_t \Big( \frac{\partial h^{(t)}}{\partial b^{(t)}} \Big)^\top \nabla_{h^{(t)}} L = \sum_t \text{diag} \Big( 1 - \big( h^{(t)} \big)^2 \Big) \nabla_{h^{(t)}} L ,\\ \nabla_{V} L &= \sum_t \sum_i \Big( \frac{\partial L} {\partial o_i^{(t)}}\Big) \nabla_{V} o_i^{(t)} = \sum_t (\nabla_{o^{(t)}} L) h^{(t)^\top},\\ \nabla_{W} L &= \sum_t \sum_i \Big( \frac{\partial L} {\partial h_i^{(t)}}\Big) \nabla_{W^{(t)}} h_i^{(t)} \\ &= \sum_t \text{diag} \Big( 1 - \big( h^{(t)} \big)^2 \Big) ( \nabla_{h^{(t)}} L) h^{(t-1)^\top} ,\\ \nabla_{U} L &= \sum_t \sum_i \Big( \frac{\partial L} {\partial h_i^{(t)}}\Big) \nabla_{U^{(t)}} h_i^{(t)} \\ &= \sum_t \text{diag} \Big( 1 - \big( h^{(t)} \big)^2 \Big) ( \nabla_{h^{(t)}} L) x^{(t)^\top} , \end{aligned}∇c​L∇b​L∇V​L∇W​L∇U​L​=t∑​(∂c∂o(t)​)⊤∇o(t)​L=t∑​∇o(t)​L,=t∑​(∂b(t)∂h(t)​)⊤∇h(t)​L=t∑​diag(1−(h(t))2)∇h(t)​L,=t∑​i∑​(∂oi(t)​∂L​)∇V​oi(t)​=t∑​(∇o(t)​L)h(t)⊤,=t∑​i∑​(∂hi(t)​∂L​)∇W(t)​hi(t)​=t∑​diag(1−(h(t))2)(∇h(t)​L)h(t−1)⊤,=t∑​i∑​(∂hi(t)​∂L​)∇U(t)​hi(t)​=t∑​diag(1−(h(t))2)(∇h(t)​L)x(t)⊤,​

因为计算图中定义的损失的任何参数都不是训练数据$x^{(t)}$的父节点,所以我们不需要计算关于它的梯度。

Previous10.2.1 导师驱动过程和输出循环网络Next10.2.3 作为有向图模型的循环网络

Last updated 5 years ago

Was this helpful?

[success] 参数包含U,W,V,b,c. (1)计算每条边上的梯度 (2)令{L}=1 (3)根据串行相乘并行相加的方法计算{U}, {W}, {V}, {b}, {c} 最后得到与书上相同的结果。