mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7mobile wallpaper 8mobile wallpaper 9mobile wallpaper 10mobile wallpaper 11mobile wallpaper 12mobile wallpaper 13
3530 字
10 分鐘
反向传播 损失函数 优化算法
2026-06-03

第 4 章 反向传播、损失函数与优化算法#

4.1 学习目标#

  1. 理解损失函数如何把“预测好坏”转成可优化的标量目标。
  2. 理解反向传播的本质是链式法则在计算图上的高效实现。
  3. 掌握梯度下降、动量、RMSProp、Adam 等常见优化器。
  4. 理解学习率、批量大小、梯度爆炸/消失、局部极小值与鞍点。
  5. 能写出一个完整的神经网络训练循环。

能力矩阵

能力域入门进阶熟练
损失函数知道 MSE / CE理解概率解释能为任务选择合适损失
反向传播会背公式理解链式法则能手推两层网络梯度
优化算法会用 SGD会用 Momentum / Adam能分析收敛与震荡
调参会改学习率会调 batch size能定位梯度问题

4.2 损失函数的作用#

损失函数衡量模型预测和真实标签之间的差距。训练神经网络时,目标就是最小化损失:

minθL(θ)\min_{\theta} L(\theta)

如果没有损失函数,模型就不知道“什么叫做更好”。


4.3 常见损失函数#

4.3.1 均方误差#

适用于回归:

LMSE=1ni=1n(y^iyi)2L_{MSE} = \frac{1}{n}\sum_{i=1}^{n}(\hat{y}_i - y_i)^2

优点:简单、可导。缺点:对异常值敏感。

4.3.2 二分类交叉熵#

L=[ylogy^+(1y)log(1y^)]L = -\left[y\log\hat{y} + (1-y)\log(1-\hat{y})\right]

适用于二分类问题。

4.3.3 多分类交叉熵#

若真实标签为 one-hot 向量 yy,预测概率为 y^\hat{y}

L=c=1Cyclogy^cL = -\sum_{c=1}^{C} y_c \log \hat{y}_c

通常结合 softmax 使用。

4.3.4 Hinge Loss#

常见于支持向量机和部分分类模型。

4.3.5 正则项#

总损失往往是数据损失加上正则项:

Ltotal=Ldata+λR(θ)L_{total} = L_{data} + \lambda R(\theta)

常见正则项包括 L2、L1、稀疏约束等。


4.4 计算图与反向传播#

4.4.1 计算图#

神经网络可以表示为一个有向无环图(DAG):

x -> linear -> relu -> linear -> softmax -> loss

每个节点对应一个操作,每条边对应数据流。

4.4.2 反向传播思想#

反向传播就是:

  • 从损失节点出发;
  • 按逆拓扑顺序把梯度传回去;
  • 每个局部操作只计算“输出变化对输入变化”的影响;
  • 再把局部梯度连乘起来。

4.4.3 链式法则的递归应用#

若:

L=L(a),a=a(z),z=z(w)L = L(a), \quad a = a(z), \quad z = z(w)

则:

Lw=Laazzw\frac{\partial L}{\partial w} = \frac{\partial L}{\partial a} \cdot \frac{\partial a}{\partial z} \cdot \frac{\partial z}{\partial w}

这就是反向传播的核心。


4.5 典型层的梯度#

4.5.1 线性层#

若:

Z=XW+bZ = XW + b

则梯度通常为:

LW=XTLZ\frac{\partial L}{\partial W} = X^T \frac{\partial L}{\partial Z}LX=LZWT\frac{\partial L}{\partial X} = \frac{\partial L}{\partial Z} W^TLb=batchLZ\frac{\partial L}{\partial b} = \sum_{batch} \frac{\partial L}{\partial Z}

4.5.2 ReLU#

ReLU(x)=max(0,x)\text{ReLU}(x) = \max(0, x)

其导数为:

