我目前正在尝试编写一些教学材料,其中我借用了一些在网上多次重做的常见例子。
我有一个简单的代码,我手动为图层创建张量,并在循环中更新它们。例如。:
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,则损失减少得太慢。
基本上我只是想了解为什么学习率在这两个片段中意味着非常不同的东西,否则这些片段是等价的。
关键的区别在于权重的初始化。 nn.Linear
is initialized smart中的重量矩阵。我很确定如果你构建两个模型并以一种方式复制权重矩阵,你将获得一致的行为。
另外,请注意这两个型号不相同,因为您的手工模型缺乏偏见。哪个matters。