视频封面

视频元信息

  • 视频标题:4.6 正向和反向传播(Forward and Backward Propagation)
  • 所属课程:吴恩达深度学习专项课程 - 改善深层神经网络(Professionalization of Deep Learning)
  • 本集时长:约 10 分钟(根据转录推断)
  • 课程定位:本集是"深层神经网络实现"模块的核心内容,讲解如何用代码实现正向传播和反向传播的完整流程

内容摘要(TL;DR)

本视频详细讲解了深层神经网络中正向传播和反向传播的代码实现方法。正向传播逐层计算 Z 和 A 并缓存中间值;反向传播从输出层开始,利用缓存的 Z 和 A 计算各层的 dW、db、dA。视频给出了四个核心反向传播公式及其向量化实现,并特别说明了反向传播的初始化方法——用损失函数对输出 ŷ 的导数作为起点。吴恩达强调这些公式虽抽象,但通过编程作业会变得具体,机器学习的复杂性主要来自数据而非代码量。


一、正向传播的实现 [00:12]

1.1 正向传播函数的功能

正向传播函数(forward function)的核心任务是:

  • 输入:A^(L-1)(上一层的激活值)
  • 输出:A^(L)(当前层的激活值)
  • 缓存:Z^(L)、W^(L)、B^(L)

缓存 W 和 B 是为了在编程时函数调用更方便,虽然理论上只需要 Z 即可完成反向传播,但实际实现中缓存更多变量能简化代码。

1.2 单样本正向传播公式

对于单个样本,正向传播的计算为:

  • Z^(L) = W^(L) · A^(L-1) + B^(L)
  • A^(L) = g^(L)(Z^(L))

其中 g 为激活函数。

1.3 向量化正向传播

对于整个训练集(m 个样本),向量化实现为:

  • Z = W · A_prev + B(B 通过 Python 广播机制自动扩展)
  • A = g(Z)(激活函数逐元素应用)

易错点:Python 广播(broadcasting)是向量化实现的关键。B 的维度是 (n^[L], 1),而 A_prev 的维度是 (n^[L-1], m),相加时 B 会自动广播为 (n^[L], m)。如果维度不匹配,Python 不会报错但会产生错误结果,这是常见的调试陷阱。

1.4 正向传播链的初始化

正向传播链的起点是输入数据 X:

  • 单样本:a^(0) = x(输入特征向量)
  • 整个训练集:A^(0) = X(输入特征矩阵)

理解:正向传播可以看作一条从左到右的"链",每一层的输出是下一层的输入,依次传递直到输出层。


二、反向传播的实现 [01:57]

2.1 反向传播函数的功能

反向传播函数(backward function)的核心任务是:

  • 输入:dA^(L)(当前层的激活梯度)
  • 输出:dA^(L-1)、dW^(L)、dB^(L)

2.2 四个核心反向传播公式(单样本)

公式一:计算 dZ^(L)

  • dZ^(L) = dA^(L) ⊙ g'^(L)(Z^(L))
  • 其中 ⊙ 表示逐元素乘积(element-wise product)

公式二:计算 dW^(L)

  • dW^(L) = dZ^(L) · (A^(L-1))^T

公式三:计算 dB^(L)

  • dB^(L) = dZ^(L)

公式四:计算 dA^(L-1)

  • dA^(L-1) = (W^(L))^T · dZ^(L)

考点:这四个公式是反向传播的完整实现,必须牢记。 注意 dW 的计算需要 A^(L-1),这就是为什么正向传播时需要缓存 A 值。

2.3 公式的验证与推导

吴恩达指出,如果将 dZ^(L) 的定义代入 dA^(L-1) 的公式中,可以得到:

  • dZ^(L) = (W^(L+1))^T · dZ^(L+1) ⊙ g'^(L)(Z^(L))

这与上一周(单隐层神经网络)中推导的反向传播公式完全一致。

推导:将 dA^(L) = W^(L+1)^T · dZ^(L+1) 代入 dZ^(L) = dA^(L) ⊙ g'^(L)(Z^(L)),即可得到上述公式。这验证了深层网络的反向传播与浅层网络在数学上的一致性。

