视频封面

视频元信息

  • 所属课程:吴恩达深度学习专项课程 - 神经网络和深度学习(第一门课)
  • 章节:2.8 计算图求导数(Derivatives with a Computation Graph)
  • 讲师:吴恩达(Andrew Ng)
  • 本讲主题:在计算图上通过反向传播(从右到左)逐节点计算导数,并引入代码变量命名约定 dvar

内容摘要(TL;DR)

本讲以函数 J = 3(a + bc) 的计算图为例,演示如何从最终输出 J 出发,沿箭头反方向(从右到左)逐边计算偏导数。先求 dJ/dv = 3,再借助链式法则求出 dJ/da = 3、dJ/du = 3、dJ/db = 6、dJ/dc = 9。同时引入代码命名约定 dvar(如 dv、da、db、dc)表示"最终输出对某中间变量的导数",为后续逻辑回归的反向传播实现打基础。


一、回顾与计算图整体结构 [00:00]

上一讲用计算图计算了函数 J。本讲使用一个更简洁版本的计算图,演示如何用它求出 J 对各个变量的导数。

计算图的结构(正向,从左到右):

  • 输入变量:a = 5,b = 3,c = 2
  • u = b × c = 6
  • v = a + u = 11
  • J = 3v = 33

计算图的核心思想:把复杂函数的计算拆成若干基本步骤,每一步都是一个简单节点,节点之间的边表示依赖关系。

理解:正向计算(左→右)得到 J 的值;反向计算(右→左)得到各变量的导数。这正是深度学习框架(如 PyTorch、TensorFlow)自动微分的基本原理。


二、第一步反向传播:求 dJ/dv [00:15]

目标:求 J 关于 v 的导数,即"如果把 v 稍微改变一点,J 会怎样变化"。

  • 当前 v = 11,J = 3v = 33
  • 把 v 增大一点点到 11.01(增加 0.01)
  • 则 J 从 33 变为 33.03(增加 0.03)

结论:dJ/dv = 3,因为 J 的增量是 v 增量的 3 倍。

这与上一讲中 f(a) = 3a 的例子完全类似:那里 df/da = 3,这里 dJ/dv = 3。对应关系:这里的 J 相当于上一讲的 f,这里的 v 相当于上一讲的 a。

理解:在反向传播术语中,一旦求出最终输出变量(这里是最受关注的 J)对某个变量的导数,就等于在计算图上"往回走了一步"。


三、第二步反向传播:求 dJ/da(链式法则登场)[02:28]

目标:求 J 关于 a 的导数。

  • 当前 a = 5,把它增大到 5.001(增加 0.001)
  • 由于 v = a + u,v 从 11 增加到 11.001
  • 进而 J 从 33 增加到 33.003

结论:dJ/da = 3(a 增加 0.001,J 增加 0.003,增量比为 3 倍)。

链式法则(Chain Rule)

当 a 影响 v、v 又影响 J 时,J 随 a 的变化量 = (v 随 a 的变化量)×(J 随 v 的变化量):

dJ/da = (dJ/dv) × (dv/da)

代入数值:

  • dv/da = 1(a 增加 0.01,v 也增加 0.01,因为 v = a + u,加法节点导数为 1)
  • dJ/dv = 3(上一步已求出)
  • 所以 dJ/da = 3 × 1 = 3 ✓

考点:链式法则是反向传播的数学核心。 已经算出的 dJ/dv 可以被复用来计算 dJ/da,这就是反向传播高效的原因——避免重复计算。

推导:加法节点 v = a + u 对任一输入的偏导数恒为 1;乘法节点 u = b × c 对 b 的偏导数为 c,对 c 的偏导数为 b。记住这两条规则,本讲所有导数都能直接口算。


四、代码命名约定:dvar [05:40]

在实现反向传播的代码中,通常有一个我们最关心的最终输出变量(这里是 J,有时是损失 L),位于计算图的最后一个节点。大量计算都是在求"最终输出变量对某个中间变量的导数"。

命名问题

如果直接按数学写法命名,会得到很长的变量名,例如:

  • dFinalOutputVar/dvar(太长)
  • dJ/dvar(仍然偏长)

吴恩达的约定

在代码中统一用 dvar 表示"最终输出变量对某中间变量 var 的导数"。

例如:

  • dv 表示 dJ/dv,值为 3
  • da 表示 dJ/da,值为 3
  • du 表示 dJ/du
  • db 表示 dJ/db
  • dc 表示 dJ/dc

易错点: 代码里的 dvar 省略了分子(最终输出变量),只保留分母变量名。阅读他人代码或框架源码时要意识到这一点,不要误以为 dv 是"v 的微分"。

思考:这种简写之所以可行,是因为在反向传播中分子永远是同一个最终输出变量,不会产生歧义。这也是为什么 PyTorch 中写 loss.backward() 后可以直接取 x.grad——梯度定义隐含了"对 loss 求导"。


五、继续反向传播:求 dJ/du [08:43]

目标:求 J 关于 u 的导数。

  • 当前 u = 6,把它增大到 6.01(增加 0.01)
  • v 从 11 增加到 11.01
  • J 从 33 增加到 33.03(增加 0.03)

计算方式与 a 完全类似,使用链式法则:

dJ/du = (dJ/dv) × (dv/du) = 3 × 1 = 3

  • dJ/dv = 3(已求出)
  • dv/du = 1(加法节点,v = a + u)

