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

PyTorch中nn.CrossEntropyLoss仅返回-0.0?训练损失始终为零的问题

CrossEntropyLoss返回0及训练损失恒为0的问题

问题1:torch.nn.CrossEntropyLoss()(torch.Tensor([0]), torch.Tensor([1]))返回tensor(-0.)的原因

PyTorch的CrossEntropyLoss有两个核心要求你没注意到:

  • 输入规则:第一个参数(模型输出)需为[batch_size, num_classes]形状,代表每个样本在不同类别上的预测得分;第二个参数(标签)必须是类别索引(整数类型),范围是0到num_classes-1,不能是浮点型或超出索引范围的值。
  • 你传入的输出是单元素张量(相当于1个类别),标签1超出了0到0的合法索引范围,属于非法输入,导致计算出现数值异常,最终返回了-0.0。

问题2:训练时损失始终为零的原因

结合代码和数据处理,核心问题是损失函数、模型输出、标签三者完全不匹配:

  1. 损失函数选型错误:CrossEntropyLoss适用于多分类任务,要求模型输出通道数等于类别数(二分类需输出2个通道),但你设置S3=1,单通道输出完全不符合该损失函数的要求。
  2. 标签格式错误:你把标签处理成了[[0], [1]]的浮点型二维张量,但CrossEntropyLoss需要的是一维整数张量(比如[0,1])。
  3. 模型输出激活错误:最后一层用ReLU会截断负得分,而CrossEntropyLoss要求输入是未经过Softmax的原始得分(logits),ReLU的截断会导致损失计算异常。

修复方案

方案1:继续使用CrossEntropyLoss(标准二分类)

  1. 调整模型结构:将S3设为2,去掉最后一层的ReLU:
def forward(self, x):
    x = F.relu(self.linear1(x))
    x = self.linear2(x)  # 输出原始logits,无需ReLU
    return x
  1. 修正标签格式:转为一维整数张量,无需嵌套列表:
y_train = torch.from_numpy(y_train).type(torch.LongTensor)
y_val = torch.from_numpy(y_val).type(torch.LongTensor)
y_test = torch.from_numpy(y_test).type(torch.LongTensor)

方案2:改用BCELoss(单输出二分类)

如果坚持用单通道输出,可切换为适合二分类的BCELoss:

  1. 调整模型结构:最后一层加Sigmoid激活:
def forward(self, x):
    x = F.relu(self.linear1(x))
    x = F.sigmoid(self.linear2(x))
    return x
  1. 损失函数替换:
loss_fn = nn.BCELoss()

内容的提问来源于Stack Exchange,提问作者Selvi7

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:15:31