对我来说,标签的维度应该与神经网络的最后一层的维度相同,这很直观。然而,通过使用PyTorch的一些实验,结果证明它在某种程度上是有效的。
代码:
import torch
import torch.nn as nn
X = torch.tensor([[1],[2],[3],[4]], dtype=torch.float32) # training input
Y = torch.tensor([[2],[4],[6],[8]], dtype=torch.float32) # training label
model = nn.Linear(1,3)
learning_rate = 0.01
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
for epoch in range(10):
y_pred model(X)
loss = nn.MSELoss(Y, y_pred)
loss.backward()
optimizer.zero_grad()
optimizer.step()
在上面的代码中,用model = nn.Linear(1,3)
代替model = nn.Linear(1,1)
。因此,当Y.shape为(4,1)时,y_pred。形状为(4,3)。
代码工作时带有一个警告:使用与输入大小不同的目标大小可能会由于广播而导致不正确的结果。">
当我执行model(torch.tensor([10], dtype=torch.float32))
时,我得到了以下输出:
tensor([20.0089, 19.6121, 19.1967], grad_fn=<AddBackward0>)
三个输出对我来说似乎都是正确的。但是如果数据大小不同,损失是如何计算的呢?
我们是否应该在任何情况下使用与输入大小不同的目标大小?这样做有什么好处吗?
假设您正在使用batch_size=4
,您正在使用1
组件与3
组件的目标来预测张量。在使用nn.MSELoss
计算损失时,您实际上看不到中间结果,使用reduction='none'
选项将允许您这样做:
>>> criterion = nn.MSELoss(reduction='none')
>>> y = torch.rand(2,1)
>>> y_hat = torch.rand(2,3)
>>> criterion(y_hat, y).shape
(2, 3)
考虑到这一点,你可以得出结论,目标y
太小,已经广播到预测张量y_hat
。实际上,在您的示例中,您将得到与
>>> y_repeat = y.repeat(1, 3)
>>> criterion(y_hat, y_repeat)
这意味着,对于每个批处理,您针对单个值对其所有组件进行l2优化:MSE(y_hat[0,0], y[0])
,MSE(y_hat[0,1], y[0])
和MSE(y_hat[0,2], y[0])
,y[1]
和y[2]
也是如此。
这个警告是为了确保你意识到这个广播操作。也许这就是你想要做的,在这种情况下,你应该自己传播目标张量。否则,这样做就没有意义了。