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

What should I use as target vector when I use BinaryCrossentropy(from_logits=True) in tensorflow.keras

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

目前我的理解是:

问题:

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

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

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

如评论部分所述,在使用 from_logits=False 的情况下,数值不稳定性来自于将概率值转换回涉及裁剪操作的 logits(如 and ). However, to the best of my knowledge, this does NOT create any serious issues for most of practical applications (although, there are some cases where applying the softmax/sigmoid function inside the loss function, i.e. using from_logits=True, would be more numerically stable in terms of computing gradients; see this answer 中讨论的数学解释)。

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

总而言之,如果你真的很在意数值稳定性,你可以走最安全的路,在模型的最后一层不使用任何激活函数from_logits=True


现在,要回答原来的问题,真正的标签或目标值(即 y_true)在使用 BinaryCrossentropy(from_logits=True) 时应该仍然只是零或一。相反,那是 y_pred(即模型的输出)在这种情况下不应该是概率分布(即如果 from_logits=True 则不应在最后一层使用 sigmoid 函数)。

我测试了 GAN 从草图恢复逼真的图像,两个训练周期之间的唯一区别是 BinaryCrossentropy(from_logits=True/False)。最后一个网络层是没有激活的 Conv2D,所以正确的选择应该是 from_logits=True,但出于实验目的——我发现生成器和鉴别器损失存在巨大差异

  • 橙色 - 正确,
  • 蓝色 - 错误。

这是 link 协作笔记本。 基于Tensorflow tutorial pix2pix.

的练习

根据练习说明 if from_logits=True

  • 值 log(2) = 0.69 是这些损失的一个很好的参考点,因为它表示困惑度为 2:鉴别器平均对这两个选项同样不确定。
  • 对于 disc_loss,低于 0.69 的值意味着鉴别器在真实图像+生成图像的组合集上的表现优于随机。
  • 对于 gen_gan_loss,低于 0.69 的值意味着生成器在欺骗描述器方面比随机更好。

否则生成器和判别器的损失都会增加两倍。类似的解释看起来不再具有相关性。

最终图像也不同:

  • 在 from_logits==False 的情况下,图像看起来模糊并且 non-realistic