循环学习率:周期性升降替代固定衰减
循环学习率:告别固定衰减,释放训练潜能
在训练神经网络时,学习率无疑是最关键的超参数之一。传统的做法是“固定衰减”:从一个初始值开始,每过几个 epoch 或当指标停滞时,按比例降低学习率。这种方法虽然经典,但存在两个明显局限:
- 学习率一旦下降就无法回升,容易使模型陷入尖锐的局部极小值。
- 需要手动设定衰减时机与幅度,调试成本高。
循环学习率 提出了一个反直觉的思路:让学习率在训练过程中周期性升降,而不是一成不变地减小。实践证明,这不仅能加速收敛,还经常能找到一个更平坦、泛化性能更好的最小值。
核心思想:用周期取代阶梯
循环学习率的核心是让学习率在上限(max_lr)和下限(base_lr)之间以某个规律循环变化。在每个周期里:
- 学习率从小变大(升温阶段):让优化器有足够动量跳出局部极小点,探索更广阔的损失面。
- 学习率从大变小(降温阶段):使模型能精细收敛到该区域的稳定点。
与之对比,固定衰减只在必要时刻减小学习率,像一个不断降低温度的退火过程,而循环学习率则像是反复“加热—冷却”,赋予了训练过程更强的探索能力。
三种常见的循环策略
| 策略名称 | 波形描述 | 适用场景 |
|---|---|---|
| 三角循环 | 学习率线性上升再线性下降,形成锯齿状 | 最基础,实现简单,通常效果已很不错 |
| 余弦退火 | 以余弦曲线平滑升降,变化更温和 | 适合需要稳定收敛的任务,波动小 |
| 热重启余弦 | 余弦周期,但每个周期结束后学习率瞬间跳回最大值 | 在图像分类等任务中表现出极强的跳出能力 |
实际使用中,单周期余弦退火 往往是最稳妥的起点:先从一个较小的学习率快速上升到最大值,再保持一段时间,最后以余弦方式缓慢下降到远低于初始值的终末学习率。
如何确定上下边界
循环学习率只有两个核心参数需要设置:base_lr(下界) 和 max_lr(上界)。可通过一次简单的 LR范围测试 确定:
- 从一个极小学习率(如1e-7)开始,每个 batch 线性(或指数)增加学习率。
- 记录损失值随学习率变化的曲线。
- 找到损失快速下降且未开始剧烈震荡或上升的区间。
base_lr可取损失开始下降的点,max_lr取损失停止下降、即将上扬前的点(通常再除一个安全系数,如除以2或10)。
举个例子,假设观察曲线发现:在 lr=1e-3 时损失开始显著减小,在 lr=1e-1 时损失突然爆炸。安全的设置可以是 base_lr=1e-4,max_lr=5e-2。
实战:用 PyTorch 实现单周期余弦循环
import torch
import torch.optim as optim
from torch.optim.lr_scheduler import OneCycleLR
model = YourModel()
optimizer = optim.Adam(model.parameters(), lr=1e-3)
steps_per_epoch = len(train_loader)
total_steps = steps_per_epoch * num_epochs
scheduler = OneCycleLR(
optimizer,
max_lr=5e-2, # 由范围测试决定
total_steps=total_steps,
pct_start=0.3, # 前30%时间用于从base_lr升到max_lr
anneal_strategy='cos', # 余弦退火
final_div_factor=1e4 # 最终学习率 = max_lr / final_div_factor
)
for epoch in range(num_epochs):
for batch in train_loader:
loss = ...
loss.backward()
optimizer.step()
scheduler.step() # batch级别更新学习率
OneCycleLR 在单个周期内完成从升温到长时间降温的全过程。训练结束时,学习率会降到极低,相当于完成了精细收敛和模拟退火。
循环长度与步长设置
单步(step)通常定义为一个 batch 更新。一个完整周期跨越的 step 数称为 steps_per_cycle。一般建议:
- 周期长度至少覆盖几个 epoch,使模型有机会经历完整的探索-利用过程。
- 推荐将一个 epoch 设为半个周期或一整周期。例如,训练 100 个 epoch,可让学习率经历 3~5 个完整余弦循环。
对于 热重启 策略,每次周期结束时学习率重置,并可以伴随周期长度的渐增(例如每个新周期长度变为原来的 2 倍),使模型在训练后期有更长的精调时间。
为什么它有效?——损失景观的视角
现代深度网络的损失面通常遍布大量平坦区域和尖锐谷地。传统的单调衰减容易使优化器卡在某个尖锐极小值附近,导致泛化能力不足。而循环学习率中阶段性的高学习率能让参数“跳出”尖锐区域,有机会进入更宽广的盆地。低学习率阶段则帮助模型在该盆地内稳定下来。因此模型最终停驻的最小值往往比固定衰减更加平稳,测试集表现更优。
常见疑问与注意事项
-
会不收敛吗?
只要max_lr设置合理,循环模式最终仍会将学习率降至极低值(如单周期策略),因此收敛性有保障。建议配合动量(momentum)或 Adam 使用,效果更稳定。 -
如何与 batch size 一起调?
max_lr通常与 batch size 正相关,batch size 翻倍时max_lr也可适当提升,但范围测试依然是最终的黄金标准。 -
学习率波动造成损失忽高忽低?
这是正常现象,尤其是热重启时,损失会短暂升高。衡量收敛应看周期末期的最低点是否稳定下降。 -
适用所有任务吗?
在计算机视觉、自然语言处理、强化学习等领域均有成功应用。唯一需要注意的是极低资源微调场景,可能传统阶梯衰减更温和,但从经验看,循环学习率结合余弦退火几乎没有明显劣势。
进阶:动态调整循环周期
不再仅使用固定长度的周期,而是自适应延长或缩短:当验证损失不再改善时,完成当前冷却阶段并提前进入下一循环;或者让周期长度随训练进行指数增长,使探索越来越深入。结合早停(early stopping)技术,可以构成几乎无需人工干预的自动学习率策略。
总结
循环学习率用波动取代单调,用一个简单的周期性策略同时实现了探索与利用的平衡。它的精髓不是复杂公式,而是一个思维转变:学习率不必一直减小。通过一次范围测试确定上下边界,再选择合适的循环形状,就能在不增加调参负担的前提下,显著提升训练速度和模型泛化能力。
立即尝试清单:
- 实施一次 LR 范围测试,找到你的
base_lr与max_lr。 - 用
OneCycleLR替换原有固定衰减策略。 - 对比验证集曲线,观察收敛速度与最终精度。
你会惊讶于这个简单改变带来的差别。