You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch训练CNN时报错「含多个值的张量布尔值模糊」如何解决

错误原因
  • 维度不匹配:你的模型是7分类任务,前向传播输出的scores张量维度为[batch_size, 7],遍历scores时取出的每个元素是长度为7的张量,直接用多值张量和0.5做比较时,PyTorch无法确定要返回哪个位置的布尔值,因此触发报错。
  • 逻辑不符合多分类规则:0.5阈值是二分类的判断逻辑,多分类任务应该取概率最高的类别作为预测结果,而不是用固定阈值判断。
  • 损失函数选择错误:你当前使用的nn.BCELoss()是为二分类、多标签分类场景设计的,不适用于单标签多分类任务,后续也会引发维度匹配错误。
解决方案
  1. 修正预测逻辑
    删除原有的列表推导式生成预测值的代码,使用argmax取概率最高的类别索引作为预测结果:
# 替换原predictions行代码,dim=1表示在类别维度取最大值的索引
predictions = scores.argmax(dim=1)

如果你的标签y是one-hot编码格式,需要同步转成类别索引再做比对:

y = y.argmax(dim=1)
  1. 修正损失函数配置
    优先选择更适配多分类的CrossEntropyLoss,不需要手动加softmax层,避免数值不稳定问题:
  • 首先修改模型的forward方法,删除最后的softmax层:
def forward(self, x):
    # 前面的层代码不变
    x = self.outLayer(x)
    # 删掉原来的softmax行,直接返回x
    return x
  • 然后修改损失函数定义:
# 替换原来的BCELoss定义
criterion = nn.CrossEntropyLoss()

如果坚持要保留softmax输出,可将损失换成nn.NLLLoss,同时把softmax改成F.log_softmax(x, dim=1)即可。

  1. 优化准确率计算代码
    替换原有check_accuracy函数中循环后的比对逻辑,全程用张量运算提升效率:
def check_accuracy(loader, model):
    if loader == train_loader:
        print("Checking accuracy on training data")
    else:
        print("Checking accuracy on validation data")

    num_correct = 0
    num_samples = 0
    model.eval()

    with torch.no_grad():
        for x, y in loader:
            x = x.to(device=device)
            y = y.to(device=device)
            # 如果y是one-hot格式,取消注释下面这行
            # y = y.argmax(dim=1)

            scores = model(x)
            predictions = scores.argmax(dim=1)
            num_correct += (predictions == y).sum()
            num_samples += predictions.size(0)
    acc = float(num_correct) / float(num_samples) * 100
    print(f"Got {num_correct} / {num_samples} with accuracy {acc:.2f}")
    return f"{acc:.2f}"

内容的提问来源于stack exchange,提问作者Deffo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 04:54:03