PyTorch中optimizer.param_groups[0]['lr']与scheduler.get_lr()[0]的差异及真实学习率判断
PyTorch 1.9.1 StepLR学习率取值差异问题解答
1. 为什么optimizer.param_groups[0]['lr']和scheduler.get_lr()[0]返回结果不一致?
核心原因是**get_lr是调度器内部方法,设计目的不是给用户外部调用获取当前生效学习率**:
get_lr仅会在scheduler.step()执行过程中被内部调用,作用是计算「待更新到优化器中的新学习率」。你在step()执行完成后外部调用get_lr,此时调度器的last_epoch已经更新完成,若当前epoch刚好是step_size的整数倍,get_lr会基于已经更新过的优化器学习率,再额外乘一次gamma,相当于多算了一次衰减,自然和优化器中实际存储的学习率不一致。- 你可以注意到源码中
get_lr开头就有警告提示:非内部场景调用get_lr时,建议使用get_last_lr()获取最新的有效学习率,就是为了避免这个误用问题。
2. 网络实际运行使用的真实学习率是哪个?
网络训练时优化器实际使用的学习率就是optimizer.param_groups[0]['lr']中存储的值,你用这个字段记录的结果是完全正确的。
如果不想直接访问优化器的参数组,也可以调用官方提供的公共方法scheduler.get_last_lr()[0]获取当前生效的学习率,结果和优化器中存储的值完全一致。
3. 新旧版本行为差异的原因
PyTorch 1.1之后重构了学习率调度器的底层逻辑:
- 旧版本的
get_lr是基于初始学习率base_lr做闭公式计算,不管用户是否手动修改过优化器的学习率,都会按初始值计算,所以外部调用也不会出现取值错误。 - 新版本为了支持「用户手动修改优化器学习率后,调度器能基于修改后的值继续衰减」的需求,将
get_lr的逻辑改成了基于优化器当前存储的学习率做增量计算,这个改动就导致外部调用get_lr时会出现重复计算衰减的问题。
内容的提问来源于stack exchange,提问作者Darcy
相关产品推荐
相关产品推荐

