跳转至

04 - 损失函数与优化

损失函数

损失曲面可视化

图注:损失曲面可视化 - 展示了神经网络训练过程中的损失地形,帮助理解优化算法如何在复杂的损失景观中寻找最优解

重要性: ⭐⭐⭐⭐⭐ 实用度: ⭐⭐⭐⭐⭐ 学习时间: 4小时 必须掌握: 是


为什么学这一章?

损失函数和优化算法是训练神经网络的核心。理解它们能帮助你: - 知道如何衡量模型的预测好坏 - 选择合适的优化策略加速收敛 - 调试训练过程中的问题 - 提升模型性能

学完这一章,你将能够: - ✅ 理解各种损失函数的适用场景 - ✅ 掌握梯度下降及其变种 - ✅ 选择合适的优化器和学习率 - ✅ 诊断和解决优化问题


📖 损失函数

什么是损失函数?

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    损失函数的作用                                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  损失函数 = 衡量预测与真实之间的差距                                    │
│                                                                     │
│  训练目标:最小化损失函数                                             │
│                                                                     │
│  ┌─────────┐      预测      ┌─────────┐      比较      ┌─────────┐ │
│  │  输入   │ ─────────────→ │  模型   │ ─────────────→ │  损失   │ │
│  │   x    │                │   f(x)  │                │  L(y,ŷ) │ │
│  └─────────┘                └─────────┘                └────┬────┘ │
│       ↑                                                     │      │
│       │              ┌─────────┐                           │      │
│       └──────────────│  真实   │←──────────────────────────┘      │
│                      │   y    │                                    │
│                      └─────────┘                                    │
│                                                                     │
│  好的损失函数特点:                                                   │
│  • 可微分(能用梯度下降优化)                                          │
│  • 凸性(最好有全局最优)                                              │
│  • 对异常值鲁棒                                                        │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

回归损失函数

1. MSE(均方误差)

MSE损失函数曲线

图注:MSE损失函数曲线 - 展示了预测值与真实值之间的平方误差关系,误差越大惩罚越重

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    MSE - Mean Squared Error                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  公式:                                                              │
│  MSE = (1/n) Σ(yᵢ - ŷᵢ)²                                            │
│                                                                     │
│  特点:                                                              │
│  • 对异常值敏感(平方放大误差)                                        │
│  • 处处可导,优化方便                                                  │
│  • 假设误差服从高斯分布                                                │
│                                                                     │
│  适用场景:房价预测、温度预测等连续值预测                                │
│                                                                     │
│  梯度(对单个样本 ŷᵢ 求偏导):                                       │
│  ∂MSE/∂ŷᵢ = (2/n)(ŷᵢ - yᵢ)                                          │
│  简化写法(单样本 L=(y-ŷ)²):∂L/∂ŷ = 2(ŷ - y)                       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

2. MAE(平均绝对误差)

MAE vs MSE对比

图注:MAE vs MSE对比 - 展示了两种损失函数对异常值的不同处理方式,MAE更鲁棒,MSE对大误差惩罚更重

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    MAE - Mean Absolute Error                         │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  公式:                                                              │
│  MAE = (1/n) Σ|yᵢ - ŷᵢ|                                             │
│                                                                     │
│  特点:                                                              │
│  • 对异常值更鲁棒                                                      │
│  • 在0点不可导(可用次梯度)                                           │
│  • 收敛速度比MSE慢                                                     │
│                                                                     │
│  MSE vs MAE:                                                        │
│  • MSE:对大误差惩罚重,适合异常值少的情况                              │
│  • MAE:对所有误差一视同仁,适合有异常值的情况                          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

分类损失函数

1. 交叉熵损失(Cross-Entropy)

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    交叉熵损失 - Cross-Entropy Loss                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  信息论基础:                                                         │
│  交叉熵衡量两个概率分布的差异                                          │
│                                                                     │
│  二分类:                                                            │
│  BCE = -[y·log(ŷ) + (1-y)·log(1-ŷ)]                                 │
│                                                                     │
│  多分类:                                                            │
│  CE = -Σ yᵢ·log(ŷᵢ)                                                 │
│                                                                     │
│  特点:                                                              │
│  • 与Softmax配合,梯度形式简洁                                         │
│  • 对错误预测惩罚大                                                    │
│  • 训练速度快(梯度大)                                                │
│                                                                     │
│  为什么不用MSE做分类?                                                │
│  • MSE在分类问题中梯度小,收敛慢                                       │
│  • 交叉熵更适合概率分布的比较                                          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

🔧 优化算法

梯度下降家族

梯度下降优化器对比

