2017-09-13 1 views
0

CIFAR-10에서 학습 할 깊은 모델이 있습니다. 교육은 CPU와 잘 작동합니다. 그러나 GPU 지원을 사용하면 일부 배치의 그라디언트가 NaN (나는 tf.check_numerics을 사용하여 검사했습니다)이 발생하지만 임의로 발생하지만 충분히 빠릅니다. 문제는 내 GPU와 관련이 있다고 생각합니다.Tensorflow : 그라디언트가 Nan 인 경우 업데이트하지 마십시오

내 질문은 : 그라디언트 중 하나 이상에 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) 그라디언트가 NaNs가 아닌 경우 을 적용하십시오. 3) 그렇지 않으면 가짜 업데이트를 적용합니다 (0 값 사용). 그래디언트 오버라이드가 필요합니다.

내 코드이다

먼저 정의 기울기를 정의

:

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)) 
:

#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=()) 

그럼 조건부 노드를 작성 :

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

그럼 예외 처리 함수를 정의

관련 문제