【问题标题】:Tensorflow: Don't Update if gradient is NanTensorflow:如果梯度为 Nan,则不要更新
【发布时间】:2017-09-13 14:19:21
【问题描述】:

我有一个要在 CIFAR-10 上训练的深度模型。训练在 CPU 上运行良好。但是,当我使用 GPU 支持时,它会导致某些批次的渐变为 NaN(我使用 tf.check_numerics 检查它)并且它随机发生但足够早。我认为问题与我的 GPU 有关。

我的问题是:如果至少有一个梯度具有 NaN 并强制模型继续进行下一批,是否有不更新?

编辑:也许我应该详细说明我的问题。

这就是我应用渐变的方式:

with tf.control_dependencies([tf.check_numerics(grad, message='Gradient %s check failed, possible NaNs' % var.name) for grad, var in grads]):
# Apply the gradients to adjust the shared variables.
  apply_gradient_op = opt.apply_gradients(grads, global_step=global_step)

我曾想过先使用tf.check_numerics 来验证渐变中是否有Nans,然后,如果有Nans(检查失败),我可以不使用opt.apply_gradients“通过”。但是,有没有办法用tf.control_dependencies 捕获错误?

【问题讨论】:

    标签: tensorflow backpropagation


    【解决方案1】:

    我可以弄明白,虽然不是最优雅的方式。 我的解决方案如下: 1)首先检查所有渐变 2)如果梯度是无NaN的,应用它们 3) 否则,应用虚假更新(零值),这需要梯度覆盖。

    这是我的代码:

    首先定义自定义渐变:

    @tf.RegisterGradient("ZeroGrad")
    def _zero_grad(unused_op, grad):
      return tf.zeros_like(grad)
    

    然后定义一个异常处理函数:

    #this is added for gradient check of NaNs
    def check_numerics_with_exception(grad, var):
      try:
       tf.check_numerics(grad, message='Gradient %s check failed, possible NaNs' % var.name)
      except:
        return tf.constant(False, shape=())
      else:
        return tf.constant(True, shape=())  
    

    然后创建条件节点:

    num_nans_grads = tf.Variable(1.0, name='num_nans_grads')
    check_all_numeric_op = tf.reduce_sum(tf.cast(tf.stack([tf.logical_not(check_numerics_with_exception(grad, var)) for grad, var in grads]), dtype=tf.float32))
    
    with tf.control_dependencies([tf.assign(num_nans_grads, check_all_numeric_op)]):
    # Apply the gradients to adjust the shared variables.
      def fn_true_apply_grad(grads, global_step):
        apply_gradients_true = opt.apply_gradients(grads, global_step=global_step)
        return apply_gradients_true
    
      def fn_false_ignore_grad(grads, global_step):
       #print('batch update ignored due to nans, fake update is applied')
       g = tf.get_default_graph()
       with g.gradient_override_map({"Identity": "ZeroGrad"}):
         for (grad, var) in grads:
           tf.assign(var, tf.identity(var, name="Identity"))
           apply_gradients_false = opt.apply_gradients(grads, global_step=global_step)
       return apply_gradients_false
    
      apply_gradient_op = tf.cond(tf.equal(num_nans_grads, 0.), lambda : fn_true_apply_grad(grads, global_step), lambda :  fn_false_ignore_grad(grads, global_step))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多