ValueError:目标和输入必须具有相同数量的元素。目标 nelement (50) != 输入 nelement (100)
Posted
技术标签:
【中文标题】ValueError:目标和输入必须具有相同数量的元素。目标 nelement (50) != 输入 nelement (100)【英文标题】:ValueError: Target and input must have the same number of elements. target nelement (50) != input nelement (100) 【发布时间】:2020-07-27 02:23:19 【问题描述】:我是 Pytorch 的新手,所以我尝试通过创建简单的狗与猫分类来学习它。 代码:
class DogCatClassifier(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 32, 5)
self.conv2 = nn.Conv2d(32, 64, 5)
self.conv3 = nn.Conv2d(64, 128, 5)
self.fc1 = nn.Linear(512, 256)
self.fc2 = nn.Linear(256, 2)
def forward(self, x):
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
print("1-st: ", x.shape)
x = F.max_pool2d(F.relu(self.conv2(x)), (2, 2))
print("2-nd: ", x.shape)
x = F.max_pool2d(F.relu(self.conv3(x)), (2, 2))
print("3-rd: ", x.shape)
x = torch.flatten(x, start_dim=1)
x = F.relu(self.fc1(x))
print("6-th: ", x.shape)
x = self.fc2(x) # bc this is our output layer. No activation here.
print("7-th: ", x.shape)
x = F.sigmoid(x)
print("8-th: ", x.shape)
return x
我传递的是单批数据(数据形状为(50, 1, 50, 50)
model = DogCatClassifier()
images, labels = next(iter(train_loader))
preds = model(images)
print(pred)
loss = F.binary_cross_entropy(preds, labels)
我的预测形状是 (50, 2),所以据我了解,F.binary_cross_entropy(preds, labels) 检查来自单个图像的两个预测,这就是为什么我针对 50 个标签得到 100 个预测。来自 tensorflow,我认为我可以实现相同的逻辑,例如使用 sigmoid 作为最后一次激活,使用 binary_cross_entropy 作为损失函数。我不明白的是如何使这段代码工作。
【问题讨论】:
【参考方案1】:您的问题出现是因为您使用的是二元交叉熵而不是常规交叉熵。顾名思义,它会检查标签是否正确,因此两个张量(代码中的预测和标签)的形状应该相同。当您对两个类都充满信心时,BCE 损失函数会变得混乱并且代码崩溃。你可以做两件事:
1- 更改为 F.cross_entropy(preds, label) 作为您的损失函数。
2- 更改代码以选择最大值作为目标。
pred = pred.argmax(dim=1, keepdim=True) # gets the max value
让我知道这是否有效,如果无效,请更新新错误。
【讨论】:
更改为 F..cross_entropy(preds, label) 有效,但由于某种原因,当损失达到约 0.65 时,无论经过多少个时期,它都不会下降。至于(2-更改代码以选择最大值作为目标。)我得到 RuntimeError: _thnn_binary_cross_entropy_forward not supported on CUDAType for Long Pytorch 实现中交叉熵的最小值永远不会为 0。如果需要,您可以通过提供相同张量的副本自行检查。重要的事实是它有一个全局最小值。如果您的 NN 没有低于该值,则意味着它已达到全局最小值或卡在局部最小值上。我的建议是使用调度程序以确保它跳出局部最小值。或者(更容易)通过使用更多的卷积层使其更深。 谢谢,我会试试的。如果我在优化器上设置动力会有帮助吗? 至于解决方案2,我从内存中写了那行,它取最大值,你应该取最大值的索引,即0或1。我无法搜索如何做到这一点现在,但谷歌支持你。 是的,动量肯定会有所帮助,如果您使用 SGD,可以尝试更复杂的东西,例如 ADAM 或 RMSprop。以上是关于ValueError:目标和输入必须具有相同数量的元素。目标 nelement (50) != 输入 nelement (100)的主要内容,如果未能解决你的问题,请参考以下文章
Pytorch 闪电指标:ValueError:preds 和 target 必须具有相同数量的维度,或者 preds 的一个额外维度
连接两个 NumPy 数组给出“ValueError:所有输入数组必须具有相同的维数”
ValueError: 目标尺寸 (torch.Size([128])) 必须与输入尺寸 (torch.Size([112])) 相同