1

我当前使用的代码sparse_softmax_cross_entropy工作正常。

loss_normal = (
    tf.reduce_mean(tf.losses
                   .sparse_softmax_cross_entropy(labels=labels,
                                                 logits=logits,
                                                 weights=class_weights))
    )

但是,当我尝试使用hinge_loss

loss_normal = (
    tf.reduce_mean(tf.losses
                   .hinge_loss(labels=labels,
                               logits=logits,
                               weights=class_weights))
    )

它报告了一个错误说:

ValueError: Shapes (1024, 2) and (1024,) are incompatible

该错误似乎源于losses_impl.py文件中的此函数:

  with ops.name_scope(scope, "hinge_loss", (logits, labels)) as scope:
    ...
    logits.get_shape().assert_is_compatible_with(labels.get_shape())
    ...

我修改了我的代码如下,只提取 logits 张量的 1 列:

loss_normal = (
    tf.reduce_mean(tf.losses
                   .hinge_loss(labels=labels,
                               logits=logits[:,1:],
                               weights=class_weights
                               ))
    )

但它仍然报告类似的错误:

ValueError: Shapes (1024, 1) and (1024,) are incompatible.

有人可以帮忙指出为什么我的代码可以正常工作,sparse_softmax_cross_entropy但不能正常工作hinge_loss吗?

4

1 回答 1

1

张量labels有形状[1024],张量logits[1024, 2]形状。这适用于tf.nn.sparse_softmax_cross_entropy_with_logits

  • 标签:形状 [d_0, d_1, ..., d_{r-1}] 的张量(其中 r 是标签和结果的等级)和 dtype int32 或 int64。标签中的每个条目必须是 [0, num_classes) 中的索引。当此操作在 CPU 上运行时,其他值将引发异常,并为 GPU 上的相应损失和梯度行返回 NaN。
  • logits:形状 [d_0, d_1, ..., d_{r-1}, num_classes] 和 dtype float32 或 float64 的未缩放对数概率。

tf.hinge_loss要求不同:

  • 标签:地面实况输出张量。它的形状应该与 logits 的形状相匹配。张量的值预计为 0.0 或 1.0。
  • logits:logits,一个浮点张量。

您可以通过两种方式解决此问题:

  • 将标签重塑为[1024, 1]并仅使用一行logits,就像您所做的那样 - logits[:,1:]

    labels = tf.reshape(labels, [-1, 1])
    hinge_loss = (
        tf.reduce_mean(tf.losses.hinge_loss(labels=labels,
                                            logits=logits[:,1:],
                                            weights=class_weights))
        )
    

    我认为你也需要以class_weights同样的方式重塑。

  • 通过 使用所有学习到的logits特征tf.reduce_sum,这将形成一个平坦的(1024,)张量:

    logits = tf.reduce_sum(logits, axis=1)
    hinge_loss = (
        tf.reduce_mean(tf.losses.hinge_loss(labels=labels,
                                            logits=logits,
                                            weights=class_weights))
        )
    

    这样你就不需要重塑labelsclass_weights.

于 2017-11-08T11:09:56.787 回答