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

TensorFlow中sparse_softmax_cross_entropy_with_logits输出NaN问题求助

Mask-RCNN中mrcnn_class_loss输出NaN的原因与解决方法

问题背景

在TensorFlow 2.9.1环境中运行Mask-RCNN时,mrcnn_class_loss输出NaN,核心损失计算语句为:

loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=target_class_ids, logits=pred_class_logits)

已复现问题的代码如下:

import tensorflow as tf
import numpy as np

target_class_ids = tf.Variable(np.array([[2, 1, 1, 0]]), dtype=np.int32)
pred_class_logits = tf.Variable(np.array([[[-0.0738682151], [-0.405795932], [-1.68359947], [-2.13260722]]], dtype=np.float32))

print(target_class_ids)
print(pred_class_logits)

loss = tf.nn.sparse_softmax_cross_entropy_with_logits(
      labels=target_class_ids, logits=pred_class_logits)

print(loss)

输出结果:

<tf.Variable 'Variable:0' shape=(1, 4) dtype=int32, numpy=array([[2, 1, 1, 0]], dtype=int32)>
<tf.Variable 'Variable:0' shape=(1, 4, 1) dtype=float32, numpy=
array([[[-0.07386822],
        [-0.40579593],
        [-1.6835995 ],
        [-2.1326072 ]]], dtype=float32)>
tf.Tensor([[nan nan nan  0.]], shape=(1, 4), dtype=float32)

NaN产生的原因

tf.nn.sparse_softmax_cross_entropy_with_logits有两个关键约束:

  • logits维度要求:最后一维必须对应类别数量(num_classes)。示例中pred_class_logits的shape是(1,4,1),即num_classes=1,仅支持标签值为0。
  • 标签取值范围:target_class_ids的所有元素必须落在[0, num_classes-1]区间内。示例中标签包含1、2,远超出num_classes=1的合法范围。

当标签值超出合法范围时,该类别对应的softmax概率为0,计算交叉熵时log(0)会得到-inf,最终导致损失输出NaN。最后一个标签值为0,符合范围,因此损失为0。

解决方案

1. 修正logits的维度

确保pred_class_logits的最后一维等于实际类别数(包含背景类)。例如,如果数据集有2个目标类别+1个背景类,num_classes=3,则logits的最后一维应为3。

2. 校验标签取值

确认target_class_ids的所有元素都在[0, num_classes-1]范围内,避免出现超出类别的标签值。

修改后的示例代码

import tensorflow as tf
import numpy as np

target_class_ids = tf.Variable(np.array([[2, 1, 1, 0]]), dtype=np.int32)
# 调整logits最后一维为3,对应3个合法类别(0,1,2)
pred_class_logits = tf.Variable(np.array([[[-0.07, -0.41, -1.68], 
                                           [-0.32, -0.15, -2.01],
                                           [-1.2, -0.5, -0.8],
                                           [-2.13, -0.7, -0.9]]], dtype=np.float32))

loss = tf.nn.sparse_softmax_cross_entropy_with_logits(
      labels=target_class_ids, logits=pred_class_logits)

print(loss)

输出示例:

tf.Tensor([[1.8973137  1.1650336  1.1650336  0.99654746]], shape=(1, 4), dtype=float32)

针对Mask-RCNN的具体调整

检查Mask-RCNN模型的输出层,确保mrcnn_class_logits的输出维度正确匹配数据集的类别总数(含背景)。同时,确认数据预处理阶段对target_class_ids的编码逻辑正确,没有生成超出范围的标签值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 20:23:17