PyTorch中StepLR学习率调度器报错‘initial_lr not specified when resuming optimizer’的解决方法及调度配置咨询
解决PyTorch StepLR报错及满足学习率调度需求的正确配置
错误原因分析
你遇到的KeyError: "param 'initial_lr' is not specified..."是因为对last_epoch参数的理解有误。这个参数的作用是恢复训练时指定上一次训练到的轮次,而非限制调度器的运行轮次。当你设置last_epoch=60或90时,调度器会认为你是从第60/90轮继续训练,此时需要优化器的param_groups中保存有initial_lr(通常是之前保存优化器状态时自动添加的),但你是从头开始训练,自然没有这个参数,因此报错。从头训练时,last_epoch应该使用默认值-1,让调度器从初始状态开始计数。
满足需求的正确配置方案
你的需求是:100个epoch中,第30、60轮后各将学习率衰减为原来的1/10,60轮后不再调整。这里有两种简洁的实现方式:
方案一:使用MultiStepLR(更直观,推荐)
MultiStepLR可以直接指定需要衰减学习率的轮次,完全匹配你的需求,无需额外判断:
import torch import torch.optim as optim from torch.optim import lr_scheduler # 初始化优化器 sgd_config = { 'params' : net.parameters(), 'lr' : 1e-7, 'weight_decay' : 5e-4, 'momentum' : 0.9 } optimizer = optim.SGD(**sgd_config) # 配置调度器:在第30、60轮后衰减学习率,衰减因子0.1 scheduler = lr_scheduler.MultiStepLR(optimizer, milestones=[30, 60], gamma=0.1) # 训练循环(假设是1-based的epoch计数) for epoch in range(1, 101): # 训练流程:前向传播、计算损失、反向传播、优化 ... optimizer.step() # 更新学习率 scheduler.step()
这个配置下:
- 第30轮结束后,学习率变为
1e-7 * 0.1 = 1e-8 - 第60轮结束后,学习率变为
1e-8 * 0.1 = 1e-9 - 第61到100轮,学习率保持
1e-9不再变化,完全符合你的要求。
方案二:使用StepLR并限制调用次数
如果你坚持使用StepLR,需要在训练循环中控制只在前60轮调用scheduler.step(),避免第90轮的额外衰减:
# 初始化优化器和调度器(last_epoch用默认-1) optimizer = optim.SGD(**sgd_config) scheduler = lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1) # 训练循环 for epoch in range(1, 101): ... optimizer.step() # 仅在前60轮更新学习率 if epoch <= 60: scheduler.step()
这样第30、60轮结束后会正常衰减,60轮后不再调用调度器,学习率保持稳定。
总结
- 从头训练时不要随意设置
last_epoch,保持默认-1即可; - 针对指定轮次的学习率调整,
MultiStepLR是更贴合需求的选择; - 如果用
StepLR,需要通过循环条件限制调度器的调用范围,避免不必要的衰减。
内容的提问来源于stack exchange,提问作者rbaleksandar
相关产品推荐
相关产品推荐

