如何解决nan loss?

Posted

技术标签:

【中文标题】如何解决nan loss?【英文标题】:How to solve 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,并使用该操作 Tensorflow Nan loss reasons的可能重复 【参考方案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 也讨论了一个类似的问题。这会导致您:

    实现您自己的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])
    

    更新您的数据,使其具有有效的概率分布

【讨论】:

我用的是标准的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。顺便说一句,你现在开始工作了吗?

以上是关于如何解决nan loss?的主要内容,如果未能解决你的问题,请参考以下文章

loss出现Nan的解决办法(梯度爆炸)

keras训练cnn模型时loss为nan

模型在训练时,经过某个步骤后显示为 loss = nan

机器学习技巧-训练过程中,loss参数出现NAN怎么解决?解决方案汇总?

[深度学习][pytorch][原创]crnn在高版本pytorch上训练loss为nan解决办法

深度学习中如何平衡多个loss?多任务学习自动调整loss weight解决方案