易错点:dW^(L) 的计算需要 A^(L-1),而正向传播中我们缓存的是 Z^(L),所以需要额外缓存 A^(L-1)。如果忘记缓存 A 值,反向传播将无法计算 dW。

2.4 向量化反向传播实现

对于整个训练集(m 个样本):

第一步:计算 dZ^(L)

  • dZ^(L) = dA^(L) ⊙ g'^(L)(Z^(L))

第二步:计算 dW^(L)

  • dW^(L) = (1/m) · dZ^(L) · (A^(L-1))^T

第三步:计算 dB^(L)

  • dB^(L) = (1/m) · np.sum(dZ^(L), axis=1, keepdims=True)

第四步:计算 dA^(L-1)

  • dA^(L-1) = (W^(L))^T · dZ^(L)

考点:np.sum(dZ, axis=1, keepdims=True) 是计算 dB 的标准写法。 axis=1 表示沿水平方向(样本维度)求和,keepdims=True 保持维度为 (n^[L], 1),防止广播错误。

理解:向量化实现中,dW 和 dB 都需要除以 m,因为它们是整个训练集上的平均梯度。这与单样本情况不同,单样本时不需要除以 m。


三、三层网络的完整流程示例 [05:19]

3.1 网络结构

吴恩达以一个三层网络为例,展示了完整的前向和反向传播流程:

  • 第一层:ReLU 激活函数
  • 第二层:ReLU 激活函数
  • 第三层:Sigmoid 激活函数(用于二分类)

3.2 正向传播流程

  1. 输入 X → 第一层 → 输出 A1(缓存 Z1)
  2. A1 → 第二层 → 输出 A2(缓存 Z2)
  3. A2 → 第三层 → 输出 ŷ = A3(缓存 Z3)
  4. 用 ŷ 计算损失函数

3.3 反向传播流程

  1. 从损失函数开始,计算 dA3
  2. 反向传播计算:dW3、dB3、dA2
  3. 继续反向:dW2、dB2、dA1
  4. 继续反向:dW1、dB1、dA0(dA0 不使用)

缓存 Z1、Z2、Z3 在反向传播中被用来计算激活函数的导数。

理解:整个流程可以概括为"正向传播存缓存,反向传播用缓存"。正向传播从左到右计算并存储中间值,反向传播从右到左利用这些缓存计算梯度。


四、反向传播的初始化 [06:44]

4.1 正向传播的初始化

正向传播的初始化很简单:输入数据 X。

4.2 反向传播的初始化

反向传播的初始化需要计算损失函数对输出 ŷ 的导数。

对于二分类问题(逻辑回归),损失函数为:

  • L(a, y) = -[y·log(a) + (1-y)·log(1-a)]

对 a 求导得到:

  • dA^(L) = -y/a + (1-y)/(1-a)

考点:反向传播的初始化公式 dA^(L) = -y/a + (1-y)/(1-a) 是二分类问题的标准起点。 这个公式来自逻辑回归损失函数的求导。

推导:L = -[y·log(a) + (1-y)·log(1-a)],对 a 求导:dL/da = -[y/a - (1-y)/(1-a)] = -y/a + (1-y)/(1-a)。

4.3 向量化初始化

对于整个训练集,dA^(L) 的向量化形式为:

  • dA^(L) = [-y^(1)/a^(1) + (1-y^(1))/(1-a^(1)), ..., -y^(m)/a^(m) + (1-y^(m))/(1-a^(m))]

即对每个样本分别计算后拼接成向量。

易错点:反向传播的初始化是 dA^(L) 而非 dZ^(L)。很多初学者会混淆这两个量。dA^(L) 是损失函数对激活值的导数,需要先计算它,再通过公式一得到 dZ^(L)。


五、吴恩达的学习建议 [08:27]

5.1 关于公式的抽象性

吴恩达承认这些公式确实很多、很抽象,初学者可能会感到困惑。他的建议是:

  • 完成本周的编程作业,亲手实现这些公式后,会变得具体很多
  • 这些推导是机器学习中较难的数学推导之一,涉及微积分和线性代数
  • 不要因为一时看不懂而气馁

5.2 关于机器学习的本质

吴恩达分享了一个重要观点:

  • 机器学习的复杂性主要来自数据,而非代码
  • 实现一个学习算法可能只需要几行代码,但处理的数据量可能非常庞大
  • 即使是他自己,在实现学习算法时,有时也会惊讶于它能正常工作

