Ch06 神经网络基础
反向传播 (Backpropagation)
一句话理解
反向传播是神经网络的学习引擎——把输出端的误差沿着网络逐层传回去,算出每个参数对误差的”贡献”,然后让参数朝减小误差的方向更新。
零基础理解
做一道菜,味道不对(误差)。你从最后一步开始往前追溯:是不是盐放多了?是不是火候不对?是不是食材比例有问题?每往前追一步,你就知道该调整什么、调整多少。反向传播做的就是这件事——从输出层往回,逐层追究每个参数的责任。
核心原理
链式法则 (Chain Rule)
反向传播的本质是链式法则的重复应用。
如果 ,则:
在神经网络中, 是损失, 是某个参数,中间的每一层都是一个函数。反向传播从输出层开始,逐层计算梯度,直到输入层。
计算图 (Computation Graph)
神经网络可以表示为一张有向无环图(DAG):
输入 x ──→ 权重 W1 ──→ 激活 ──→ 权重 W2 ──→ 激活 ──→ 输出 ŷ ──→ 损失 L
前向:x → W1 → a1 → W2 → a2 → ŷ → L
反向:∂L/∂ŷ → ∂L/∂W2 → ∂L/∂a1 → ∂L/∂W1
每个节点存储两部分信息:
- 前向值:计算输出
- 反向梯度:计算局部梯度,乘以从后面传来的梯度,传给前面的节点
前向传播 vs 反向传播
| 维度 | 前向传播 (Forward) | 反向传播 (Backward) |
|---|---|---|
| 方向 | 输入 → 输出 | 输出 → 输入 |
| 计算内容 | 激活值 | 梯度 |
| 依赖 | 当前层的输入 | 后面层的梯度 + 当前层的前向值 |
| 时间复杂度 | O(参数数量) | O(参数数量) |
| 空间复杂度 | O(层数 × 层宽度) | O(层数 × 层宽度) 需存储前向中间值 |
| 目的 | 得到预测 | 得到参数梯度用于更新 |
一个具体的反向传播例子
考虑一个最简单的两层网络:
输入: x = 2
隐藏层: h = w1 · x = 3 · 2 = 6, a = ReLU(6) = 6
输出层: ŷ = w2 · a = 0.5 · 6 = 3
真实值: y = 1
损失: L = (ŷ - y)² = (3 - 1)² = 4
反向传播:
| 步骤 | 计算 | 结果 |
|---|---|---|
| 1. ∂L/∂ŷ | 2(ŷ - y) = 2(3 - 1) | 4 |
| 2. ∂L/∂w2 | ∂L/∂ŷ · ∂ŷ/∂w2 = 4 · 6 | 24 |
| 3. ∂L/∂a | ∂L/∂ŷ · ∂ŷ/∂a = 4 · 0.5 | 2 |
| 4. ∂L/∂h | ∂L/∂a · ∂a/∂h = 2 · 1 (ReLU导数, x>0) | 2 |
| 5. ∂L/∂w1 | ∂L/∂h · ∂h/∂w1 = 2 · 2 | 4 |
然后用梯度下降更新:w1’ = w1 - lr×4, w2’ = w2 - lr×24。
自动微分 (Autograd)
2026 年:框架自动处理
现代深度学习框架(PyTorch/TensorFlow/JAX)通过自动微分自动完成反向传播,开发者不需要手写梯度计算。
| 微分方式 | 做法 | 误差 | 速度 | 使用场景 |
|---|---|---|---|---|
| 手动微分 | 手算导数公式 | 易出错 | 最快 | 简单函数 |
| 数值微分 | 有截断误差 | 极慢 | 验证梯度 | |
| 符号微分 | 代数推导导数表达式 | 精确 | 中 | 表达式膨胀问题 |
| 自动微分(正向) | 沿计算图前向传播对偶数 | 精确 | O(n) | 输入维度小 |
| 自动微分(反向) | 沿计算图反向传播梯度 | 精确 | O(n) | 输出维度小(深度学习) |
PyTorch Autograd 示例
import torch
x = torch.tensor([2.0], requires_grad=True)
w1 = torch.tensor([3.0], requires_grad=True)
w2 = torch.tensor([0.5], requires_grad=True)
h = w1 * x
a = torch.relu(h)
y_pred = w2 * a
loss = (y_pred - 1.0) ** 2
loss.backward() # 自动计算所有 requires_grad=True 的张量的梯度
print(w1.grad) # tensor([4.])
print(w2.grad) # tensor([24.])
为什么反向传播是深度学习的基石
| 原因 | 说明 |
|---|---|
| 高效性 | 一次反向传播计算所有参数的梯度,而非逐参数计算 |
| 可扩展 | 时间复杂度与参数数量线性相关,支持百亿参数模型 |
| 自动化 | 框架自动处理,开发者只需定义前向计算 |
| 端到端 | 从输入到输出整个模型可联合优化 |
常见问题
梯度消失 (Vanishing Gradient)
当激活函数(Sigmoid/Tanh)的导数在饱和区接近 0,深层网络的梯度逐层相乘后指数衰减,浅层参数几乎不更新。
解决方案:ReLU/GELU、残差连接、BatchNorm/LayerNorm。
梯度爆炸 (Exploding Gradient)
当权重初始化过大或网络过深,梯度逐层相乘后指数增长,参数更新幅度过大,训练崩溃。
解决方案:梯度裁剪(Gradient Clipping)、好的权重初始化(Xavier/He)、归一化层。
梯度消失 vs 梯度爆炸
| 现象 | 梯度大小 | 参数更新 | 训练表现 |
|---|---|---|---|
| 梯度消失 | 趋近于 0 | 几乎不更新 | Loss 不下降,浅层学不到 |
| 梯度爆炸 | 趋近于 +∞ | 跳动过大 | Loss 震荡或 NaN |
| 正常 | 适中 | 平稳 | Loss 稳步下降 |
2026 年视角
反向传播的基础原理从 1986 年(Rumelhart et al.)至今未变,但 2026 年的实践已经完全不同:
| 年代 | 反向传播实践 |
|---|---|
| 1986 | 手写梯度,单层网络 |
| 2012 | 手动实现卷积反向传播,框架初现 |
| 2016 | PyTorch/TensorFlow 自动微分 |
| 2020 | 混合精度训练(FP16+FP32),梯度缩放 |
| 2024 | FSDP/ZeRO 分布式反向传播,梯度检查点 |
| 2026 | 全自动,分布式训练下的梯度同步与通信优化 |
2026 年开发者视角:写 loss.backward() 就够了,框架处理一切。但理解原理对调试(Bad NaN, 梯度异常)仍然至关重要。
相关笔记
- 第6章 · 神经网络基础 — 反向传播在神经网络训练流程中的位置
- 梯度下降 (Gradient Descent) — 反向传播算出梯度后,梯度下降负责更新参数
- ReLU 与激活函数 (Activation Functions) — 激活函数选择如何影响梯度传播
- 第9章 · Transformer 架构精讲 — Transformer 中的残差连接如何缓解梯度消失
- LSTM 长短期记忆网络 (Long Short-Term Memory) — LSTM 的门控机制如何缓解梯度消失
来源
- Rumelhart, Hinton & Williams, “Learning representations by back-propagating errors” (1986) — https://www.nature.com/articles/323533a0
- Goodfellow et al., “Deep Learning”, Chapter 6.5 — https://www.deeplearningbook.org/
- PyTorch Autograd Documentation — https://pytorch.org/docs/stable/autograd.html
- 3Blue1Brown, “Backpropagation calculus” — https://www.3blue1brown.com/lessons/backpropagation-calculus
- Baydin et al., “Automatic Differentiation in Machine Learning: a Survey” (2018) — https://arxiv.org/abs/1502.05767
关联13
知识图谱反向链接8
局部图谱 · 点节点跳转