反向传播
反向传播是神经网络训练的核心算法,通过计算损失函数对每个参数的梯度,实现参数的高效更新。
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
- 反向传播:从输出层开始,逐层计算梯度并传播
- 参数更新:使用计算得到的梯度更新参数