我正在尝试创建一个最简单的1线性层网络以适应线性回归。只是为了帮助自己更好地了解Pytorch的工作原理。但是,我在模型训练中遇到了一个奇怪的问题。
在模型的init()方法中,我必须添加一个手动初始化步骤(如下所示),以使模型快速收敛到我的回归函数。 (权重值2、3是随机数,我可以在此处输入任何值,模型仍会收敛)
self.layer1.weight = torch.nn.Parameter(torch.Tensor([2, 3]))
没有这条线,模型永远不会收敛,训练损失只是随机地在数十万范围内波动。有了这条线,它迅速减小到接近1。
我推测这是因为如果我不将默认初始权重参数初始化为距离零较远的话,则它们会太小。然后,我更改了初始值,发现只要有这条线,收敛就始终有效,我设置的确切值并不重要。我尝试使用调试器单步执行此行,并使用 vars()方法检查 self.layer1 的属性,唯一改变的是权重,其他所有内容相同。有人可以解释一下幕后发生的事情吗?谢谢。
我的整个脚本:
import torch
import numpy as np
class Net(torch.nn.Module):
def __init__(self, input_dim, output_dim):
super(Net, self).__init__()
self.layer1 = torch.nn.Linear(input_dim, output_dim, bias=False)
# the line below is the strange initialization required to
# have the model converge.
self.layer1.weight = torch.nn.Parameter(torch.Tensor([2, 3]))
def forward(self, x):
x = self.layer1(x)
return x
# generate data using the linear regression setup y = 5 * x1 + 3 * x2
sample_size = 10000
input_dim = 2
output_dim = 1
epoch = 30
bs = 100
data = np.random.randn(sample_size, 3)
data[:, :2] = data[:, :2] * 100
# add a normal noise term
data[:, 2] = 5 * data[:, 0] + 3 * data[:, 1] + np.random.randn(sample_size)
data = torch.Tensor(data)
train_x = data[:, :input_dim]
train_y = data[:, input_dim]
net = Net(input_dim, output_dim)
criterion = torch.nn.MSELoss()
optimizer = torch.optim.RMSprop(net.parameters(), lr=.01)
for i in range(epoch):
batch = 0
while batch * bs < train_x.shape[0]:
batch_x = train_x[batch * bs : (batch + 1) * bs, :]
batch_y = train_y[batch * bs : (batch + 1) * bs]
pred_y = net.forward(batch_x)
loss = criterion(pred_y, batch_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if batch % 100 == 0:
#print(f"{i} {batch} {loss}")
print(net.layer1.weight)
batch += 1
答案 0 :(得分:0)
快速提示:您的代码无法编译,请如下所示修改此行:
self.layer1.weight = torch.nn.Parameter(torch.Tensor([[2, 3]]))
无论权重初始化如何,我都无法使您的模型收敛。经过一些实验,我发现将批处理大小减小到一个就可以了:
$ python main.py
Parameter containing:
tensor([[0.7388, 0.3678]], requires_grad=True)
Parameter containing:
tensor([[1.7438, 1.0657]], requires_grad=True)
Parameter containing:
tensor([[2.3338, 1.5431]], requires_grad=True)
Parameter containing:
tensor([[2.9008, 1.9784]], requires_grad=True)
Parameter containing:
tensor([[3.2375, 2.1437]], requires_grad=True)
Parameter containing:
tensor([[3.6419, 2.4014]], requires_grad=True)
Parameter containing:
tensor([[4.0652, 2.6458]], requires_grad=True)
Parameter containing:
tensor([[4.5095, 2.7628]], requires_grad=True)
Parameter containing:
tensor([[4.7711, 2.8982]], requires_grad=True)
Parameter containing:
tensor([[4.9131, 2.9768]], requires_grad=True)
Parameter containing:
tensor([[4.9887, 2.9979]], requires_grad=True)
...