Pytorch 为什么torch.optim.SGD方法的学习率会发生变化?

Pytorch 为什么torch.optim.SGD方法的学习率会发生变化?,pytorch,learning-rate,Pytorch,Learning Rate,有了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 rang

有了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\u调度程序.StepLR(optimizer,1,gamma=0.9)
(实际上是
torch.optim.lr\u调度程序.StepLR(optimizer,step\u size=1,gamma=0.9)
),因此您将学习率乘以
gamma=0.9
step\u size=1
一步:

  • 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.9*0.9
唯一“奇怪”的一点是,它在第二步缺少0.81=0.9*0.9(更新:请参阅以获取解释)


为防止提前减少,如果数据集中有
N
个样本,且批大小为D,则将
torch.optim.lr\u scheduler.StepLR(优化器,step\u size=N/D,gamma=0.9)
设置为在每个历元减少。要减少每个E历元集
torch.optim.lr_调度程序.StepLR(优化器,步长=E*N/D,gamma=0.9)
这正是
torch.optim.lr_调度程序.StepLR
应该做的。它改变了学习速度。从pytorch文档中:

在每一步大小的时间段内,通过gamma衰减每个参数组的学习率。请注意,这种衰减可能与来自此调度程序外部的学习速率的其他更改同时发生。当last_epoch=-1时,将初始lr设置为lr

如果您试图优化
参数
,您的代码应该更像这样(只是一个玩具示例,
丢失
的精确形式将取决于您的应用程序)

关于“奇怪”行为的回答(缺少
0.81
):这是PyTorch的默认方式,因为
1.1.0
发布,请检查,即此部分:

[…]如果您使用学习率计划程序(调用 在优化器更新(调用
optimizer.step()
),这将跳过学习率的第一个值 时间表


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

太好了!谢谢你如此精确的描述@Alex如果答案解决了您的问题,请接受它-请参阅@xiawi查看我关于“stange”行为的答案或
optimizer
step而不是
0.81
。感谢@joemrt提供您的答案!
for epoch in range(5):
  optimizer.zero_grad()
  loss = (params[0]**2).sum()
  loss.backward()
  optimizer.step()