在 线性分类器 中, 给出了预测分数。训练时还要回答一个问题:预测错了,究竟该改 的哪个元素,改多少?反向传播就是用链式法则高效计算这个答案;它不是另一种与梯度下降并列的优化器。
先看一个标量
设 ,,。当 时,链式法则给出:
若 ,ReLU 在该点的导数为 0,这条路径就不给 传递梯度;在 处需约定一个次梯度,框架通常自行处理。梯度是局部斜率,更新 才是沿负梯度方向移动,其中 是学习率。
两层网络为什么要“反着算”
令隐藏层 ,输出 。前向计算先得到 再得到 ;反向计算从损失对 的导数出发,先求 的梯度,再通过 把误差信号传回 ,最后求 。中间结果会被多个参数复用,不必为每个权重单独重算整条导数链。
可以用微小扰动检查手算梯度。下例只验证单个标量,不适合用有限差分训练整个网络:
def loss(w, x=2.0, y=1.0):
a = max(0.0, w * x)
return 0.5 * (a - y) ** 2
w, eps = 0.75, 1e-5
numerical = (loss(w + eps) - loss(w - eps)) / (2 * eps)
analytic = (w * 2.0 - 1.0) * 2.0 # 此处 w*x > 0
print(numerical, analytic) # 都接近 1.0
数值梯度是调试工具:太大的 eps 近似不准,太小又会受浮点误差影响。实际训练由自动微分记录张量运算图并应用链式法则。PyTorch 训练循环 会把 backward() 与 optimizer.step() 分开看,避免把“求梯度”和“更新参数”混为一谈。
参考:PyTorch 自动微分教程。