图注:梯度下降优化器对比 - 展示了不同优化算法在损失曲面上的收敛路径,可以看出Adam等自适应优化器收敛更快更稳定

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    梯度下降算法演进                                    │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. 批量梯度下降 (BGD)                                                │
│     θ = θ - η·∇J(θ)  # 使用全部数据                                   │
│     优点:稳定,收敛到全局最优                                         │
│     缺点:慢,内存占用大                                               │
│                                                                     │
│  2. 随机梯度下降 (SGD)                                                │
│     θ = θ - η·∇J(θ; xᵢ, yᵢ)  # 使用单个样本                           │
│     优点:快,能跳出局部最优                                           │
│     缺点:震荡大,不稳定                                               │
│                                                                     │
│  3. 小批量梯度下降 (Mini-batch) ⭐ 最常用                              │
│     θ = θ - η·∇J(θ; batch)  # 使用小批量                              │
│     优点:平衡了速度和稳定性                                           │
│     典型batch size: 32, 64, 128, 256                                  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

动量法(Momentum)

Momentum优化效果

图注:Momentum优化效果 - 展示了动量法如何通过累积之前的梯度方向来加速收敛并减少震荡

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    Momentum - 加速收敛                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  思想:累积之前的梯度方向,像滚雪球一样加速                              │
│                                                                     │
│  公式:                                                              │
│  vₜ = γ·vₜ₋₁ + η·∇J(θ)    # 速度更新                                  │
│  θ = θ - vₜ               # 参数更新                                  │
│                                                                     │
│  γ (动量系数):通常取 0.9                                             │
│                                                                     │
│  效果对比:                                                          │
│                                                                     │
│  标准SGD                    Momentum                                  │
│      ↓                        ↓                                     │
│      ↓  震荡大                ↓  平滑快速                            │
│    ╱╲╱╲                    ═══════                                  │
│                                                                     │
│  优点:                                                              │
│  • 加速收敛(尤其在相关方向)                                          │
│  • 减少震荡                                                          │
│  • 有助于跳出局部最优                                                  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Adam 优化器 ⭐ 最常用

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    Adam - Adaptive Moment Estimation                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Adam = Momentum + RMSprop                                           │
│                                                                     │
│  一阶矩估计(动量):                                                  │
│  mₜ = β₁·mₜ₋₁ + (1-β₁)·gₜ     # 梯度的指数移动平均                     │
│                                                                     │
│  二阶矩估计(RMSprop):                                               │
│  vₜ = β₂·vₜ₋₁ + (1-β₂)·gₜ²    # 梯度平方的指数移动平均                 │
│                                                                     │
│  偏差修正:                                                          │
│  m̂ₜ = mₜ / (1-β₁ᵗ)                                                  │
│  v̂ₜ = vₜ / (1-β₂ᵗ)                                                  │
│                                                                     │
│  参数更新:                                                          │
│  θ = θ - η·m̂ₜ / (√v̂ₜ + ε)                                          │
│                                                                     │
│  默认参数:                                                          │
│  β₁ = 0.9, β₂ = 0.999, ε = 1e-8                                     │
│                                                                     │
│  优点:                                                              │
│  • 自适应学习率(每个参数有自己的学习率)                               │
│  • 结合了Momentum和RMSprop的优点                                       │
│  • 对超参数不敏感                                                      │
│  • 适合大多数情况 ⭐                                                   │
│                                                                     │
│  缺点:                                                              │
│  • 可能不收敛到最优解(可用AdamW改进)                                  │
│  • 需要更多内存                                                        │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

学习率调度

学习率调度策略对比

图注:学习率调度策略对比 - 展示了五种常用学习率调度策略:Step Decay、Exponential Decay、Cosine Annealing、ReduceLROnPlateau和Cyclical LR

Step Decay学习率调度

图注:Step Decay学习率调度 - 每隔固定步数将学习率乘以衰减系数,形成阶梯状下降

Cosine Annealing学习率调度

