5

全部,如何在更新时检查Tensorflow中的梯度NaN?

当您训练大量样本的大型模型时,某些样本在参数更新时可能会导致NaN梯度。

我想找到这些样品。同时我不希望此批次样本的梯度更新模型参数,因为它可能导致模型参数为NaN。

因此,任何人都有好主意来处理这个问题?

我的代码是象下面这样:

# Create an optimizer. 
    params = tf.trainable_variables() 
    opt = tf.train.AdamOptimizer(1e-3) 
    gradients = tf.gradients(self.loss, params) 

    max_gradient_norm = 10 
    clipped_gradients, self.gradient_norms = tf.clip_by_global_norm(gradients, 
                max_gradient_norm) 

    self.optimizer = opt.apply_gradients(zip(clipped_gradients, params)) 

回答

9

您可以检查您是否梯度具有楠tf.check_numerics

grad_check = tf.check_numerics(clipped_gradients) 
with tf.control_dependencies([grad_check]): 
    self.optimizer = opt.apply_gradients(zip(clipped_gradients, params)) 

grad_check会抛出InvalidArgument如果clipped_gradients是NaN或无穷大。

tf.control_dependencies确保在应用渐变之前对grad_check进行评估。请参阅tf.add_check_numerics_ops()

+0

非常感谢。但我还有一个问题。当我在我的代码中添加tf.add_check_numerics_ops()时,出现Out of Memory错误。并删除这条线,一切都很好。我的模型非常大,所以tf.add_check_numerics_ops()会为检查操作分配更多的GPU内存? – Issac

+0

'tf.check_numerics'内核中有一个张量拷贝:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/kernels/check_numerics_op.cc#L60。所以只需使用'tf.check_numerics'添加一些检查。如果您想使用为所有浮点型张量运行'tf.check_numerics'的'tf.add_check_numerics_ops()',则需要特别小心。 – yuefengz

0

如果损失不是NaN,您可以使用tf.is_nantf.cond的组合来执行其余代码。