You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CIFAR-10训练中正确使用OneCycleLR学习率调度器?

关于OneCycleLR调度器的两个关键问题解答

一、epochs参数的正确设置

  • OneCycleLR是单周期学习率调度器,epochs参数代表的是整个训练过程的总epoch数,而非单次循环的epoch数。
  • 若你计划训练200个epoch,必须将epochs=200。如果设置epochs=10却训练200个epoch,前10个epoch会完成OneCycle的完整循环(从初始LR升到max_lr再降到极低值),剩余190个epoch的学习率会维持在最终的极小值(由final_div_factor参数控制),不会重复执行循环。

二、学习率异常变化的原因及解决方法

你的学习率出现先低后升的异常,核心有两个原因:

1. OneCycleLR会自动覆盖优化器的初始LR

OneCycleLR默认通过max_lr / div_factor计算训练的起始学习率。你的设置中:

optimizer = optim.Adam([x for x in model.parameters() if x.requires_grad], lr=0.001)
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.01, epochs=200, steps_per_epoch=128)

默认div_factor=25.0,所以起始LR为0.01 / 25 = 0.0004,这就是你看到的Epoch 1的LR值——OneCycleLR直接覆盖了你手动设置的lr=0.001。

若希望起始LR接近手动设置的0.001,有两种调整方式:

  • 修改div_factor:比如设置div_factor=10,此时起始LR为0.01/10=0.001,与优化器初始LR一致;
  • 直接将优化器初始LR设为max_lr / div_factor,避免参数冲突。

2. scheduler.step()的调用时机错误

OneCycleLR要求每个训练step(即每个batch训练完成后)调用一次scheduler.step(),而非每个epoch结束后调用。

如果你的代码是每个epoch调用一次scheduler.step(),总步数会被错误计算为200步(而非200*128=25600步)。此时,OneCycleLR的上升阶段(占总步数的pct_start=0.3)会被大幅拉长,导致训练到118epoch还处于上升阶段,完全不符合预期。

正确的调用逻辑示例:

for epoch in range(200):
    for batch_idx, (data, target) in enumerate(train_loader):
        # 前向传播、损失计算、反向传播
        optimizer.step()
        # 每个batch后更新学习率
        scheduler.step()
    # epoch结束后的验证、日志记录等操作

内容的提问来源于stack exchange,提问作者CasellaJr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 19:09:28