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 的一个额外维度

ValueError:所有输入数组必须具有相同的维数

连接两个 NumPy 数组给出“ValueError:所有输入数组必须具有相同的维数”

ValueError: 目标尺寸 (torch.Size([128])) 必须与输入尺寸 (torch.Size([112])) 相同

ValueError:所有输入数组必须具有相同的维数

Numpy hstack - “ValueError:所有输入数组必须具有相同的维数” - 但它们确实如此