共计 1562 个字符,预计需要花费 4 分钟才能阅读完成。
反向传播算法是深度学习模型训练的核心引擎,它通过高效计算梯度来指导参数更新。理解反向传播不仅需要掌握链式法则的数学原理,更要能够将其转化为实际代码实现。本文将从理论推导到 PyTorch 实战,带你完整走通这个关键流程。

一、反向传播的数学原理
1. 计算图与链式法则
计算图是理解反向传播最直观的工具。以前馈神经网络为例:
- 输入数据
x经过线性变换W1*x + b1 - 通过激活函数如
ReLU得到隐藏层输出h1 - 继续传播直到输出层
y_pred - 计算损失
L = loss(y_pred, y_true)
反向传播时,梯度从损失函数开始,沿着计算图逆向传播。例如求 dL/dW1 需要链式法则:
dL/dW1 = (dL/dy_pred) * (dy_pred/dh2) * (dh2/dh1) * (dh1/dW1)
2. 矩阵求导的维度分析
实际编程中必须注意维度匹配:
- 标量对向量求导(如
dL/db)结果与原向量同维 - 向量对矩阵求导(如
dh/dW)会产生三维张量 - 实践中通常使用批量数据,需要考虑 batch 维度的聚合
二、PyTorch 实现实战
1. 实现双层 MLP
import torch
import torch.nn as nn
class MLP(nn.Module):
def __init__(self, input_dim=784, hidden_dim=128, output_dim=10):
super().__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, hidden_dim)
self.fc3 = nn.Linear(hidden_dim, output_dim)
self.relu = nn.ReLU()
def forward(self, x):
h1 = self.relu(self.fc1(x))
h2 = self.relu(self.fc2(h1))
return self.fc3(h2)
2. 梯度验证技巧
使用 hook 机制检查中间层梯度:
def print_grad(grad):
print(f'Gradient norm: {grad.norm().item():.4f}')
model = MLP()
x = torch.randn(32, 784)
grad_handles = []
for param in model.parameters():
handle = param.register_hook(print_grad)
grad_handles.append(handle)
# 训练结束后记得移除 hook
for handle in grad_handles:
handle.remove()
三、常见问题与解决方案
1. 梯度消失 / 爆炸
识别方法:
– 监控各层梯度范数
– 出现 NaN 或极大值通常是爆炸
解决方案:
– 使用梯度裁剪(torch.nn.utils.clip_grad_norm_)
– 改用残差连接
– 调整初始化方法(如 He 初始化)
2. 自定义激活函数验证
实现新激活函数时务必验证梯度:
class MyActivation(nn.Module):
def forward(self, x):
return x * torch.sigmoid(x)
# 必须手动实现反向传播
def backward(self, grad_output):
x = self.saved_tensors
sig_x = torch.sigmoid(x)
return grad_output * (sig_x + x * sig_x * (1 - sig_x))
四、思考题
- 残差连接的反向传播如何处理恒等映射分支?
- Hessian 矩阵在优化算法中扮演什么角色?
- 自动微分相比符号微分有哪些优势和局限?
希望这篇笔记能帮助你建立完整的反向传播知识体系。在实际项目中,建议结合 TensorBoard 等工具可视化梯度流动,这是调试模型的利器。
正文完