结论:du = 3,即 dJ/du = 3。


六、求 dJ/db(详细演示链式法则乘法)[09:51]

目标:求 J 关于 b 的导数,即"微调 b 会如何影响 J"。

使用链式法则:

dJ/db = (dJ/du) × (du/db)

第一步:求 du/db

  • u = b × c,其中 c = 2
  • b 从 3 增大到 3.01(增加 0.01)
  • u 从 6 变为 6.02(增加 0.02)

du/db = 2(b 增加 0.01,u 增加 0.02,增量比为 2 倍,正好等于 c 的值)。

第二步:代入链式法则

  • dJ/du = 3(上一步已求出)
  • du/db = 2
  • dJ/db = 3 × 2 = 6

数值验证

  • b = 3.01 → u = 6.02 → v = a + u = 5 + 6.02 = 11.02
  • J = 3 × v = 3 × 11.02 = 33.06
  • 相比原来的 33,J 增加了 0.06

结论:db = 6(即 dJ/db = 6)。

理解:这里体现了链式法则的"传导"直觉——b 的变化先影响 u(放大 2 倍),u 的变化再影响 J(放大 3 倍),总放大倍数就是 2 × 3 = 6 倍。


七、求 dJ/dc [12:57]

目标:求 J 关于 c 的导数。

使用链式法则:

dJ/dc = (dJ/du) × (du/dc)

  • dJ/du = 3(已求出)
  • du/dc = b = 3(乘法节点 u = b × c 对 c 的偏导数等于 b)
  • dJ/dc = 3 × 3 = 9

易错点: 乘法节点 u = b × c 对 b 的导数是 c,对 c 的导数是 b,容易记反。建议用"另一个因子"来记忆:对谁求导,导数就是另一个乘数。


八、本讲核心结论与要点总结 [13:16]

关键结论

  1. 计算导数最高效的方式是从右到左计算,即沿着箭头方向的反方向进行反向传播。
  2. 计算顺序有严格的依赖关系:
    • 先算 dJ/dv
    • dJ/dv 用于计算 dJ/da 和 dJ/du
    • dJ/du 又用于计算 dJ/db 和 dJ/dc

正向与反向的分工

方向 计算内容 作用
正向(左→右) 计算代价函数 J 得到待优化的目标值
反向(右→左) 计算各变量导数 为梯度下降提供梯度

各节点导数汇总表

变量 关系式 导数 值
v J = 3v dJ/dv 3
a v = a + u dJ/da 3
u v = a + u dJ/du 3
b u = b × c dJ/db 6
c u = b × c dJ/dc 9

思考:注意 dJ/da 和 dJ/du 都等于 3,看起来巧合,其实是因为它们都是加法节点 v 的输入,而加法对每个输入的偏导都是 1,再乘以共同的 dJ/dv = 3。


九、后续预告与学习建议 [14:19]

  • 下一讲将在逻辑回归的背景下重新走一遍这个过程,展示实现逻辑回归模型导数计算所需的具体步骤。
  • 吴恩达提醒:如果不熟悉微积分或链式法则,本节细节讲得较快,没跟上也不必担心,下一讲会结合具体模型再讲一遍。

学习提醒: 本节是理解神经网络反向传播的基石。务必亲手推导一遍 J = 3(a + bc) 的全部五个导数,并尝试自己画出计算图标注每个节点的导数值,这样才能真正掌握反向传播的流程。


【拓展】相关背景与延伸理解

1. 为什么叫"反向传播"

反向传播(Backpropagation)本质上就是链式法则在计算图上的系统性应用。它的巧妙之处在于:从输出往输入方向逐层计算,每一层的导数都可以复用上一层的结果,把原本指数级复杂度的求导过程降到与正向计算同阶的复杂度。

2. 与自动微分的联系

现代深度学习框架(PyTorch、TensorFlow、JAX)都实现了反向模式自动微分(reverse-mode autodiff),其原理与本讲完全一致:

  • 前向传播时构建计算图并缓存中间值
  • 反向传播时沿图反向应用链式法则

思考:这也是为什么 PyTorch 中需要 loss.backward() 这一步——它触发的就是本讲演示的从右到左的导数计算过程。

3. 加法门与乘法门的直观记忆法

  • 加法门(+):梯度"原样分发"。因为对任一输入的偏导都是 1,所以上游梯度直接传给每个输入。
  • 乘法门(×):梯度"交叉相乘"。对某个输入的梯度等于上游梯度乘以另一个输入的值。

这一直觉在后续学习更复杂网络(如 CNN、RNN)的反向传播时非常有用。

4. 容易踩坑的点

  • 不要把 dvar 理解成"var 的微分",它始终是"最终输出对 var 的偏导"。
  • 链式法则的乘法顺序不影响结果,但依赖关系必须满足:计算某节点的导数前,必须先算出它下游(靠近输出一侧)节点的导数。
  • 数值验证是个好习惯:像本讲一样取一个小增量(如 0.01)验证导数值,可以快速检查推导是否正确。这在调试自定义层时非常实用。

关键标签 / 关键词

计算图 反向传播 链式法则 导数 偏导数 dvar Backpropagation Computation Graph Chain Rule 吴恩达 深度学习 神经网络 逻辑回归 自动微分 梯度下降


生成时间:2026-10-10 21:32:14 生成平台:VideoNote www.xygy.top