我正在尝试让 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 可以解释吗?可以采取哪些措施来修复代码以解决问题?谢谢您的宝贵时间!!
在 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”作为标签是不可能的。nan
,并在(我的)CPU 上引发错误。
我检查了链接的存储库,它有 a config,默认为
NUM_CLASSES=1
。您是否将其重写为您案例中正确的类数?