学习率调度

wen IT资讯 22

本文目录导读:

学习率调度

  1. 为什么需要学习率调度?
  2. 主流的学习率调度策略
  3. 高级变体 & 自适应调度器
  4. 总结与选择建议

学习率调度(Learning Rate Scheduling)是深度学习训练中非常关键的一环,它的核心思想是:在训练过程中动态地调整学习率,而不是使用一个固定值

一个好的学习率调度策略,可以显著提升模型的收敛速度、最终精度,并帮助模型逃离局部极小值或鞍点。

为什么需要学习率调度?

想象一下我们正在下山(寻找损失函数的最小值):

  1. 学习率太大:步长太大,容易在山谷两侧来回震荡,甚至直接跳出山谷(错过最优点),导致损失无法收敛。
  2. 学习率太小:步长太小,虽然能稳步下降,但训练过程非常缓慢,而且很容易陷入局部的“小坑”里(局部极小值)出不来。

一个理想的策略是:

  • 训练初期:使用较大的学习率,快速接近最优解区域。
  • 训练中后期:逐渐减小学习率,在最优解附近进行精细的微调,避免震荡。

主流的学习率调度策略

下面介绍几种最常用、效果也最好的策略。

分段常数衰减

这是最简单的策略之一,人为设定几个“里程碑”步数(Epoch),到达后学习率直接乘以一个衰减因子(如0.1)。

  • 原理:手动控制学习率在特定阶段下降。

  • 代码示例(PyTorch)

    import torch.optim.lr_scheduler as lr_scheduler
    # 假设 optimizer 是之前定义好的
    # milestones:在第30、60、80个Epoch时触发衰减
    # gamma:衰减因子,新的lr = 旧的lr * 0.1
    scheduler = lr_scheduler.MultiStepLR(optimizer, milestones=[30, 60, 80], gamma=0.1)
    for epoch in range(100):
        train(...)
        validate(...)
        scheduler.step() # 每个epoch结束后调用,更新学习率
  • 优点:简单、直观,效果稳定。

  • 缺点:需要手动调整milestones,不够自适应。

指数衰减

学习率在每个迭代或每个Epoch后,按指数函数衰减。

  • 公式lr = lr_initial * gamma ^ epoch
  • 代码示例(PyTorch)
    # gamma:通常设为0.9-0.99,接近1则衰减慢
    scheduler = lr_scheduler.ExponentialLR(optimizer, gamma=0.95)
  • 优点:曲线平滑,易于控制衰减速度。
  • 缺点:衰减速度固定,可能过早衰减导致模型收敛变慢。

余弦退火

这是一种非常流行且高效的策略,学习率按照半个余弦函数的周期来下降。

  • 原理:从初始学习率开始,像余弦曲线一样平滑地下降到接近0。
  • 代码示例(PyTorch)
    # T_max:半个余弦周期的长度,例如设为总Epochs数,则学习率在结束时降到最低。
    scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=100)
  • 优点:衰减过程非常平滑,在很多视觉任务中效果优于分段衰减。
  • 缺点:如果T_max设置不当,可能在训练结束时学习率降得太低。

带重启的余弦退火

这是余弦退火的进阶版,它会在学习率降到最低点后,突然将学习率重置到一个较高的值,然后重新开始一个余弦周期。

  • 原理:这种“重启”操作能让模型跳出当前的局部极小值,探索新的更优解空间。
  • 代码示例(PyTorch)
    # T_0:第一个周期的长度(Epoch数)
    # T_mult:每次重启后,周期长度乘以该系数(通常设为2)
    scheduler = lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_0=20, T_mult=2)
  • 优点:非常有效,尤其适用于复杂、非凸的损失函数。
  • 缺点:超参数(T_0, T_mult)需要调试。

循环学习率

学习率在一个预设的上下限之间循环变化,而不是单调下降。

  • 原理:通过周期性的增大和减小学习率,帮助模型逃离局部极小值。
  • 优点:有时能获得比单调下降更好的效果。
  • 缺点:属于比较激进的方法,需要小心调节边界值。

高级变体 & 自适应调度器

除了上述基于“轮数”的调度,还有基于“指标”的自适应调度器:

  • ReduceLROnPlateau(PyTorch)
    • 原理:监控验证集的损失,当损失连续多个Epoch(patience参数)没有下降时,就自动降低学习率。
    • 优点:完全自适应,工程师不需要预设衰减步数,这是很多实战场景的首选。
    • 代码示例
      scheduler = lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=5)
      for epoch in range(100):
          val_loss = train_and_validate(...)
          scheduler.step(val_loss) # 传入监控指标

总结与选择建议

策略名称 核心特点 适用场景 推荐指数
分段常数衰减 简单、稳定、可解释性强 大多数标准任务,尤其是CV(图像)任务 ⭐⭐⭐⭐
指数衰减 平滑、可控 对收敛速度要求不敏感的任务 ⭐⭐⭐
余弦退火 平滑、流行、效果好 现代CNN(卷积神经网络)和Transformer训练 ⭐⭐⭐⭐⭐
带重启的余弦退火 强探索能力、更优解 复杂任务、训练时间短、追求极致精度 ⭐⭐⭐⭐
ReduceLROnPlateau 完全自适应、省心 数据量不大、难以选择milestones、快速实验 ⭐⭐⭐⭐⭐

一个实用的工作流:

  1. 新手或快速实验: 优先尝试 ReduceLROnPlateau,设置 patience=35factor=0.1,它非常稳健。
  2. CV(图像)任务(如ResNet, EfficientNet): 经典用法是 分段常数衰减(如 30, 60, 90),如果追求更好效果,可以改用 余弦退火
  3. Transformer类模型(如BERT, ViT, GPT): 通常使用一种更精细的调度器——Warmup + 余弦衰减,先使用很小的学习率预热 warmup_steps 步,让模型稳定,然后再用余弦衰减下降,PyTorch 提供了 CosineAnnealingWarmRestarts 或可以自定义实现。

最关键的一点: 无论选择哪种调度器,监控验证集的损失/准确率 都是判断学习率是否合适的金标准,如果验证损失在持续震荡或上升,说明学习率可能太大了。

上一篇Kaiming He

下一篇Xavier初始化

抱歉,评论功能暂时关闭!