You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PyTorch CrossEntropyLoss权重张量与类别数量不匹配报错问题求助

解决CrossEntropyLoss权重报错及NaN问题

首先,你的核心错误是权重张量长度和类别数不匹配,这完全是一个笔误导致的:

在你的代码里,权重列表写的是:

class_weights = torch.tensor([0.1, 1.0, 1.0, 1,0, 1.0], ...)

注意这里的1,0——这是用逗号分隔的两个独立数值(1和0),而不是你想写的1.0!这就导致你的权重张量一共有6个元素,但你的任务是5分类(类别0-4),PyTorch要求权重必须覆盖所有C个类别,所以才会抛出weight tensor should be defined either for all or no classes的错误。

第一步:修正笔误

把权重里的1,0改成1.0,让权重张量长度严格等于5:

class_weights = torch.tensor([0.1, 1.0, 1.0, 1.0, 1.0], dtype=torch.float16, device=result.device)

这样权重就对应了类别0到4,和你的输出通道数(5)完全匹配,这个报错应该就会消失。

关于NaN问题的补充

你提到调整权重为4个元素时代码能运行但出现NaN,这是因为4个权重只覆盖了类别0-3,类别4没有对应的权重,加上你使用float16精度(数值范围远小于float32,容易出现下溢/上溢),就很容易触发NaN。

解决NaN的建议:

  • 先切换到float32调试,确认损失计算逻辑正常后,再尝试float16;
  • 如果必须用float16,建议使用PyTorch的自动混合精度(torch.cuda.amp),它能自动管理不同张量的精度,减少数值不稳定的情况;
  • 当使用ignore_index=0时,确保权重和类别数匹配的前提下设置,这个参数会忽略类别0的损失计算,和你降低类别0权重的目标是一致的,可以结合使用。

关于PyTorch版本的建议

你当前使用的1.9.0版本确实比较老旧,新版本(比如1.12及以上)对这类参数不匹配的错误提示会更清晰,同时对混合精度训练的支持也更完善,建议升级到稳定版来避免一些潜在的旧版本问题。

验证最小复现示例

你的loss_func_fails里同样存在1,0的笔误,修正后就能正常运行。比如把权重改成:

class_weights = torch.tensor([0.1, 1.0, 1.0, 1.0, 1.0], dtype=torch.float32, device=result.device)

再运行loss_func_fails就不会报错了。

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

火山引擎 最新活动