0

이 같은 train_op을 만들 때없는 것 같다 테스트 세트.모델() Optimizer.minimize으로 overfitting하지만 (tf.contrib.layers.optimize_loss)

난 그냥 이런 minimize() 방법을 사용하는 경우 : 심지어 1000 단계 후 첫 검증에

optimizer = tf.train.AdamOptimizer(learning_rate=params['learning_rate']) 
train_op = optimizer.minimize(
    loss=loss, 
    global_step=tf.train.get_global_step() 
) 

내가 훨씬 더 결과 (정밀, 리콜, 손실)을 얻을 수를, 그리고 후에는 완전히 것 같다 동안 overfitted (유효성에 대한 손실은 거의 일정하며 100x 열차 손실이지만 정밀도와 리콜 크래시)

나는 똑 바른 Optimizer.minimize()와는 다른 contrib 버전의 정리 된 버전 인 함수를 만들었습니다. 표시된 장소 2 개 :

def make_train_op(loss, optimizer, global_step): 
    with tf.variable_scope(None, "OptimizeLoss", [loss, global_step]): 

     # ========================================== 
     # this part is extra comparing to minimize() 
     update_ops = set(tf.get_collection(tf.GraphKeys.UPDATE_OPS)) 
     if update_ops: 
      with tf.control_dependencies([update_ops]): 
       loss = tf.identity(loss) 
     # ========================================== 

     gradients = optimizer.calculate_gradients(
      loss, 
      tf.trainable_variables() 
     ) 

     grad_updates = optimizer.apply_gradients(
      gradients, 
      global_step=global_step, 
      name="train") 

     # ========================================== 
     # so is this one 
     with tf.control_dependencies([grad_updates]): 
      train_op = tf.identity(loss) 
     # ========================================== 
     return train_op 

그리고 유효성 검사가 다시 잘 수행됩니다. 모든 경우의 교육은 거의 같거나 (그리고 건강한) 것처럼 보입니다. 네트워크는 크로스 엔트로피 손실이있는 CNN/batchnorm/dropout/maxpool 믹스가 비교적 간단합니다.

내가 이해하는 방식은 손실에 대한 의존성으로 나타나지 않지만 그래디언트를 계산하는 데 필요한 그래프의 일부인 일부 연산이 있다는 것입니다. 어떻게 가능할까요? 이것이 정상적인 상황이라면, 왜 두 개의 발췌 문장이 핵심 부분이되지 않습니까? 이 종속성 강제의 필요성을 피하기 위해 모델을 빌드하는 동안 다른 것을해야합니까?

답변

1

문제는 batchnorm 업데이트 작업으로, 그리고 실제로 documented입니다 :

참고 : 교육의 moving_mean 및 moving_variance를 업데이트해야 할 때. 기본적으로 업데이트 작업은 tf.GraphKeys.UPDATE_OPS에 배치되므로 train_op에 대한 종속성으로 추가해야합니다. 예 :

update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) 
with tf.control_dependencies(update_ops): 
    train_op = optimizer.minimize(loss)