思考:这解释了为什么深度学习在实践中常常"看起来很简单"——代码量不大,但背后的数据复杂性和数学原理才是真正的挑战。

5.3 下一步预告

下一视频将讨论超参数(hyperparameters)和参数(parameters) 的区别,以及如何组织超参数来提高开发效率。


六、核心公式总结表

步骤 单样本公式 向量化公式
正向传播 Z Z^(L) = W^(L)·A^(L-1) + B^(L) Z = W·A_prev + B
正向传播 A A^(L) = g^(L)(Z^(L)) A = g(Z)
反向传播 dZ dZ^(L) = dA^(L) ⊙ g'^(L)(Z^(L)) dZ = dA ⊙ g'(Z)
反向传播 dW dW^(L) = dZ^(L)·(A^(L-1))^T dW = (1/m)·dZ·A_prev^T
反向传播 dB dB^(L) = dZ^(L) dB = (1/m)·np.sum(dZ, axis=1, keepdims=True)
反向传播 dA_prev dA^(L-1) = (W^(L))^T·dZ^(L) dA_prev = W^T·dZ
反向传播初始化 dA^(L) = -y/a + (1-y)/(1-a) 对每个样本计算后拼接

七、常见踩坑点与注意事项

踩坑点 1:维度不匹配

  • W 的维度是 (n^[L], n^[L-1]),A_prev 的维度是 (n^[L-1], m)
  • dW 的维度应与 W 相同,dB 的维度应与 B 相同
  • 使用 keepdims=True 防止 dB 维度错误

踩坑点 2:缓存遗漏

  • 正向传播需要缓存 Z^(L) 和 A^(L-1)
  • 反向传播计算 dW 时需要 A^(L-1),计算 dZ 时需要 Z^(L)
  • 忘记缓存会导致反向传播无法进行

踩坑点 3:除以 m

  • 向量化实现中,dW 和 dB 需要除以 m(样本数)
  • 单样本实现中不需要除以 m
  • 混淆两者会导致梯度尺度错误,影响训练效果

踩坑点 4:逐元素乘积 vs 矩阵乘法

  • dZ = dA ⊙ g'(Z) 中,⊙ 是逐元素乘积(element-wise product)
  • dW = dZ · A^T 中,· 是矩阵乘法
  • 混淆两者会导致计算错误

八、拓展补充【拓展】

8.1 计算图视角

吴恩达在课程中多次使用"计算图"(computation graph)的概念。正向传播和反向传播本质上是在计算图上进行前向计算和反向梯度传播。现代深度学习框架(如 PyTorch、TensorFlow)的核心就是自动构建计算图并自动求导。

8.2 自动微分与手动实现

本视频讲解的是手动实现反向传播,这是理解深度学习原理的最佳方式。但在实际工程中,我们通常使用自动微分(automatic differentiation):

  • PyTorch:通过 loss.backward() 自动计算所有梯度
  • TensorFlow:通过 GradientTape 或 tf.gradients 自动求导
  • 自动微分的底层原理正是本视频所讲的链式法则和计算图

8.3 梯度检查(Gradient Checking)

在实现反向传播后,吴恩达在后续课程中会介绍梯度检查技术,通过数值近似验证反向传播的正确性:

  • 数值梯度:f'(θ) ≈ [f(θ+ε) - f(θ-ε)] / (2ε)
  • 将数值梯度与反向传播计算的梯度对比
  • 相对误差小于 10^-7 通常认为是正确的

8.4 为什么反向传播如此高效

反向传播的核心优势在于复用中间计算结果。正向传播时缓存 Z 和 A,反向传播时直接使用这些缓存,避免了重复计算。这使得计算复杂度从 O(n²) 降低到 O(n),是深度学习能够处理大规模网络的关键。


关键标签/关键词

深度学习 #吴恩达 #正向传播 #反向传播 #神经网络 #向量化 #梯度计算 #链式法则 #计算图 #dW #dB #dA #dZ #激活函数 #缓存机制 #Python广播 #np.sum #keepdims #二分类 #逻辑回归 #损失函数 #超参数 #参数 #编程作业 #机器学习 #深度学习专项课程


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