Pytorch学习率控制

在pytorch中,官方向我们提供了用于学习率控制的辅助类Scheduler,这些类位于torch.optim.lr_scheduler下。在这些类中提供了基于epoch的学习率调整方法。

torch.optim.lr_scheduler.LambdaLR

将每一个参数组的学习率设置为初始学习率乘以给定的学习率,当last_epoch=-1时,将学习率设定为初始学习率。

例如:

1
2
3
4
5
6
7
>>> lambda1 = lambda epoch: epoch // 30
>>> lambda2 = lambda epoch: 0.95 ** epoch
>>> scheduler = LambdaLR(optimizer, lr_lambda=[lambda1, lambda2])
>>> for epoch in range(100):
>>> train(...)
>>> validate(...)
>>> scheduler.step()

torch.optim.lr_scheduler.StepLR

step_size步给每一个参数组乘以gamma。这一衰减可以和scheduler之外学习率的改变一起发生。

例如:

1
2
3
4
5
6
7
8
9
10
>>>> # Assuming optimizer uses lr = 0.05 for all groups
>>> # lr = 0.05 if epoch < 30
>>> # lr = 0.005 if 30 <= epoch < 60
>>> # lr = 0.0005 if 60 <= epoch < 90
>>> # ...
>>> scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
>>> for epoch in range(100):
>>> train(...)
>>> validate(...)
>>> scheduler.step()

torch.optim.lr_scheduler.MultiStepLR

在指定的epoch,给每一个参数组乘以gamma。这一衰减可以和scheduler之外的衰减同时发生。

例如:

1
2
3
4
5
6
7
8
9
>>>> # Assuming optimizer uses lr = 0.05 for all groups
>>> # lr = 0.05 if epoch < 30
>>> # lr = 0.005 if 30 <= epoch < 80
>>> # lr = 0.0005 if epoch >= 80
>>> scheduler = MultiStepLR(optimizer, milestones=[30,80], gamma=0.1)
>>> for epoch in range(100):
>>> train(...)
>>> validate(...)
>>> scheduler.step()

torch.optim.lr_scheduler.ExponentialLR

对学习率进行指数衰减。

例如:

1
2
3
4
5
6
7
8
9
10
11
scheduler = lr_scheduler.ExponentialLR(optimizer, gamma=0.9)
print()
plt.figure()
y.clear()
for epoch in range(100):
scheduler.step()
print(epoch, 'lr={:.6f}'.format(scheduler.get_lr()[0]))
y.append(scheduler.get_lr()[0])

plt.plot(x, y)
plt.show()

torch.optim.lr_scheduler.CosineAnnealingLR

余弦退火衰减,在采用小批量随机梯度下降(MBGD/SGD)算法时,神经网络应该越来越接近 Loss 值的全局最小值。当它逐渐接近这个最小值时,学习率应该变得更小来使得模型不会超调且尽可能接近这一点。余弦退火利用余弦函数来降低学习率,进而解决这个问题。

如果学习率仅由这一scheduler设定,那么每一步的学习率的计算公式如下:

由上式可以看出,每隔$T_{max}$个epoch,学习率会重启为初始学习率。

例如,设置总的epochs为100,$T_{max}=20$,学习率变化曲线如下图所示:

设置总的epochs为100,$T_{max}=100$,学习率变化曲线如下图所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import torch
import torchvision.models as models
from torch import optim
import matplotlib.pyplot as plt


model = models.resnet50(pretrained=True)
optimizer = torch.optim.SGD(model.parameters(), lr=0.0002, momentum=0.9)
epoches = 55
lr_scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, 40)

lr_list = list()
for x in range(epoches):
if x == 30:
optimizer.param_groups[0]['initial_lr'] = 0.0001
lr_scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, 25)
lr = lr_scheduler.get_lr()
lr_list.append(lr)
lr_scheduler.step()

plt.figure()
plt.title('Lr Change')
plt.plot(range(epoches), lr_list)

torch.optim.lr_scheduler.ReduceLROnPlateau

当某一给定的矩阵停止提升时,对学习率进行衰减。这一scheduler读取给定的矩阵,当该矩阵的数值在patience个epoch内未提升时,衰减学习率。

1
2
3
4
5
6
7
>>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> scheduler = ReduceLROnPlateau(optimizer, 'min')
>>> for epoch in range(10):
>>> train(...)
>>> val_loss = validate(...)
>>> # Note that step should be called after validate()
>>> scheduler.step(val_loss)

torch.optim.lr_scheduler.CyclicLR

依据循环学习率策略对每一个参数组的学习率进行设置。这一策略以固定的频率在两个边界之间对学习率进行设定。
循环学习率策略在每一个batch的训练之后对学习率进行调整,也就是说,应该在每一次训练步骤完成之后调用.step方法。
这个类由三个内建的调整策略:

  • triangular:基础循环,不对幅度进行缩放。
  • triangular2:基础三角循环,在每一次循环中对幅值减半。
  • exp_range:在每一次循环迭代中,对初始学习率乘以gamma**(cycle iterations)
------ 本文结束------
坚持原创技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道