ddxReLU(x)={1,x>00,x<0\frac{d}{dx}\text{ReLU}(x) = \begin{cases}1, & x > 0 \\ 0, & x < 0\end{cases}

4.5.3 Sigmoid#

σ(x)=11+ex\sigma(x) = \frac{1}{1+e^{-x}}

导数:

σ(x)=σ(x)(1σ(x))\sigma'(x) = \sigma(x)(1-\sigma(x))

4.5.4 Softmax 与交叉熵#

Softmax + 交叉熵常被合并为一个更稳定的损失形式。对 logits 的梯度最终会简化为:

Lzi=y^iyi\frac{\partial L}{\partial z_i} = \hat{y}_i - y_i

这也是它在分类任务中非常常用的原因。


4.6 优化算法#

4.6.1 批量梯度下降#

θθηL(θ)\theta \leftarrow \theta - \eta \nabla L(\theta)

优点:稳定;缺点:慢、计算重。

4.6.2 随机梯度下降#

每次用一个样本更新参数。优点是快,缺点是噪声大。

4.6.3 小批量梯度下降#

实际训练中最常见。它在稳定性和效率之间取得平衡。

4.6.4 Momentum#

动量法引入速度项:

vt=βvt1+(1β)gtv_t = \beta v_{t-1} + (1-\beta)g_tθt=θt1ηvt\theta_t = \theta_{t-1} - \eta v_t

它可以加速方向一致的更新,抑制震荡。

4.6.5 RMSProp#

对梯度平方做滑动平均,按历史尺度自适应缩放学习率。

4.6.6 Adam#

Adam 结合了动量与自适应学习率,是最常见的默认优化器之一。

一阶矩估计 + 二阶矩估计 + 偏差修正

4.7 学习率与收敛#

4.7.1 学习率过大#

  • 损失震荡
  • 不收敛
  • 训练发散

4.7.2 学习率过小#

  • 收敛非常慢
  • 容易卡在平台期

4.7.3 学习率策略#

  • Step decay
  • Cosine decay
  • Warmup
  • Reduce on plateau

4.8 梯度问题#

4.8.1 梯度消失#

常发生在:

  • 深层网络
  • Sigmoid / Tanh 饱和区
  • 不合理初始化

表现:前面层几乎学不动。

4.8.2 梯度爆炸#

梯度不断乘大,导致参数更新过猛。常见缓解方法:

  • 梯度裁剪
  • 更小学习率
  • 合理初始化
  • 使用归一化层

4.8.3 局部极小值与鞍点#

现代深度学习中,更多时候困难来自鞍点、平坦区和病态曲率,而不是传统意义上的“坏局部最优”。


4.9 从零写训练循环#

for epoch in range(num_epochs):
for X_batch, y_batch in dataloader:
logits = model(X_batch)
loss = criterion(logits, y_batch)
optimizer.zero_grad()
loss.backward()
optimizer.step()

训练循环的关键是:

  1. 前向传播;
  2. 计算损失;
  3. 清空梯度;
  4. 反向传播;
  5. 参数更新。

4.10 常见误区#

  1. 以为 loss 越小就一定越好。实际上还要看验证集表现。
  2. 以为 Adam 一定优于 SGD。实际上不同任务表现会不同。
  3. 以为梯度越大越好。实际上梯度过大可能导致发散。
  4. 以为反向传播是在“倒着再算一遍”。实际上它是共享中间结果的高效链式求导。
  5. 以为优化器可以替代好结构和好数据。实际上它只能改善训练过程,不能凭空创造信息。

4.11 反向传播深度推导与数值技巧#

本节以更细粒度推导反向传播,讨论数值稳定性、梯度校验、以及实际工程中常见的问题与解决方案。

4.11.1 矩阵形式的反向传播回顾#

对于一层线性变换 Z=XW+bZ = XW + b,假设上游梯度为 LZ=G\frac{\partial L}{\partial Z} = G,则:

LW=XTG,Lb=i=1NGi,:,LX=GWT\frac{\partial L}{\partial W} = X^T G,\qquad \frac{\partial L}{\partial b} = \sum_{i=1}^N G_{i,:},\qquad \frac{\partial L}{\partial X} = G W^T

这里 XRN×dX\in\mathbb{R}^{N\times d}WRd×hW\in\mathbb{R}^{d\times h}GRN×hG\in\mathbb{R}^{N\times h},所有求和都在 batch 维度展开。

把每一层的局部导数写成矩阵形式有利于向量化实现和 GPU 加速。

4.11.2 Softmax + Cross-Entropy 的渐变推导(数值稳定版)#

设 logits 为 zRCz\in\mathbb{R}^C,softmax 输出为 y^i=ezijezj\hat{y}_i=\frac{e^{z_i}}{\sum_j e^{z_j}},交叉熵为 L=iyilogy^iL=-\sum_i y_i\log\hat{y}_i

推导可得:

Lzi=y^iyi\frac{\partial L}{\partial z_i}=\hat{y}_i-y_i

注意:在实现时应该先做数值稳定化:令 z~=zmaxjzj\tilde{z}=z-\max_j z_j,再计算 ez~e^{\tilde{z}},以避免指数溢出。

此外,当标签 yy 为整数类别索引(而非 one-hot)时,框架内置的 CrossEntropyLoss 通常会把 softmax 与负对数概率合并为一项来提高稳定性与效率。

4.11.3 反向传播的递归公式与自动微分#

自动微分(AD)库把每个原子操作的局部导数保存在计算图中,反向传播本质是对计算图做逆拓扑遍历,把局部梯度按链式法则连乘起来。

对任意复合函数 f=ghf=g\circ h,有:

Lx=Lgghhx\frac{\partial L}{\partial x}=\frac{\partial L}{\partial g}\frac{\partial g}{\partial h}\frac{\partial h}{\partial x}

在实际实现中要注意中间变量的缓存(例如前向传播中的激活值),以免在反向传播时重复计算导致性能下降。

4.11.4 梯度检验(Gradient Checking)#

在手写反向传播实现时,常用有限差分来检验梯度的正确性:

LθL(θ+ϵ)L(θϵ)2ϵ\frac{\partial L}{\partial \theta} \approx \frac{L(\theta + \epsilon)-L(\theta - \epsilon)}{2\epsilon}

实践建议:对少量参数做数值梯度检验,选用 ϵ=105\epsilon=10^{-5}10610^{-6},并比较相对误差:

extrel_err=gnumganalyticalmax(1,gnum,ganalytical) ext{rel\_err}=\frac{|g_{num}-g_{analytical}|}{\max(1, |g_{num}|, |g_{analytical}|)}

若相对误差在 10610^{-6}~10410^{-4} 之间通常可接受;若更大,说明反向传播实现存在问题。

4.11.5 数值稳定性与常见数值陷阱#

  • exp 溢出:使用 shifted logits 技术处理 softmax。
  • log(0) 问题:在计算交叉熵时对概率截断(添加 eps)。
  • 精度损失:长序列累积小数误差可能导致反向传播不稳定,建议使用双精度做验证。
  • 梯度下溢/上溢:监控梯度范数,必要时启用梯度裁剪。

4.12 优化器详解:从 SGD 到高级自适应方法#

本节对常用优化算法给出更完整的数学表达、实现细节和工程建议,并介绍一些现代训练中常用的变体。

4.12.1 SGD 与动量的推导#

标准 SGD:

hetat+1=θtηgt heta_{t+1} = \theta_t - \eta g_t

动量(Momentum):

vt=γvt1+ηgtv_t = \gamma v_{t-1} + \eta g_thetat+1=θtvt heta_{t+1} = \theta_t - v_t

其中 γ\gamma 通常取 0.9 左右,动量可以看作对历史梯度的指数加权平均,从而使更新方向更加平滑。

4.12.2 Nesterov 加速梯度#

Nesterov Momentum 要点是先沿着动量方向做一个预测,再计算梯度:

vt=γvt1+ηf(θtγvt1)v_t = \gamma v_{t-1} + \eta \nabla f(\theta_t - \gamma v_{t-1})hetat+1=θtvt heta_{t+1} = \theta_t - v_t

实际效果是在鞍点和曲率变化处能带来更快收敛。

4.12.3 RMSProp#

设平方梯度的一阶矩估计为 sts_t

st=βst1+(1β)gt2s_t = \beta s_{t-1} + (1-\beta) g_t^2hetat+1=θtηst+ϵgt heta_{t+1} = \theta_t - \frac{\eta}{\sqrt{s_t + \epsilon}} g_t

其中 ϵ\epsilon 防止除零。

4.12.4 Adam(含偏差修正)#

Adam 同时维护一阶矩估计 mtm_t 和二阶矩估计 vtv_t

mt=β1mt1+(1β1)gtm_t = \beta_1 m_{t-1} + (1-\beta_1) g_tvt=β2vt1+(1β2)gt2v_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2

偏差修正:

m^t=mt1β1t,v^t=vt1β2t\hat{m}_t = \frac{m_t}{1-\beta_1^t},\qquad \hat{v}_t = \frac{v_t}{1-\beta_2^t}

更新规则:

hetat+1=θtηm^tv^t+ϵ heta_{t+1} = \theta_t - \eta \frac{\hat{m}_t}{\sqrt{\hat{v}_t}+\epsilon}

常用超参:β1=0.9,β2=0.999,ϵ=108\beta_1=0.9,\beta_2=0.999,\epsilon=10^{-8}

注意:使用 Adam 时如果同时使用权重衰减(weight decay),推荐使用 AdamW(把 weight decay 与梯度分开处理)以获得更符合正则化语义的行为。

4.12.5 Adam 的实际问题与改进#

  • Adam 在某些任务上导致泛化不如 SGD。(可尝试在训练后用 SGD 微调)
  • 学习率过大时,Adam 也会出现不稳定;建议使用学习率热身(warmup)+衰减。
  • RAdam、AdaBound、AdamW 等是对 Adam 的多种改进,其中 AdamW 把 L2 正则化改为显式 weight decay,是实践中的优选。

4.12.6 二阶方法(概念与适用场景)#

Newton 方法使用 Hessian HH

hetat+1=θtH1gt heta_{t+1} = \theta_t - H^{-1} g_t

直接使用 Hessian 代价巨大,但近似二阶信息(例如 L-BFGS、K-FAC)在小样本或精调阶段有时效果很好。深度学习中更常用的折衷是利用二阶信息做学习率调整或预调度。


4.13 正则化与权重衰减的细节#

在实现上要区分 L2 正则化(把参数加入损失)与 weight decay(在参数更新阶段对参数做衰减),二者在 Adam 等自适应优化器下表现不同。

4.13.1 L2 正则与 weight decay 的数学差异#

L2 正则通过损失项 λθ2\lambda\|\theta\|^2 引入额外梯度 2λθ2\lambda\theta;weight decay 则在更新时把参数乘以 (1ηλ)(1-\eta\lambda)。在 SGD 情形两者等价,但在 Adam 等自适应优化器中并不严格等价,故推荐使用 AdamW。

4.13.2 Dropout 与 BatchNorm 的正则效应#

Dropout 在训练时随机丢弃神经元,具有隐式模型平均的效果;BatchNorm 通过归一化稳定内部协变量偏移,两者可以结合使用,但 BatchNorm 在小 batch 场景下表现可能欠佳。


4.14 初始化、归一化与梯度流的工程注意事项#

合理初始化可以直接缓解梯度消失/爆炸问题。常见的 Xavier(Glorot)与 He 初始化都基于保持前后层激活方差不变的思想。

4.14.1 Xavier 初始化#

对于 tanh 或 sigmoid,Xavier 初始化取:

Var(w)=2nin+noutVar(w)=\frac{2}{n_{in}+n_{out}}

4.14.2 He 初始化#

对于 ReLU 系列,He 初始化常取:

Var(w)=2ninVar(w)=\frac{2}{n_{in}}

4.14.3 BatchNorm 的梯度影响#

BatchNorm 在训练时会改变梯度传播路径,常常允许用更大的学习率并加速收敛。但它也引入了训练和推理状态的不一致(使用 batch 统计 vs 全量统计),需要谨慎处理 moving mean/var 的更新。


4.15 学习率调度与 Warmup 的实践技巧#

学习率调度是深度学习中最常用的工具之一:先快速探索参数空间,再慢慢收敛到谷底。Warmup 能在训练初期缓解自适应优化器的震荡问题。

常见组合:Warmup + CosineAnnealing;Warmup + StepDecay;Warmup + ReduceOnPlateau。


4.16 训练稳定性诊断清单(工程手册)#

当训练不稳定或不收敛时,请按下面清单逐项排查:

  1. 数据是否正确(标签、归一化、batch)?
  2. 模型输出是否包含 NaN 或 Inf?
  3. 梯度范数是否突然爆炸?(日志记录 ||g||
  4. 学习率是否合适?尝试降 10 倍。
  5. 是否遗漏 optimizer.zero_grad()
  6. 激活函数是否选择合理?(Sigmoid 容易饱和)
  7. 权重初始化是否合理?
  8. 是否使用了过强的数据增强或正则?
  9. 检查 BatchNorm 的 batch size 是否太小。
  10. 用小数据集(如 100 个样本)测试能否过拟合。

4.17 进阶优化方法速览(便于阅读)#

  • AdamW:修正 weight decay 实现,更合适自适应优化器。
  • RAdam:修正 Adam 在训练初期造成的不稳定性。
  • Lookahead:在基础优化器上叠加慢速/快速权重同步策略以增强鲁棒性。
  • SAM(Sharpness-Aware Minimization):同时优化损失值和 loss 的平滑性以获得更好泛化。
  • LARS / LAMB:用于大 batch 或大模型(如 BERT、ViT)以平衡层间学习率。

4.18 实战示例:从零实现一个两层网络的反向传播(伪代码)#

# 简化示例:X: (N, D), W1: (D, H), b1: (H,), W2: (H, C), b2: (C,)
def forward(X, W1, b1, W2, b2):
Z1 = X.dot(W1) + b1
A1 = relu(Z1)
Z2 = A1.dot(W2) + b2
logits = Z2
probs = softmax(logits)
return Z1, A1, Z2, probs
def backward(X, y, Z1, A1, Z2, probs, W2):
N = X.shape[0]
# dZ2 = probs - one_hot(y)
dZ2 = probs
dZ2[range(N), y] -= 1
dZ2 /= N
dW2 = A1.T.dot(dZ2)
db2 = np.sum(dZ2, axis=0)
dA1 = dZ2.dot(W2.T)
dZ1 = dA1 * (Z1 > 0).astype(float)
dW1 = X.T.dot(dZ1)
db1 = np.sum(dZ1, axis=0)
return dW1, db1, dW2, db2

这段伪代码演示了前向与反向的主要步骤,以及 softmax+cross-entropy 的梯度如何在实践中实现(用减一的技巧把 one-hot 处理掉以节省计算)。


4.19 本章小结#

本章从反向传播的数学基础出发,补充了数值稳定性、优化器实现细节、初始化与正则化差异、以及工程中的排错清单。掌握这些内容能显著提高你在训练深度网络时的效率与成功率。


4.20 课后练习(扩展)#

  1. 手动实现两层网络的前向与反向传播,并用数值梯度检验其正确性。
  2. 比较 Adam 和 SGD 在同一数据集上的泛化差异:分别记录训练曲线与验证曲线并分析。
  3. 实验不同的初始化(Xavier、He)对深层网络收敛速度的影响。
  4. 用小样本做过拟合测试,练习调参流程:减小模型/增加正则/调整学习率。
  5. 实现梯度裁剪并观察是否能缓解梯度爆炸问题。

4.21 参考资料与延伸阅读#

  • Kingma, Diederik, and Jimmy Ba. “Adam: A Method for Stochastic Optimization.”
  • Ioffe, Sergey, and Christian Szegedy. “Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift.”
  • Loshchilov, Ilya, and Frank Hutter. “Decoupled Weight Decay Regularization.”(AdamW)
  • Wilson, Ashia C., et al. “The Marginal Value of Adaptive Gradient Methods in Machine Learning.”
  • Papers on RAdam, Lookahead, SAM for practical optimizer variants.
分享

如果這篇文章對你有幫助,歡迎分享給更多人!

反向传播 损失函数 优化算法
https://lemusakuya.com/posts/study-notes/neural-networks/04_反向传播_损失函数_优化算法/
作者
レム・咲く夜
發布於
2026-06-03
許可協議
CC BY-NC-SA 4.0

部分資訊可能已經過時

目錄