2017-09-13 49 views
0

私はCIFAR-10で訓練する深いモデルを持っています。トレーニングはCPUでうまく動作します。しかし、GPUサポートを使用すると、一部のバッチのグラデーションがNaN(tf.check_numericsを使用してチェックされています)がランダムに発生しますが、十分に早く発生します。私はこの問題が私のGPUに関係していると信じています。Tensorflow:勾配がNanの場合は更新しない

質問:少なくとも1つのグラデーションにNaNがあり、モデルが次のバッチに進むように強制すると、更新しないことはありますか?

を編集してください:おそらく私は自分の問題について詳しく説明する必要があります。私ができるナンは(チェックが失敗した)がある場合、その後、私はグラデーションでナンがあることを確認するために最初のtf.check_numericsを使用して考えてい

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) 

、および:

は、これは私がグラデーションを適用する方法でありますopt.apply_gradientsを使わずに「パス」します。しかし、tf.control_dependenciesでエラーをキャッチする方法はありますか?

答えて

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)) 
関連する問題