模型的输出取决于权重张量的形状
Output of the model depends on the shape of the weights tensor
我想训练模型对三个输入求和。所以越简单越好。
首先权重是随机初始化的。它产生错误的错误估计(大约 0.5)
然后我用零初始化权重。有两个选项:
- 权重张量的形状是 [1, 3]
- 权重张量的形状是[3]
当我选择第一个选项时,模型仍然无法正常工作,无法学习这个简单的公式。
当我选择第二个选项时,它完美地解决了 10e-12 的错误。
为什么结果取决于权重的形状?为什么我需要用零初始化模型来解决这个简单的问题?
import torch
from torch.nn import Sequential as Seq, Linear as Lin
from torch.optim.lr_scheduler import ReduceLROnPlateau
X = torch.rand((1024, 3))
y = (X[:,0] + X[:,1] + X[:,2])
m = Seq(Lin(3, 1, bias=False))
# 1 option
m[0].weight = torch.nn.parameter.Parameter(torch.tensor([[0, 0, 0]], dtype=torch.float))
# 2 option
#m[0].weight = torch.nn.parameter.Parameter(torch.tensor([0, 0, 0], dtype=torch.float))
optim = torch.optim.SGD(m.parameters(), lr=10e-2)
scheduler = ReduceLROnPlateau(optim, 'min', factor=0.5, patience=20, verbose=True)
mse = torch.nn.MSELoss()
for epoch in range(500):
optim.zero_grad()
out = m(X)
loss = mse(out, y)
loss.backward()
optim.step()
if epoch % 20 == 0:
print(loss.item())
scheduler.step(loss)
第一个选项没有学习,因为它失败并显示 :而 out.shape == (1024, 1)
对应的目标 y
具有 (1024, )
的形状。正如预期的那样,MSELoss 计算张量的均值 (out - y)^2
,在本例中其形状为 (1024, 1024)
,对于此任务来说显然是错误的 objective。同时,在应用第二个选项后,张量 (out - y)^2
的大小为 (1024, )
,其均值对应于实际 mse。如果在定义 y
.
之后通过 y = y.unsqueeze(-1)
将目标形状设置为 (1024, 1)
,则默认方法无需显式更改权重形状(通过选项 1 和 2)。
我想训练模型对三个输入求和。所以越简单越好。
首先权重是随机初始化的。它产生错误的错误估计(大约 0.5)
然后我用零初始化权重。有两个选项:
- 权重张量的形状是 [1, 3]
- 权重张量的形状是[3]
当我选择第一个选项时,模型仍然无法正常工作,无法学习这个简单的公式。
当我选择第二个选项时,它完美地解决了 10e-12 的错误。
为什么结果取决于权重的形状?为什么我需要用零初始化模型来解决这个简单的问题?
import torch
from torch.nn import Sequential as Seq, Linear as Lin
from torch.optim.lr_scheduler import ReduceLROnPlateau
X = torch.rand((1024, 3))
y = (X[:,0] + X[:,1] + X[:,2])
m = Seq(Lin(3, 1, bias=False))
# 1 option
m[0].weight = torch.nn.parameter.Parameter(torch.tensor([[0, 0, 0]], dtype=torch.float))
# 2 option
#m[0].weight = torch.nn.parameter.Parameter(torch.tensor([0, 0, 0], dtype=torch.float))
optim = torch.optim.SGD(m.parameters(), lr=10e-2)
scheduler = ReduceLROnPlateau(optim, 'min', factor=0.5, patience=20, verbose=True)
mse = torch.nn.MSELoss()
for epoch in range(500):
optim.zero_grad()
out = m(X)
loss = mse(out, y)
loss.backward()
optim.step()
if epoch % 20 == 0:
print(loss.item())
scheduler.step(loss)
第一个选项没有学习,因为它失败并显示 out.shape == (1024, 1)
对应的目标 y
具有 (1024, )
的形状。正如预期的那样,MSELoss 计算张量的均值 (out - y)^2
,在本例中其形状为 (1024, 1024)
,对于此任务来说显然是错误的 objective。同时,在应用第二个选项后,张量 (out - y)^2
的大小为 (1024, )
,其均值对应于实际 mse。如果在定义 y
.
y = y.unsqueeze(-1)
将目标形状设置为 (1024, 1)
,则默认方法无需显式更改权重形状(通过选项 1 和 2)。