【问题标题】:Using binary_crossentropy loss in Keras (Tensorflow backend)在 Keras 中使用 binary_crossentropy 损失(Tensorflow 后端)
【发布时间】:2018-01-26 06:26:26
【问题描述】:

在 Keras 文档中的训练示例中,

https://keras.io/getting-started/sequential-model-guide/#training

使用

binary_crossentropy,在网络的最后一层添加sigmoid激活,但有必要在最后一层添加sigmoid吗?正如我在源代码中发现的:

def binary_crossentropy(output, target, from_logits=False):
  """Binary crossentropy between an output tensor and a target tensor.
  Arguments:
      output: A tensor.
      target: A tensor with the same shape as `output`.
      from_logits: Whether `output` is expected to be a logits tensor.
          By default, we consider that `output`
          encodes a probability distribution.
  Returns:
      A tensor.
  """
  # Note: nn.softmax_cross_entropy_with_logits
  # expects logits, Keras expects probabilities.
  if not from_logits:
    # transform back to logits
    epsilon = _to_tensor(_EPSILON, output.dtype.base_dtype)
    output = clip_ops.clip_by_value(output, epsilon, 1 - epsilon)
    output = math_ops.log(output / (1 - output))
  return nn.sigmoid_cross_entropy_with_logits(labels=target, logits=output)

Keras 在 Tensorflow 中调用 sigmoid_cross_entropy_with_logits,但在 sigmoid_cross_entropy_with_logits 函数中,又重新计算了 sigmoid(logits)

https://www.tensorflow.org/versions/master/api_docs/python/tf/nn/sigmoid_cross_entropy_with_logits

所以我认为最后添加 sigmoid 是没有意义的,但似乎我在网上找到的所有 Keras 中的二进制/多标签分类示例和教程都添加了 sigmoid 终于。另外我不明白是什么意思

# Note: nn.softmax_cross_entropy_with_logits
# expects logits, Keras expects probabilities.

为什么 Keras 期望概率?它不使用 nn.softmax_cross_entropy_with_logits 函数吗?有意义吗?

谢谢。

【问题讨论】:

    标签: tensorflow keras


    【解决方案1】:

    默认情况下,在 Keras 中,我们在输出层使用激活 sigmoid,然后使用 keras binary_crossentropy 损失函数,独立于后端实现(Theano、Tensorflow 或 CNTK)。

    如果您更深入地了解纯 Tensorflow 案例,您会发现 tensorflow 后端 binary_crossentropy 函数(您在问题中粘贴)使用 tf.nn.sigmoid_cross_entropy_with_logits。后面的函数还添加了 sigmoid 激活。为了避免双 sigmoid,tensorflow 后端 binary_crossentropy 将默认(使用 from_logits=False)计算逆 sigmoid (logit(x)=log(x/1-x)) 以将输出从网络恢复到原始状态无需激活。

    可以通过在最后一层不使用sigmoid激活函数来避免额外的激活sigmoid和逆sigmoid计算,然后使用参数from_logits=True调用tensorflow后端binary_crossentropy(或者直接使用tf.nn.sigmoid_cross_entropy_with_logits)

    【讨论】:

      【解决方案2】:

      在分类交叉熵中:

      • 如果是prediction,它将直接计算cross entropy
      • 如果是logit,它将应用softmax_cross entropy with logit

      在二进制交叉熵中:

      • 如果是prediction,它将转换回logit,然后应用sigmoied cross entropy with logit
      • 如果是logit,则直接申请sigmoied cross entropy with logit

      【讨论】:

        【解决方案3】:

        你是对的,这正是正在发生的事情。我相信这是由于历史原因。

        Keras 是在 tensorflow 之前创建的,作为 theano 的包装器。在 theano 中,必须手动计算 sigmoid/softmax,然后应用交叉熵损失函数。 Tensorflow 在一个融合操作中完成所有工作,但带有 sigmoid/softmax 层的 API 已经被社区采用。

        如果你想避免不必要的 logit 概率转换,用from_logits=True 调用binary_crossentropy loss 并且不要添加sigmoid 层。

        【讨论】:

        • 不仅在 Theano 中,在 Torch / PyTorch 中也有相同的逻辑,我发现这比 TF mess 更直观
        • Theano 实际上并没有强迫您使用错误的交叉熵实现。这纯粹是 Keras 的设计决定。早于 Keras 的基于 Theano 的框架实际上是正确的。参见例如 pylearn2 实现:github.com/lisa-lab/pylearn2/blob/master/pylearn2/expr/…
        • 我必须在这里添加评论。当我看到@IanGoodfellow 时,我简直不敢相信!教父,GAN 的创造者本人!阿美!
        猜你喜欢
        • 2019-12-10
        • 1970-01-01
        • 2018-05-30
        • 1970-01-01
        • 2018-04-13
        • 2019-12-11
        • 1970-01-01
        • 2021-09-06
        • 2019-01-20
        相关资源
        最近更新 更多