在进行训练的过程中有时候会遭遇各种突发情况导致训练被迫终止,或者是说需要停下训练来测试效果,这个时候我们就可以每隔几个epoch保存一下模型,然后断掉之后重新加载模型继续训练。
去网上搜索了很多恢复训练的教程,大家都提到了保存模型/optimizer/epoch,但是有一个非常关键的点。你的更新模型策略设置的scheduler,是不能跟着一起保存的!也就是说,假设你定的是每三轮变为原来的0.5,从epoch=5开始恢复训练,那么你的epoch=6并不会改变学习率,而是从epoch=5+3=8才开始更改学习率!scheduler是根据内置的index进行更新的,外界的epoch对其并不会产生影响
schedulerG = optim.lr_scheduler.StepLR(optimizerG, step_size=3, gamma=0.7)
这样写的scheduler恢复训练就会出问题
(1).加载epoch=3的模型,则start_epoch=4,令last_epoch= start_epoch-1=3,Multistep设置在epoch=5时
milestones = [5]
schedulerG = optim.lr_scheduler.MultiStepLR(optimizerG, milestones=milestones, gamma=0.05, last_epoch = start_epoch-1)
测得在epoch=4结束更新之后,epoch=5开始时lr改变。
非常迷惑,按理来讲不是应该epoch=5结束的时候再更新吗?非常不理解
(2).加载epoch=3的模型,则start_epoch=4,令last_epoch= start_epoch-2=2,Multistep设置在epoch=5时
milestones = [5]
schedulerG = optim.lr_scheduler.MultiStepLR(optimizerG, milestones=milestones, gamma=0.05, last_epoch = start_epoch-2)
测得在epoch=5结束更新之后,epoch=6开始时lr改变。
这虽然和我们设计的multistep对上了,但是依然对last_epoch的设置感到不理解。
(3).加载epoch=8的模型,则start_epoch=9,令last_epoch= start_epoch-2=7,Multistep设置在epoch=5,10时
milestones = [5,10]
schedulerG = optim.lr_scheduler.MultiStepLR(optimizerG, milestones=milestones, gamma=0.05, last_epoch = start_epoch-2)
测得在epoch=9/10的时候和(2)的学习率是一样的,并且在epoch=10结束后,epoch=11开始时学习率发生变化,符合预期学习率变化策略。可以看出即使略过了第一个变化的点epoch=5,但是学习率依然在epoch=5时发生了变化。
(4).最后我们再来做一组实验,不加载模型,则start_epoch=1,令last_epoch= start_epoch-2=-1,Multistep设置在epoch=5时
milestones = [5]
schedulerG = optim.lr_scheduler.MultiStepLR(optimizerG, milestones=milestones, gamma=0.05, last_epoch = start_epoch-2)
测得在epoch=5结束更新之后,epoch=6开始时lr改变。大概last_epoch=start_epoch-2才可以吧。。还是不是很明白。tips:如果这个时候让last_epoch=0那么会报错:
"param 'initial_lr' is not specified in param_groups[0] when resuming an optimizer"
虽然不是很明白具体原理,但是如果你设置的epoch是1,2……那我建议是设置last_epoch=start_epoch-2能够符合Multisteplr的预期设置。
如果有大神有理解麻烦指点!