关于pytorch学习率调度器

Vin*_*_Ho 5 python pytorch

这是我的代码

optimizer = optim.SGD(net.parameters(), lr=0.1)
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.5)

for i in range(15):
    lr = scheduler.get_lr()[0]
    lr1 = optimizer.param_groups[0]["lr"]
    print(i, lr, lr1)
    scheduler.step()
Run Code Online (Sandbox Code Playgroud)

这是结果

0 0.1 0.1
1 0.1 0.1
2 0.1 0.1
3 0.1 0.1
4 0.1 0.1
5 0.025 0.05
6 0.05 0.05
7 0.05 0.05
8 0.05 0.05
9 0.05 0.05
10 0.0125 0.025
11 0.025 0.025
12 0.025 0.025
13 0.025 0.025
14 0.025 0.025
Run Code Online (Sandbox Code Playgroud)

我们可以看到,当scheduler.step()被应用时,学习率首先下降了 0.25 倍,然后反弹回 0.5 倍。是scheduler.get_lr()lr的问题还是lr的问题scheduler.step()

关于环境

  • 蟒蛇=3.6.9
  • pytorch=1.1.0

另外我在使用pytorch=0.4.1的时候也找不到这个问题。

Ber*_*iel 8

是的,“问题”在于使用get_lr(). 要获得当前的 LR,您实际上需要的是get_last_lr().


如果你看一下实现

def get_lr(self):
    if not self._get_lr_called_within_step:
        warnings.warn("To get the last learning rate computed by the scheduler, "
                      "please use `get_last_lr()`.", UserWarning)

    if (self.last_epoch == 0) or (self.last_epoch % self.step_size != 0):
        return [group['lr'] for group in self.optimizer.param_groups]
    return [group['lr'] * self.gamma
            for group in self.optimizer.param_groups]
Run Code Online (Sandbox Code Playgroud)

当在 step=5 时,不满足条件(因为step_size=5),会返回lr * gamma. 尴尬的是,当您调用get_lr()step()函数时应该收到警告(如您在上面的实现中所见),而显然您没有。该警告仅在 3 个月前添加,因此您不会在 v1.1.0 上看到它。

为了完整起见,该step()方法所做的是将 1 添加到last_epoch并通过调用get_lr()函数更新 LR (请参见此处):

self.last_epoch += 1
values = self.get_lr()
Run Code Online (Sandbox Code Playgroud)