图注:Cosine Annealing学习率调度 - 使用余弦函数平滑地降低学习率,提供更自然的衰减曲线

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    学习率调度策略                                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  为什么需要学习率调度?                                                │
│  • 初期:大学习率,快速接近最优                                        │
│  • 后期:小学习率,精细调整                                            │
│                                                                     │
│  常用策略:                                                          │
│                                                                     │
│  1. Step Decay                                                       │
│     每N个epoch,学习率乘以衰减系数(如0.1)                            │
│     lr = lr₀ × γ^(epoch // step_size)                                │
│                                                                     │
│  2. Exponential Decay                                                │
│     学习率指数衰减                                                    │
│     lr = lr₀ × γ^epoch                                               │
│                                                                     │
│  3. Cosine Annealing                                                 │
│     余弦退火,平滑下降                                                │
│     lr = lr_min + 0.5*(lr_max-lr_min)*(1+cos(π·epoch/max_epoch))    │
│                                                                     │
│  4. ReduceLROnPlateau                                                │
│     验证集损失不下降时,降低学习率                                     │
│                                                                     │
│  5. Warmup ⭐ 重要!                                                  │
│     前几个epoch从小学习率逐渐增大,稳定训练                            │
│     特别适用于大模型和深层网络                                         │
│     linear warmup: lr = lr_max × (step / warmup_steps)               │
│                                                                     │
│  推荐组合(大模型训练):                                              │
│  Warmup + Cosine Annealing                                           │
│  • 前5-10%步数:线性warmup                                            │
│  • 剩余步数:余弦退火到接近0                                          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

学习率调度代码实现

Python
import numpy as np
import matplotlib.pyplot as plt

class LearningRateScheduler:
    """学习率调度器"""

    def __init__(self, initial_lr, total_steps):  # __init__构造方法,创建对象时自动调用
        self.initial_lr = initial_lr
        self.total_steps = total_steps

    def step_decay(self, step, drop_every=10, drop_factor=0.5):
        """阶梯式衰减"""
        return self.initial_lr * (drop_factor ** (step // drop_every))

    def exponential_decay(self, step, decay_rate=0.95):
        """指数衰减"""
        return self.initial_lr * (decay_rate ** step)

    def cosine_annealing(self, step, min_lr=0):
        """余弦退火"""
        return min_lr + 0.5 * (self.initial_lr - min_lr) * \
               (1 + np.cos(np.pi * step / self.total_steps))

    def warmup_cosine(self, step, warmup_steps=1000, min_lr=0):
        """Warmup + 余弦退火 ⭐ 推荐"""
        if step < warmup_steps:
            # Linear warmup
            return self.initial_lr * (step / warmup_steps)
        else:
            # Cosine annealing
            progress = (step - warmup_steps) / (self.total_steps - warmup_steps)
            return min_lr + 0.5 * (self.initial_lr - min_lr) * \
                   (1 + np.cos(np.pi * progress))

# 可视化不同学习率调度策略
steps = np.arange(0, 1000)
scheduler = LearningRateScheduler(initial_lr=0.1, total_steps=1000)

plt.figure(figsize=(12, 8))

plt.subplot(2, 2, 1)
lr_step = [scheduler.step_decay(s) for s in steps]  # 列表推导式,简洁创建列表
plt.plot(steps, lr_step)
plt.title('Step Decay')
plt.xlabel('Step')
plt.ylabel('Learning Rate')

plt.subplot(2, 2, 2)
lr_exp = [scheduler.exponential_decay(s) for s in steps]
plt.plot(steps, lr_exp)
plt.title('Exponential Decay')
plt.xlabel('Step')
plt.ylabel('Learning Rate')

plt.subplot(2, 2, 3)
lr_cos = [scheduler.cosine_annealing(s) for s in steps]
plt.plot(steps, lr_cos)
plt.title('Cosine Annealing')
plt.xlabel('Step')
plt.ylabel('Learning Rate')

plt.subplot(2, 2, 4)
lr_warmup_cos = [scheduler.warmup_cosine(s, warmup_steps=200) for s in steps]
plt.plot(steps, lr_warmup_cos)
plt.title('Warmup + Cosine (Recommended)')
plt.xlabel('Step')
plt.ylabel('Learning Rate')

plt.tight_layout()
plt.savefig('lr_schedulers.png', dpi=150)
plt.show()

print("学习率调度策略可视化完成!")

📊 优化器对比

优化器 优点 缺点 适用场景
SGD 简单,泛化好 慢,需调学习率 大规模数据,最终优化
Momentum 加速收敛 需调参 通用
Adam 自适应,快 可能过拟合 默认选择 ⭐
AdamW 更好的权重衰减 稍复杂 推荐替代Adam
RMSprop 适合非平稳目标 需调参 RNN

💡 核心要点

  1. 损失函数选择
  2. 回归:MSE(默认),MAE(有异常值)
  3. 分类:Cross-Entropy(配合Softmax)

  4. 优化器选择

  5. 默认用Adam
  6. 追求极致性能用SGD + Momentum
  7. 注意学习率调度

  8. 学习率

  9. 最重要超参数
  10. 太大:不收敛
  11. 太小:收敛慢
  12. 典型值:0.1, 0.01, 0.001, 0.0001

🎯 下一步

继续学习 05-反向传播算法,理解梯度是如何计算的。