在复原USRNet的过程中,总是训练不出理想模型,10w+次效果还很差,并且学习率调整很奇怪。
最后发现是学习率调整策略中get_lr()有很大问题!!!!!
网上很少有这方面的内容,特记录如下。
- get_lr()和get_last_lr()的区别
首先,我用的是MultiStepLR这个调整策略,定义如下:
def define_scheduler(self):
self.schedulers.append(lr_scheduler.MultiStepLR(self.G_optimizer,
self.opt_train['G_scheduler_milestones'],
self.opt_train['G_scheduler_gamma']
))
第一个参数是优化器类型;
第二个参数是设置的几个节点;
第三个参数是衰减因子;
可以写几个节点,在这几个节点处初识衰减率会乘衰减因子进行衰减。
具体可以看这篇博客,写的很详细:
pytorch中的学习率调整函数
在更新学习率的部分有这样一个函数get_lr()有很大的bug:
def current_learning_rate(self):
print(self.schedulers[0].get_lr()[0])
return self.schedulers[0].get_last_lr()[0]
get_last_lr()才表示当前的学习率,使用get_lr()会衰减两次!!
上数据,为了方便检测,我设了两个很小的节点,分别会在迭代5,10次是衰减,乘以0.5,初始学习率是1.000e-04:
红色部分是get_last_lr()打印的;
白色部分是get_lr()打印的:
可以看到错误的写法确实会在节点处衰减两次
这是由于step()时会调一次get_lr(),为了得到lr又掉用一次get_lr(),这样就会衰减两次。
因此get_last_lr()才是当前的lr
- step()括号里不能有参数
源代码传入了当前迭代次数,学习率简直错到离谱,八辈子都练不出来。
请记住,不要传参不要传参!
主函数调用:
model.update_learning_rate()
定义部分:
def update_learning_rate(self):
for scheduler in self.schedulers:
scheduler.step()
- 关于优化参数和学习率调整的顺序问题
先优化参数,再学习率调整不然会报警告。
据说除了警告外还会导致会跳过学习率的第一个值。
(但我浅试了一下,好像除了警告没什么大区别(存疑),但是,要听劝,我还是准备改了)
可以参考知乎上这篇笔记:
pytorch调整模型训练的学习率