在深度学习中,学习率是神经网络模型训练测试时一个非常重要的超参数,通俗一点来说学习率(learing rate)控制了模型训练时参数更新的速度,即模型‘学习’的速度。今天这篇博客介绍一下几个比较常用的动态调整学习率函数。
1、为什么要动态调整学习率?
在我们平常的模型训练中,我们可能会经常将学习率设置为一个固定大小的值,其实这种做法有时候是不太妥当的。也许有些小伙伴遇到过自己的模型在训练过程中loss一直在一个值附近徘徊,但模型还未训练到最优状态,这时候就需要考虑到学习率的调整了。
在模型训练的前期,模型收敛的速度是比较快的,这个时候我们可以选择比较大的学习率,但在训练一定轮数后,模型可能还未达到但很接近最优模型,我们就需要选择一个比较合适的学习率值继续进行模型的优化训练,否则模型在训练过程中就可能在最优值附近不断‘振荡’徘徊,迟迟达不到最优解。
2、常用的动态调整学习率函数
2.1 等间隔学习率调整:StepLR()
scheduler = StepLR(optimizer, step_size, gamma, last_epoch=-1)
参数解析:
- ‘optimizer’:优化器对象;
- ‘step_size’ :调整间隔数,根据epoch进行设置,如step_size=30,则在30,60,90…个step时,对学习率进行调整;
- ‘gamma’:调整系数(学习率调整倍数)。默认=0.1,即下降10倍;
- ‘last_epoch’:上一个即最后一个epoch值,用于指示学习率的调整(last_epoch=-1时,学习率设置为初始值,即优化器中的学习率)
使用方式:
from torch.optim.lr_scheduler import StepLR
# 定义训练次数,学习率,损失函数与优化器
epoch = '你的训练次数'
learning_rate = '你设置的初始学习率值'
Loss_func = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)
scheduler = StepLR(optimizer, step_size, gamma, last_epoch=-1)
# 训练时
for epoch in range(epoch):
train(...)
test(...)
scheduler.step()
StepLR()学习率调整公式:lr = lr * gamma
2.2 指定间隔学习率调整:MultistepLR()
scheduler = MultiStepLR(optimizer, milestones, gamma, last_epoch=-1)
参数解析:
- ‘optimizer’:优化器对象;
- ‘milestones’:指定需要调整的epoch位置,为列表形式(如milestones=[50,100,160],即在epoch=50,100,160时对学习率进行调整);
- ‘gamma’:调整系数(学习率调整倍数);
- ‘last_epoch’:上一个即最后一个epoch值,用于指示学习率的调整
使用方式与StepLR类似
MultiStepLR()学习率调整公式:lr = lr * gamma
2.3 指数衰减学习率调整: ExponentialLR()
scheduler = ExponentialLR(optimizer, gamma, last_epoch=-1)
参数解析:
- ‘optimizer’:优化器对象;
- ‘gamma’:调整系数,为指数的底,通常接近1;
- ‘last_epoch’:上一个即最后一个epoch值,用于指示学习率的调整
使用方式与上述两种学习率调整函数类似
ExponentialLR()学习率调整公式:Ir = lr * gamma^epoch
2.4 自定义学习率调整:LambdaLR()
scheduler = LambdaLR(optimizer, lr_lambda, last_epoch=-1, verbose=False)
参数解析:
- ‘optimizer’:优化器对象;
- ‘lr_lambda’:一个用于计算学习率调整倍数的表达式或函数;
- ‘last_epoch’:上一个即最后一个epoch值,用于指示学习率的调整;
- ‘verbose’:是否打印调试信息,默认为false
使用案例(数据集导入和网络模型搭建部分已省略):
from torch.optim.lr_scheduler import LambdaLR
# 定义训练次数,学习率,损失函数与优化器
epoch = 50
learning_rate = 0.001
Loss_func = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)
lambda = lambda epoch: 1 - epoch * 0.01
scheduler = LambdaLR(optimizer, lr_lambda=lambda)
for epoch in range(epoch):
for step, (data, target) in enumerate(train_data):
print('step=', step, end=' ')
print('lr=', scheduler.get_last_lr())
optimizer.step()
scheduler.step()
# 输出:
# step= 0 lr= [0.001]
# step= 1 lr= [0.00099]
# step= 2 lr= [0.00098]
# step= 3 lr= [0.0009699999999999999]
# step= 4 lr= [0.00096]
# step= 5 lr= [0.00095]
# step= 6 lr= [0.00094]
# step= 7 lr= [0.0009299999999999999]
# step= 8 lr= [0.00092]
# step= 9 lr= [0.00091]
# step= 10 lr= [0.0009000000000000001]
。。。
上述案例中我们定义了一个用于调整学习率的表达式lambda,其对模型每一轮的每一次训练的学习率做lr = lr * (1 - epoch * 0.01)的调整。
LambdaLR()学习率调整公式:Ir = lr * lr_lambda (其中lr_lambda为自定义调整学习率的表达式或函数)
OK,以上就是本次文章的全部内容,其实学习率的不断调整就是为了模型能够向着正确的方向收敛,从而达到最优模型。
不知不觉这已经是我的第10篇博客,之所以写博客,一是记录自己的学习情况,一是多写些文章和上传项目也是一个加分项嘛。后续因为考试和考研的缘故,更新速度和更新方向可能会发生变化,特地告知大家,感谢大家的阅读!
本文介绍了深度学习中动态调整学习率的重要性,探讨了StepLR、MultistepLR、ExponentialLR和LambdaLR等常用函数,解释了为何需要调整学习率并给出了实例。
7795

被折叠的 条评论
为什么被折叠?



