Python 在tensorflow.keras中使用二进制交叉熵(from_logits=True)时,应该使用什么作为目标向量

Python 在tensorflow.keras中使用二进制交叉熵(from_logits=True)时,应该使用什么作为目标向量,python,tensorflow,machine-learning,keras,loss-function,Python,Tensorflow,Machine Learning,Keras,Loss Function,我有一个多标签分类,其中每个目标都是1和0的向量而不是互斥的(为了清晰起见,我的目标类似于[0,1,0,0,1,1,…]) 到目前为止,我的理解是: 我应该使用一个二进制交叉熵函数。(如本节所述) 另外,我知道tf.keras.loss.BinaryCrossentropy()是tensorflow的sigmoid\u cross\u熵与\u logits的包装。这可以与来自_logits的一起使用True或False。(如本节所述) 由于sigmoid\u cross\u entropy\u

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

到目前为止,我的理解是:

  • 我应该使用一个二进制交叉熵函数。(如本节所述)

  • 另外,我知道
    tf.keras.loss.BinaryCrossentropy()
    是tensorflow的
    sigmoid\u cross\u熵与\u logits的包装。这可以与来自_logits的
    一起使用
    True
    False
    。(如本节所述)

  • 由于
    sigmoid\u cross\u entropy\u with\u logits
    执行sigmoid,因此它希望输入在[-inf,+inf]范围内

  • tf.keras.loss.BinaryCrossentropy()
    ,当网络实现
    它本身是最后一层的乙状激活,必须与来自\u logits=False的
    一起使用。然后,它将推断出sigmoid函数,并将输出传递给将再次执行sigmoid的
    sigmoid\u cross\u entropy\u。然而,由于sigmoid/logit函数的渐近线,这可能导致数值问题

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

问题:

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


我想我应该在推理时对网络输出应用一个sigmoid激活。有没有一种方法可以添加一个仅在推理模式下活动而不在训练模式下活动的sigmoid层?

首先,让我来说明一下数值稳定性:

如评论部分所述,在使用
from_logits=False
的情况下,数值不稳定性来自将概率值转换回logits,这涉及到剪切操作(如和中所述)。然而,据我所知,这不会给大多数实际应用造成任何严重问题(尽管在某些情况下,在损失函数中应用softmax/sigmoid函数,即使用_logits=True的
,在计算梯度方面,数值上更稳定;有关数学解释,请参阅)

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

总而言之,如果你真的关心数值稳定性,你可以选择最安全的路径,使用来自_logits=True的
,而无需在模型的最后一层使用任何激活功能



现在,为了回答最初的问题,当使用
二进制交叉熵(from_logits=true)
时,真正的标签或目标值(即
y_真
)仍然应该是零或一。相反,这是
y_pred
(即模型的输出),在这种情况下不应该是概率分布(即,如果从_logits=True
中选择
,则不应在最后一层上使用sigmoid函数)。

我在从草图恢复真实图像时测试了GAN,两个列车循环之间的唯一区别是二进制交叉熵(从_logits=True/False).最后一个网络层是Conv2D,没有激活,因此正确的选择应该是从_logits=True,但出于实验目的-我发现生成器和鉴别器的损耗有巨大的差异

  • 橙色-是的
  • 蓝色-错误
这是要协作的笔记本。 以运动为基础

根据练习说明,如果from_logits=True

  • log(2)=0.69是这些损失的一个很好的参考点,因为它表明了2的困惑:鉴别器对这两个选项的平均不确定性相同
  • 对于disc_损失,低于0.69的值意味着鉴别器在真实+生成图像的组合集上比随机鉴别器做得更好
  • 对于gen_gan_损失,值低于0.69意味着生成器i在愚弄描述符方面比随机做得更好
否则,生成器和鉴别器的损失都会增加两倍。类似的解释似乎不再适用

最终图像也不同:

  • 如果from_logits==False,则图像看起来模糊且不真实

“但是,由于sigmoid/logit函数的渐近线,这可能会导致数值问题。”请提供相关的源代码好吗?而且,我不认为只使用sigmoid层和简单的
模型。compile(loss='binary\u crossentropy',…)
会带来任何问题。许多模型都是以这种方式训练的,没有任何问题!“注意:使用from_logits=True可能在数值上更稳定。”在这种特定情况下,这不是常见的问题。让我这样说:您遇到过这个特定问题吗(例如,交叉熵损失函数中的数值不稳定性导致的
的收敛问题?如果不是,那么你不应该想得太多。这是我知道的另一个来源(该问题答案的作者恰好是我!).但正如你在那里看到的,它不会产生任何严重的实际应用问题,因为差异非常小。无论如何,我不是这方面的专家,也许我是一个思考不足的人!也许其他人有一个更成熟的观点。