反向传播

反向传播是神经网络训练的核心算法,通过计算损失函数对每个参数的梯度,实现参数的高效更新。

共 3 篇文章·阅读时间:约40分钟

01梯度下降

梯度下降是优化的基础算法,通过沿梯度相反方向移动来最小化目标函数。它是训练神经网络的核心方法。

梯度概念

梯度是多元函数在某一点的最大上升方向。沿梯度相反方向移动,函数值下降最快。

梯度下降更新公式

θ = θ - η · ∇J(θ)

  • θ:模型参数
  • η:学习率(step size)
  • ∇J(θ):损失函数关于参数的梯度

梯度下降变体

批量梯度下降 (BGD)

公式:使用全部数据计算梯度
优点:收敛稳定,方向准确
缺点:计算量大,无法处理大数据

随机梯度下降 (SGD)

公式:每次使用一个样本计算梯度
优点:速度快,能跳出局部最优
缺点:收敛不稳定,震荡严重

小批量梯度下降 (Mini-batch SGD)

公式:每次使用 batch_size 个样本
优点:平衡速度和稳定性,GPU 高效并行
缺点:需要选择合适的 batch size

学习率的影响

  • 过大:震荡发散,无法收敛
  • 过小:收敛太慢,容易陷入局部最优
  • 适中:稳定收敛

02链式法则

链式法则是微积分的核心,用于计算复合函数的导数。反向传播正是链式法则在神经网络中的应用。

链式法则原理

如果 y = f(g(x)),则链式法则给出:

dy/dx = (dy/dg) · (dg/dx) = f'(g(x)) · g'(x)

在神经网络中,每一层的输出都是下一层输入的函数,反向传播从输出层开始, 逐层计算梯度并向前传播。

反向传播公式

对于全连接层 y = f(Wx + b),反向传播计算损失 L 对参数 W, b, x 的梯度:

输出层反向传播

∂L/∂y = 上游梯度

∂L/∂W = ∂L/∂y · yT

∂L/∂b = ∂L/∂y

隐藏层反向传播

∂L/∂x = WT · ∂L/∂y

传递给下一层的上游梯度

梯度消失与梯度爆炸

  • 梯度消失:多层连乘导致梯度趋近于0,难以训练深层网络
  • 梯度爆炸:梯度过大导致参数更新过大,网络不稳定
  • 解决方案:残差连接、Batch Normalization、LSTM/GRU、梯度裁剪

03计算图

计算图将神经网络表示为有向无环图,清晰地展示了前向传播和反向传播的计算流程。

计算图概念

计算图将复杂的计算分解为简单的基本操作(如加法、乘法、激活函数), 每个节点表示一个操作或变量。

示例:z = (w * x + b) * 2

节点:w, x, b (输入变量)
操作:mul, add, mul
前向:w → mul → (w*x) → add → (w*x+b) → mul → z
反向:z.grad → mul ← (w*x+b).grad → add ← (w*x).grad → mul ← w.grad, x.grad

自动微分

自动微分利用计算图自动计算导数,结合了符号计算和数值计算的优点。

前向模式

从输入到输出计算导数,适合少量输入、多个输出的情况。

反向模式

从输出到输入计算梯度,适合多个输入、少量输出的情况(神经网络正是这种情况)。
几乎所有深度学习框架(PyTorch、TensorFlow)都使用反向模式自动微分。

PyTorch 自动微分示例

import torch

x = torch.tensor([1.0, 2.0], requires_grad=True)
y = (x * 2 + 1).sum()  # y = 2*(1+2) + 2 = 8

y.backward()  # 反向传播
print(x.grad)  # tensor([2., 2.])

反向传播算法步骤

  1. 前向传播:输入通过各层计算,得到输出和损失
  2. 初始化:损失对输出的梯度为1
  3. 反向传播:从输出层开始,逐层计算梯度并传播
  4. 参数更新:使用计算得到的梯度更新参数
----