[英]why this model fail to converge without manual weight initialization step (pytorch linear regression)
我正在尝试创建最简单的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
快速说明:您的代码无法编译,请如下所示修改此行:
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)
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.