首页 文章

Tensorflow加权与S形交叉熵损失

提问于
浏览
0

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

解决问题的最佳方法应该是使用 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)

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

请参阅相关问题here .

1 回答

  • 1

    在丢失函数之后可能会抛出错误,因为 tf.losses.sigmoid_cross_entropytf.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)
    

    张量 logitslabels 是一种人造的,都具有形状 (10,) . 但重要的是 weighted_losssigmoid_loss 是不同的 . 这是输出:

    (10,)
    ()
    

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

    如果这没有帮助,请确保 labels tensor的类型为 float32 . 这个bug非常容易制作,例如,以下声明不起作用:

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

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

相关问题