Pytorch 手动更新与使用模型更新需要非常不同的学习率

Pytorch 手动更新与使用模型更新需要非常不同的学习率,pytorch,Pytorch,我目前正试图写一些教学材料,其中我借用了一些常见的例子,这些例子在网络上被多次修改过 我有一段简单的代码,手动为层创建张量,并在循环中更新它们。例如: w1 = torch.randn(D_in, H, dtype=torch.float, requires_grad=True) w2 = torch.randn(H, D_out, dtype=torch.float, requires_grad=True) learning_rate = 1e-6 for t in range(501):

我目前正试图写一些教学材料,其中我借用了一些常见的例子,这些例子在网络上被多次修改过

我有一段简单的代码,手动为层创建张量,并在循环中更新它们。例如:

w1 = torch.randn(D_in, H, dtype=torch.float, requires_grad=True)
w2 = torch.randn(H, D_out, dtype=torch.float, requires_grad=True)

learning_rate = 1e-6
for t in range(501):
    y_pred = x.mm(w1).clamp(min=0).mm(w2)
    loss = (y_pred - y).pow(2).sum()
    loss.backward()
    w1 -= learning_rate * w1.grad
    w2 -= learning_rate * w2.grad
    w1.grad.zero_()
    w2.grad.zero_()
这很有效。然后,我使用实际模块构造类似的代码:

model = torch.nn.Sequential(
          torch.nn.Linear(D_in, H),
          torch.nn.ReLU(),
          torch.nn.Linear(H, D_out),
        )
loss_fn = torch.nn.MSELoss(reduction='sum')
learning_rate = 1e-4
for t in range(501):
    y_pred = model(x)
    loss = loss_fn(y_pred, y)
    model.zero_grad()
    loss.backward()
    for param in model.parameters():
        param.data -= learning_rate * param.grad
这也很有效

但是这里有一个区别。如果我在手动情况下使用1e-4 LR,损失会爆炸,变大,然后是inf,然后是nan。所以这不好。如果在模型中使用1e-6 LR,则损耗降低得太慢


基本上,我只是想理解为什么学习率在这两个片段中的含义非常不同,而这两个片段在其他方面是等效的。

关键的区别在于权重的初始化。a
nn.Linear
中的权重矩阵。我敢肯定,如果你同时构建模型,并以这样或那样的方式复制权重矩阵,你会得到一致的行为


此外,请注意,这两种模型并不等同,因为您的手工模型缺少偏差。这一点。

谢谢,这很有帮助。我怀疑在这种情况下,初始化没有手动情况下的偏差重要。但不管怎样,这都足以补充我的解释。我并不完全需要它们是相同的,只是为了能够解释它们为什么不同。哦,我会把我的大部分钱放在初始化上,因为初始化是关键;-)请参考反向传播公式,了解将权重矩阵乘以常数时梯度会发生什么情况。。。而目标函数保持不变。从说明的角度来看,我认为仔细初始化手动模型并观察它如何突然变得更容易训练是非常酷的;-)在最终学会注意初始化之前,我已经多次击中自己的脚。