在Keras中使用binary_crossentropy丢失(Tensorflow后端)

时间:2017-08-17 17:47:29

标签: tensorflow keras

在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 < / strong>最后。除此之外,我不明白

的含义是什么
# Note: nn.softmax_cross_entropy_with_logits
# expects logits, Keras expects probabilities.

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

感谢。

3 个答案:

答案 0 :(得分:1)

你是对的,这正是发生了什么。我相信这是由于历史原因。

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

如果您想避免不必要的logit&lt; - &gt;概率转换,使用binary_crossentropy调用from_logits=True丢失并且不添加sigmoid层。

答案 1 :(得分:0)

在分类交叉熵中:

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

在二元互熵中:

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

答案 2 :(得分:0)

默认情况下,在Keras中,我们在输出层上使用激活Sigmoid,然后使用keras binary_crossentropy损失函数,而与后端实现(Theano,Tensorflow或CNTK)无关。

如果您更深入地研究纯Tensorflow案例,您会发现tensorflow后端binary_crossentropy函数(您在问题中粘贴了该函数)使用tf.nn.sigmoid_cross_entropy_with_logits。后面的功能还添加了S型激活。为了避免双重Sigmoid,默认情况下(与from_logits = False一起)tensorflow后端binary_crossentropy将计算反Sigmoid(logit(x)= log(x / 1-x)),以使输出从网络返回到原始状态没有激活。

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