当我在 tensorflow.keras 中使用 BinaryCrossentropy(from_logits=True) 时,我应该使用什么作为目标向量

Luc*_*rio 3 python machine-learning keras tensorflow loss-function

我有一个多标签分类,其中每个目标都是一个互斥的 1 和 0 向量(为了清楚起见,我的目标类似于[0, 1, 0, 0, 1, 1, ... ])。

到目前为止我的理解是:

  • 我应该使用二元交叉熵函数。(如本答案所述

  • 另外,我知道这tf.keras.losses.BinaryCrossentropy()是围绕 tensorflow 的sigmoid_cross_entropy_with_logits. 这可以与from_logits True或一起使用False。(如本问题所述

  • 由于sigmoid_cross_entropy_with_logits自己执行 sigmoid,它期望输入在 [-inf,+inf] 范围内。

  • tf.keras.losses.BinaryCrossentropy(),当网络实现自己最后一层的 sigmoid 激活时,必须与 一起使用from_logits=False。然后它将推断 sigmoid 函数并将输出传递给sigmoid_cross_entropy_with_logits将再次执行 sigmoid的输出。然而,由于 sigmoid/logit 函数的渐近线,这可能会导致数值问题。

  • 为了提高数值稳定性,我们可以避免最后一个 sigmoid 层并使用 tf.keras.losses.BinaryCrossentropy(from_logits=False)

题:

如果我们使用tf.keras.losses.BinaryCrossentropy(from_logits=False),我应该使用什么目标?我是否需要更改 one-hot 向量的目标?

我想我应该在推理时将 sigmoid 激活应用于网络输出。有没有办法添加仅在推理模式下而不是在训练模式下活动的 sigmoid 层?

tod*_*day 9

首先,让我对数值稳定性做一些说明:

如在评论部分所提到的,在使用的情况下,数值不稳定性from_logits=False来自概率值的转变回logits涉及削波操作(如在讨论这个问题其答案)。然而,据我所知,这不会对大多数实际应用产生任何严重的问题(尽管在某些情况下,在损失函数中应用 softmax/sigmoid 函数,即使用,在数值上更稳定计算梯度;有关数学解释,请参阅此答案)。from_logits=True

换句话说,如果您不关心敏感度小于 1e-7 的生成概率值的精度,或者您在实验中观察到的相关收敛问题,那么您不必太担心;只需像以前一样使用 sigmoid 和二元交叉熵,即model.compile(loss='binary_crossentropy', ...),它会工作正常。

总而言之,如果你真的关心数值稳定性,你可以走最安全的路径并使用,from_logits=True而无需在模型的最后一层使用任何激活函数。


现在,要回答最初的问题,真正的标签或目标值(即y_true)在使用BinaryCrossentropy(from_logits=True). 相反,这就是y_pred(即模型的输出)在这种情况下不应该是概率分布(即 sigmoid 函数不应该用于最后一层 if from_logits=True)。