【问题标题】:Tensorflow weighted vs sigmoid cross-entropy lossTensorflow 加权与 sigmoid 交叉熵损失
【发布时间】:2018-05-31 19:16:11
【问题描述】:

我正在尝试使用 TensorFlow 实现多标签分类(即,每个输出模式可以有许多活动单元)。问题在于类别不平衡(即,标签分布中的零比零多得多,这使得标签模式非常稀疏)。

解决问题的最佳方法应该是使用tf.nn.weighted_cross_entropy_with_logits 函数。但是,我收到此运行时错误:

ValueError: Tensor conversion requested dtype uint8 for Tensor with dtype float32

我不明白这里有什么问题。作为损失函数的输入,我传递了标签张量、logits 张量和正类权重,这是一个常数:

positive_class_weight = 10
loss = tf.nn.weighted_cross_entropy_with_logits(targets=labels, logits=logits, pos_weight=positive_class_weight)

关于如何解决这个问题的任何提示?如果我只是将相同的标签和 logits 张量传递给 tf.losses.sigmoid_cross_entropy 损失函数,那么一切正常(在 Tensorflow 运行正常的意义上,但当然训练预测总是为零)。

查看相关问题here。

【问题讨论】:

    标签: tensorflow deep-learning multilabel-classification cross-entropy


    【解决方案1】:

    错误很可能在损失函数之后抛出,因为tf.losses.sigmoid_cross_entropy和tf.nn.weighted_cross_entropy_with_logits之间唯一显着的区别是返回张量的形状。

    看看这个例子:

    logits = tf.linspace(-3., 5., 10)
    labels = tf.fill([10,], 1.)
    
    positive_class_weight = 10
    weighted_loss = tf.nn.weighted_cross_entropy_with_logits(targets=labels, logits=logits, pos_weight=positive_class_weight)
    print(weighted_loss.shape)
    
    sigmoid_loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=labels, logits=logits)
    print(sigmoid_loss.shape)
    

    张量logits 和labels 是一种人造的,并且都具有(10,) 的形状。但重要的是weighted_loss 和sigmoid_loss 是不同的。这是输出:

    (10,)
    ()
    

    这是因为tf.losses.sigmoid_cross_entropy 执行归约(默认情况下为总和)。所以为了复制它,你必须用tf.reduce_sum(...)包裹加权损失。

    如果这没有帮助,请确保 labels 张量的类型为 float32。这个错误很容易产生,例如,以下声明将不起作用:

    labels = tf.fill([10,], 1)  # the type is not float!
    

    您可能也有兴趣阅读this question。

    【讨论】:

    • 非常感谢,这解决了问题。我必须将标签显式转换为float32,并使用tf.reduce_sum(...) 减少损失输出。
    猜你喜欢
    • 2021-11-25
    • 2016-08-01
    • 2017-11-11
    • 2017-03-14
    • 2018-01-31
    • 1970-01-01
    • 2017-12-26
    • 2019-06-19
    • 2021-02-03
    相关资源
    最近更新 更多