37 前向传播与反向传播
37 前向传播与反向传播
一、整体目标
- 实现一个 L 层深度神经网络 的前向传播和反向传播。
- 前向传播用于计算预测值 $\hat{y}$;
- 反向传播用于计算损失函数对各参数的梯度($\frac{\partial \mathcal{L}}{\partial W^{[l]}}$, $\frac{\partial \mathcal{L}}{\partial b^{[l]}}$),用于参数更新。
二、前向传播(Forward Propagation)
1. 输入与输出
- 第 $l$ 层的输入:$A^{[l-1]}$(即上一层的激活值)
- 第 $l$ 层的输出:$A^{[l]}$
- 缓存(cache):通常保存 $Z^{[l]}$,有时也包括 $W^{[l]}, b^{[l]}$
2. 核心公式(单样本或向量化)
对于第 $l$ 层:
\[Z^{[l]} = W^{[l]} A^{[l-1]} + b^{[l]}\] \[A^{[l]} = g^{[l]}(Z^{[l]})\]其中:
- $g^{[l]}(\cdot)$ 是第 $l$ 层的激活函数(如 ReLU、Sigmoid 等)
- 若处理整个训练集(m 个样本),则 $A^{[0]} = X \in \mathbb{R}^{n_x \times m}$
✅ 初始化:$A^{[0]} = X$
3. 流程
从第 1 层到第 L 层依次计算 $Z^{[l]}$ 和 $A^{[l]}$,最终得到预测值 $\hat{Y} = A^{[L]}$。
三、反向传播(Backward Propagation)
1. 目标
- 输入:损失对当前层激活值的导数 $dA^{[l]} = \frac{\partial \mathcal{L}}{\partial A^{[l]}}$
输出:
- $dA^{[l-1]} = \frac{\partial \mathcal{L}}{\partial A^{[l-1]}}$
- $dW^{[l]} = \frac{\partial \mathcal{L}}{\partial W^{[l]}}$
- $db^{[l]} = \frac{\partial \mathcal{L}}{\partial b^{[l]}}$
2. 单样本反向传播公式(逐层)
\[dZ^{[l]} = dA^{[l]} \odot g^{[l]'}(Z^{[l]})\] \[dW^{[l]} = dZ^{[l]} (A^{[l-1]})^\top\] \[db^{[l]} = dZ^{[l]}\] \[dA^{[l-1]} = (W^{[l]})^\top dZ^{[l]}\]其中 $\odot$ 表示 逐元素乘积(Hadamard product)
3. 向量化版本(处理 m 个样本)
\[dZ^{[l]} = dA^{[l]} \odot g^{[l]'}(Z^{[l]})\] \[dW^{[l]} = \frac{1}{m} dZ^{[l]} (A^{[l-1]})^\top\] \[db^{[l]} = \frac{1}{m} \sum_{i=1}^{m} dZ^{[l](i)} = \frac{1}{m} \text{np.sum}(dZ^{[l]}, \text{axis}=1, \text{keepdims=True})\] \[dA^{[l-1]} = (W^{[l]})^\top dZ^{[l]}\]💡 注意:$dW^{[l]}$ 和 $db^{[l]}$ 需要对 m 个样本求平均(即除以 $m$)
4. 反向传播的初始化(最后一层)
若使用 二分类交叉熵损失函数:
\[\mathcal{L} = -\frac{1}{m} \sum_{i=1}^m \left[ y^{(i)} \log \hat{y}^{(i)} + (1 - y^{(i)}) \log (1 - \hat{y}^{(i)}) \right]\]则最后一层(第 L 层)的初始梯度为:
\[dA^{[L]} = \frac{\partial \mathcal{L}}{\partial A^{[L]}} = -\frac{Y}{A^{[L]}} + \frac{1 - Y}{1 - A^{[L]}}\]这是反向传播的起点!
四、完整流程(以 3 层网络为例)
前向传播:
- $A^{[0]} = X$
- $Z^{[1]} = W^{[1]}X + b^{[1]}$, $A^{[1]} = \text{ReLU}(Z^{[1]})$
- $Z^{[2]} = W^{[2]}A^{[1]} + b^{[2]}$, $A^{[2]} = \text{ReLU}(Z^{[2]})$
- $Z^{[3]} = W^{[3]}A^{[2]} + b^{[3]}$, $A^{[3]} = \sigma(Z^{[3]}) = \hat{Y}$
反向传播:
- 计算 $dA^{[3]} = -\frac{Y}{A^{[3]}} + \frac{1 - Y}{1 - A^{[3]}}$
逐层反向计算:
- $dZ^{[3]} = dA^{[3]} \odot \sigma’(Z^{[3]})$
- $dW^{[3]} = \frac{1}{m} dZ^{[3]} (A^{[2]})^\top$, $db^{[3]} = \frac{1}{m} \sum dZ^{[3]}$
- $dA^{[2]} = (W^{[3]})^\top dZ^{[3]}$
- …… 依此类推至第 1 层
⚠️ 注意:通常不需要 $dA^{[0]}$,可丢弃。
五、关键要点总结
| 模块 | 关键点 |
|---|---|
| 前向传播 | 从输入 $X$ 开始,逐层计算 $Z^{[l]}$ 和 $A^{[l]}$,缓存 $Z^{[l]}$ 供反向使用 |
| 反向传播 | 从损失函数出发,利用链式法则逐层回传梯度,计算 $dW^{[l]}, db^{[l]}$ |
| 激活函数导数 | 必须知道 $g^{[l]’}(Z^{[l]})$,例如: - ReLU: $g’(z) = \mathbb{1}_{z > 0}$ - Sigmoid: $\sigma’(z) = \sigma(z)(1 - \sigma(z))$ |
| 向量化 | 所有操作均支持批量处理(m 个样本),效率更高 |
| 缓存设计 | 前向时需缓存 $Z^{[l]}$(有时也包括 $A^{[l-1]}$),反向时直接调用 |
六、学习建议(来自吴恩达)
“如果你觉得这些公式很抽象,不要担心。当你动手完成编程作业时,一切会变得清晰。反向传播的数学推导确实复杂,但你只需要记住那 四个核心方程 就能正确实现。”
- 动手实践比死记硬背更重要。
- 深度学习的“魔法”往往来自 数据 而非代码长度。
- 即使专家也会对模型成功感到惊讶——因为数据蕴含了巨大信息量。
附:常用激活函数及其导数(供参考)
| 激活函数 $g(z)$ | 导数 $g’(z)$ |
|---|---|
| Sigmoid: $\sigma(z) = \frac{1}{1 + e^{-z}}$ | $\sigma(z)(1 - \sigma(z))$ |
| ReLU: $g(z) = \max(0, z)$ | $\mathbb{1}_{z > 0}$ |
| Tanh: $g(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}}$ | $1 - g(z)^2$ |
本文由作者按照 CC BY 4.0 进行授权