【问题标题】:How to solve nan loss?如何解决nan loss?
【发布时间】:2017-03-02 16:50:36
【问题描述】:

问题

我在 MNIST 上运行深度神经网络,其中损失定义如下:

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, label))

该程序似乎运行正常,直到我在 10000+ th minibatch 中出现 nan 损失。有时,程序会正常运行,直到完成。我认为tf.nn.softmax_cross_entropy_with_logits 给了我这个错误。 这很奇怪,因为代码只包含muladd 操作。

可能的解决方案

也许我可以使用:

if cost == "nan":
  optimizer = an empty optimizer 
else:
  ...
  optimizer = real optimizer

但我找不到nan 的类型。如何检查变量是否为nan

我还能如何解决这个问题?

【问题讨论】:

  • 检查“tf.add_check_numerics_ops”的实现,将Assert ops添加到每个张量以确保没有nan,因此您可以使用它用来检查nanness的任何东西
  • 我是 tensorflow 新手,当我使用“tf.add_check_numerics_ops”时,它给我带来了一个错误“tensorflow.python.framework.errors.InvalidArgumentError: All inputs to node model/CheckNumerics_254 must be from the同框。”我用错了吗?
  • 我的意思是您可以查看add_check_numerics_ops 的实现以查看哪个操作确定变量是否为NaN,并使用该操作

标签: python tensorflow nan


【解决方案1】:

我在这里发现了类似的问题TensorFlow cross_entropy NaN problem

感谢作者user1111929

tf.nn.softmax_cross_entropy_with_logits => -tf.reduce_sum(y_*tf.log(y_conv))

实际上是一种计算交叉熵的可怕方法。在某些样本中,一段时间后可以确定地排除某些类,导致该样本的 y_conv=0。这通常不是问题,因为您对这些不感兴趣,但是以 cross_entropy 的写入方式,它会为该特定样本/类产生 0*log(0) 。因此是 NaN。

替换为

cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv + 1e-10))

或者

cross_entropy = -tf.reduce_sum(y_*tf.log(tf.clip_by_value(y_conv,1e-10,1.0)))

解决了 nan 问题。

【讨论】:

    【解决方案2】:

    您得到 NaN 的原因很可能是在您的成本函数或 softmax 中的某个地方,您试图取零的对数,这不是一个数字。但是为了回答您关于检测 NaN 的具体问题,Python 具有在数学模块中测试 NaN 的内置功能。例如:

    import math
    val = float('nan')
    val
    if math.isnan(val):
        print('Detected NaN')
        import pdb; pdb.set_trace() # Break into debugger to look around
    

    【讨论】:

    • log(0) = -据我所知无限
    【解决方案3】:

    检查您的学习率。您的网络越大,需要学习的参数就越多。这意味着您还需要降低学习率。

    【讨论】:

      【解决方案4】:

      我没有您的代码或数据。但是tf.nn.softmax_cross_entropy_with_logits 应该是稳定的,具有有效的概率分布(更多信息here)。我假设您的数据不符合此要求。 here 也讨论了一个类似的问题。这会导致您:

      1. 实现您自己的softmax_cross_entropy_with_logits 函数,例如试试(source):

        epsilon = tf.constant(value=0.00001, shape=shape)
        logits = logits + epsilon
        softmax = tf.nn.softmax(logits)
        cross_entropy = -tf.reduce_sum(labels * tf.log(softmax), reduction_indices=[1])
        
      2. 更新您的数据,使其具有有效的概率分布

      【讨论】:

      • 我用的是标准的mnist数据集,我认为它的概率分布是有效的。
      • 为什么将 epsilon 添加到 logits 而不是 softmax?
      • epsilon 被添加到 logits 中,因此得到的 softmax 的总和仍然为 1,但也不能包含零(这些结果为 NaN)。很奇怪,标准 mnist 数据集有这个问题......你能检查一下如果你使用这个新的 cross_entropy 函数会发生什么吗?如果这不起作用,您可能需要查看实际的 logits。
      • 嗨,我刚刚在 SO here 上发现了一个类似的问题,在这种情况下,使用 clipping 调整了 cross_entropy。虽然在这里他从一个非常简单的 cross_entropy 实现开始,而不是 tf.nn.softmax_cross_entropy_with_logits。顺便说一句,你现在开始工作了吗?
      猜你喜欢
      • 2017-02-10
      • 1970-01-01
      • 2015-05-25
      • 2017-03-21
      • 2012-07-17
      • 2021-10-12
      • 2018-11-01
      • 1970-01-01
      • 2021-01-04
      相关资源
      最近更新 更多