使用torch.nn.CrossEntropyLoss时多目标张量报错求助
解决CrossEntropyLoss的多目标报错问题
首先明确两个关键矛盾和错误点:
- 你提到“二分类任务”但要求模型输出4个logits对应4类概率,这两者不匹配——二分类只需要2个logits,4个logits对应4分类任务。
torch.nn.CrossEntropyLoss()不支持one-hot格式的目标张量,它要求目标是1D的类别索引(每个元素是0到类别数-1的整数),而你的target.shape = torch.Size([1,2])是one-hot格式,这是报错的直接原因。
针对不同任务的解决方案
情况1:实际是4分类任务(输出4个logits)
你的模型输出[1,4]对应4个类别,此时需要将目标张量转换为1D的类别索引:
- 如果你的
graphs.y是4分类的one-hot编码(应为[1,4]维度,可能你描述有误),用torch.argmax()提取类别索引:# 假设graphs.y是[batch_size, 4]的one-hot张量 target = torch.argmax(graphs.y, dim=1) # 得到[batch_size,]的1D张量 loss = criterion(out, target) - 如果你的
graphs.y确实是[1,2]维度,说明数据标注或预处理错误,需要修正目标张量为4分类对应的类别索引(0-3)。
情况2:实际是二分类任务
此时模型输出应该调整为[1,2](2个logits),同时处理目标张量:
- 如果目标是one-hot格式
[1,2],转换为类别索引:target = torch.argmax(graphs.y, dim=1) # 得到[1,]的1D张量 loss = criterion(out, target) - 或者直接使用
torch.nn.BCEWithLogitsLoss()(适配二分类的one-hot目标),无需转换目标格式:criterion = nn.BCEWithLogitsLoss() # 模型输出需调整为[1,1]或[1,2],对应单标签/多标签二分类 loss = criterion(out, graphs.y.float())
为什么你之前的尝试无效?
graphs.y.squeeze:把[1,2]变成[2,],但这仍然是包含2个元素的张量,不是类别索引,CrossEntropyLoss仍会判定为多目标。torch.max(graphs.y, 1)[0]:提取的是one-hot中的最大值(比如1),而非类别索引(0或1),目标元素值不符合损失函数的要求。
内容的提问来源于stack exchange,提问作者Tony Sirico
相关产品推荐
相关产品推荐

