@TOC
pytorch的优化器和如何调整学习率都可以在这个链接中找到torch.optim
这里我们不介绍优化器,介绍一些调整学习率的方法,通过pytorch的库就不需要我们手动设置adjust learning rate函数了
LambdaLR
pytorch官方文档: LambdaLR
torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1, verbose=False)
Sets the learning rate of each parameter group to the initial lr times a given function. When last_epoch=-1, sets initial lr as lr.
将params中的学习率设置为学习率乘上一个给定的函数
- optimizer: 优化器
- lr_lambda: 一个关于epoch的函数,用来计算学习率要乘的那个数字
- last_epoch: 最后一个迭代的索引,默认-1
- verbose: 没啥用
lambdalr学习率的调整非常的简单,我们只需要在optimizer的基础上加上一个调整学习率的函数以及lambdalr即可,当需要更新学习率时,使用scheduler.step()
这里我们将optimizer用scheduler进行包装scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda1),命名为scheduler,之后的操作都是对scheduler操作的
同上一篇博客一样,我们依然用linear举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| class linear(nn.Module): def __init__(self): super(linear, self).__init__() self.linear1 = nn.Linear(2, 3) self.linear2 = nn.Linear(3, 4)
def forward(self, x): x = self.linear1(x) y = self.linear2(x) return y
net = linear() optimizer = optim.SGD(params=net.parameters(), lr=0.05) lambda1 = lambda epoch: 0.2**epoch scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda1) plt.figure() x = list(range(40)) y = [] for epoch in range(40): print(epoch, scheduler.get_last_lr()[0]) y.append(scheduler.get_last_lr()[0]) scheduler.step() plt.plot(x,y)
''' 0 0.05 1 0.010000000000000002 2 0.0020000000000000005 3 0.00040000000000000013 4 8.000000000000002e-05 5 1.6000000000000006e-05 ... 38 1.3743895347200028e-28 39 2.748779069440006e-29 '''
|
如果我们对linear1和linear2的学习率调整方法不一样怎么办?这里lr_scheduler库也提供了解决办法
首先将传入optimizer的参数分开,假设有两组参数,然后在lambdalr的学习率函数调整部分设置两个函数即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| net = linear() params = [{"params": net.linear1.parameters(), "lr":0.05}, {"params": net.linear2.parameters(), "lr":0.05}] optimizer = optim.SGD(params=params, lr=10)
lambda1 = lambda epoch: 0.5**epoch lambda2 = lambda epoch: 0.2**epoch
scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=[lambda1, lambda2]) plt.figure() x = list(range(40)) y1 = [] y2 = []
for epoch in range(40): print(epoch, scheduler.get_last_lr()[0], scheduler.get_last_lr()[1]) y1.append(scheduler.get_last_lr()[0]) y2.append(scheduler.get_last_lr()[1]) scheduler.step() plt.plot(x, y1) plt.plot(x, y2) plt.legend(['linear1', 'linear2'], loc='upper left') plt.show()
''' 0 0.05 0.05 1 0.025 0.010000000000000002 2 0.0125 0.0020000000000000005 3 0.00625 0.00040000000000000013 4 0.003125 8.000000000000002e-05 5 0.0015625 1.6000000000000006e-05 ... 38 1.8189894035458566e-13 1.3743895347200028e-28 39 9.094947017729283e-14 2.748779069440006e-29 '''
|
scheduler还有几个方法,下面简单介绍
- get_last_lr: 上面也有例子,是获取当前的学习率
- state_dict: 获取当前scheduler状态
- load_state_dict: 加载模型,保存之后加载