【问题标题】:The output of softmax makes the binary cross entropy's output NAN, what should I do?softmax的输出使得二元交叉熵的输出NAN,怎么办?
【发布时间】:2019-11-03 23:52:01
【问题描述】:

我在 Tensorflow 中实现了一个神经网络,其中最后一层是卷积层,我将此卷积层的输出输入到 softmax 激活函数中,然后将其输入到交叉熵损失函数中,该函数定义如下有标签,但问题是我得到了 NAN 作为我的损失函数的输出,我发现这是因为我在 softmax 的输出中有 1。所以,我的问题是在这种情况下我应该怎么做? 我的输入是一个 16 x 16 的图像,其中我有 0 和 1 作为每个像素的值(二进制分类)

我的损失函数:

#Loss function
def loss(prediction, label):
    #with tf.variable_scope("Loss") as Loss_scope:
    log_pred = tf.log(prediction, name='Prediction_Log')
    log_pred_2 = tf.log(1-prediction, name='1-Prediction_Log')
    cross_entropy = -tf.multiply(label, log_pred) - tf.multiply((1-label), log_pred_2) 

    return cross_entropy

【问题讨论】:

  • 您应该使用tf.nn.softmax_cross_entropy_with_logits_v2tf.losses.softmax_cross_entropy,使用最后一层的输出 softmax 激活(“logits”)之前。这些函数旨在正确处理极端情况。
  • @jdehesa 好点! :-) 我真的应该在我的答案中包含一个指向开箱即用函数的指针。我认为 OP 的问题是关于实施她自己的损失 fn
  • 现在更新了答案,并附上了关于开箱即用功能很好地处理这个问题的说明
  • @jdehesa ,我已经尝试过这些(没有softmax,如文档所述),但问题是我的损失为零,所以我的模型没有学习。

标签: python tensorflow conv-neural-network softmax cross-entropy


【解决方案1】:

请注意,log(0) 是未定义的,因此如果有 prediction==0prediction==1,您将有一个 NaN。

为了解决这个问题,在任何损失函数中将一个非常小的值 epsilon 添加到传递给 tf.log 的值是很常见的(我们在除以时也会做类似的事情以避免被零除)。这使得我们的损失函数在数值上是稳定的,并且 epsilon 值足够小,可以忽略它给我们的损失带来的任何不准确性。

也许可以试试:

#Loss function
def loss(prediction, label):
    #with tf.variable_scope("Loss") as Loss_scope:

    epsilon = tf.constant(0.000001)
    log_pred = tf.log(prediction + epsilon, name='Prediction_Log')
    log_pred_2 = tf.log(1-prediction + epsilon, name='1-Prediction_Log')

    cross_entropy = -tf.multiply(label, log_pred) - tf.multiply((1-label), log_pred_2) 
    return cross_entropy

更新:

正如 jdehesa 在他的 cmets 中指出的那样 - “开箱即用”的损失函数已经很好地处理了数值稳定性问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 2020-01-03
    • 2017-12-22
    • 2018-03-12
    相关资源
    最近更新 更多