为什么通过torch.optim.SGD方法学习率会发生变化



使用SGD,学习率在时期内不应该改变,但确实如此。请帮助我理解为什么会发生这种情况,以及如何防止这种LR改变?

import torch
params = [torch.nn.Parameter(torch.randn(1, 1))]
optimizer = torch.optim.SGD(params, lr=0.9)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1, gamma=0.9)
for epoch in range(5):
print(scheduler.get_lr())
scheduler.step()

输出为:

[0.9]
[0.7290000000000001]
[0.6561000000000001]
[0.5904900000000002]
[0.5314410000000002]

我的torch版本是1.4.0

由于您使用的是命令torch.optim.lr_scheduler.StepLR(optimizer, 1, gamma=0.9)(实际上是指torch.optim.lr_scheduler.StepLR(optimizer, step_size=1, gamma=0.9)(,因此每step_size=1步都要将学习率乘以gamma=0.9

  • 0.9=0.9
  • 0.729=0.9*0.9*0.9
  • 0.6561=0.9*0.9*0.9*0.9
  • 0.59049=0.9*0.9*0.9*0.9

唯一"奇怪"的一点是,它在第二步中缺少0.81=0.9*0.9(更新:请参阅Szymon Maszke的答案以获得解释(

为了防止早期减少,如果数据集中有N样本,并且批次大小为D,则将torch.optim.lr_scheduler.StepLR(optimizer, step_size=N/D, gamma=0.9)设置为在每个历元减少。减少每个E历元集合torch.optim.lr_scheduler.StepLR(optimizer, step_size=E*N/D, gamma=0.9)

这正是torch.optim.lr_scheduler.StepLR应该做的。它改变了学习率。来自pytorch文档:

在每个步长_大小的时期内通过gamma衰减每个参数组的学习率。请注意,这种衰减可以与来自该调度器外部的学习速率的其他变化同时发生。当last_epoch=-1时,将初始lr设置为lr

如果您正在尝试优化params,您的代码应该更像这样(只是一个玩具示例,loss的精确形式将取决于您的应用程序(

for epoch in range(5):
optimizer.zero_grad()
loss = (params[0]**2).sum()
loss.backward()
optimizer.step()

要扩展xiawi关于"奇怪"行为的答案(缺少0.81(:这是PyTorch自1.1.0发布以来的默认方式,请查看文档,即这部分:

[…]如果您使用学习率调度程序(调用scheduler.step()((调用optimizer.step()(,这将跳过学习率的第一个值日程

此外,您应该在第一次get_lr()调用后获得此函数抛出的UserWarning,因为您根本没有调用optimizer.step()

相关内容

  • 没有找到相关文章

最新更新