tf.nn.sparse_softmax_cross_entropy_with_logits() 输出与 nan

问题描述 投票:0回答:1

我正在尝试让 Mask-RCNN 与张量流一起运行。迄今为止,训练运行时没有任何错误消息(例如

TypeError: unhashable type: 'ListWrapper'
)的唯一变体来自此处:https://github.com/maxw1489/Mask_RCNN(使用tensorflow 2.9.1)。然而,存在损失计算不正确的问题。到目前为止,我已经能够隔离错误,即
mrcnn_class_loss = nan
的输出。如果你进入计算这个损失的函数(
def mrcnn_class_loss_graph(target_class_ids, pred_class_logits, active_class_ids)
),那么关键点就是
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=target_class_ids, logits=pred_class_logits)

我分析了此函数的输入,并创建了以下代码片段,用

nan
演示了此行为:

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 可以解释吗?可以采取哪些措施来修复代码以解决问题?谢谢您的宝贵时间!!

tensorflow nan mask-rcnn
1个回答
0
投票

在 CPU 和 GPU 上测试代码后,我发现了一些有趣的地方。在 CPU 上,我收到以下错误:

tensorflow.python.framework.errors_impl.InvalidArgumentError: {{function_node _wrapped__SparseSoftmaxCrossEntropyWithLogits_device/job:localhost/replica:0/task:0/device:CPU:0}} 收到的标签值 2 超出了有效范围范围为 [0, 1)。 标签值:2 1 1 0 [Op:SparseSoftmaxCrossEntropyWithLogits] 名称:

有趣的是,这个错误并不与 GPU 相关。在那里,出现的是 nan 值。

似乎在 CPU 上会显式检查一个预测的 logits 向量是否足够长以使所有标签成为可能。让我向您展示一个修改后的代码的示例:

target_class_ids = tf.Variable(np.array([[2, 3, 1, 0]]), dtype=np.int32)
pred_class_logits = tf.Variable(np.array([[
    [-0.0738682151,  -0.0052,  0.78],
     [-0.0405795932, -0.0215,  0.32],
     [-1.68359947,   -0.54,   -5.6],
     [-2.13260722,   -0.111,   0.45]]], dtype=np.float32))
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(
      labels=target_class_ids, logits=pred_class_logits)
print(loss)
tf.Tensor([[0.63222516        nan 0.2814241  3.081086  ]], shape=(1, 4), dtype=float32)

CPU输出(重要部分):

收到标签值 3,超出了 [0, 3) 的有效范围。 标签值:2 3 1 0 [Op:SparseSoftmaxCrossEntropyWithLogits] 名称:

在这里,我稍微修改了标签,并使每个预测的 logits 向量更长。
注意到

nan
标签索引处的
3
值了吗?因为每次预测有 3 个逻辑,所以只有 3 个标签 (0, 1, 2) 可以作为输出。在 CPU 上,这是明确告知的。仅使用长度为 3 的 Logits 向量,“3”作为标签是不可能的。
在您的示例中,每个预测的 logits 向量的长度仅为 1。因此,每个大于“0”的标签都会转到 GPU 上的
nan
,并在(我的)CPU 上引发错误。


我检查了链接的存储库,它有 a config,默认为

NUM_CLASSES=1
。您是否将其重写为您案例中正确的类数?

© www.soinside.com 2019 - 2024. All rights reserved.