2017-09-27 4 views
1

모든 코드 우리는 흥미로운 손실 함수가있는 GAN 알고리즘에 노력하고 있습니다 Tensorflow 1.3 파이썬 3.x를Tensorflow : 그래프

가정되는의 부분에 MultiGPU 교육.

Stage 1 - Compute only the completion/generator loss portion of the network 
      Iterates over the completion portion of the GAN for X iterations. 

Stage 2 - Compute only the discriminator loss portion of the network 
      Iterates over the discriminator portion for Y iterations (but 
      don't train on Stage 1) 

Stage 3 - Compute the full loss on the network 
      Iterate over both completion and discriminator for Z iterations 
      (training on the entire network). 

이 단일 GPU가 있습니다. 우리는 교육 시간이 길기 때문에 멀티 GPU로 작동하도록하고 싶습니다.

타워 손실에 대해 이야기하고, 타워를 함께 평균 처리하고, GPU에서 그라데이션을 계산 한 다음 CPU에 적용하는 Tensorflow/models/tutorials/Images/cifar10/cifar10_multi_gpu_train.py를 살펴 보았습니다. 이것은 훌륭한 출발점입니다. 그러나 우리의 손실은 더 복잡하기 때문에 모든 것을 복잡하게 만듭니다.

코드는 복잡하지만 대략 비슷하지만 https://github.com/timsainb/Tensorflow-MultiGPU-VAE-GAN입니다 (하지만 Tensorflow 0.1에서 작성 되었기 때문에 실행되지 않습니다. 따라서 작동하지 않았지만 약간의 기이함이 있습니다. (

for i in range(num_gpus): 
    with tf.device('/gpu:%d' % gpus[i]): 
     with tf.name_scope('Tower_%d' % gpus[i]) as scope: 
      with tf.variable_scope("generator") 
       generator = build_generator() 

     with tf.variable_scope("discriminator"): 
      with tf.variable_scope("real_discriminator") : 
       real_discriminator = build_discriminator(x) 

      with tf.variable_scope("fake_discriminator", reuse = True): 
       fake_discriminator = build_discriminator(generator) 

     gen_only_loss, discm_only_loss, full_loss = build_loss(generator, 
      real_discriminator, fake_discriminator) 

     tf.get_variable_scope().reuse_variables() 

     gen_only_grads = gen_only_opt.compute_gradients(gen_only_loss) 
     tower_gen_only_grads.append(gen_only_grads) 

     discm_only_train_vars= tf.get_collection( 
      tf.GraphKeys.TRAINABLE_VARIABLES, "discriminator") 
     discm_only_train_vars= discm_only_train_vars+ tf.get_collection( 
      tf.GraphKeys.TRAINABLE_RESOURCE_VARIABLES, "discriminator") 

     discm_only_grads = discm_only_opt.compute_gradients(discm_only_loss, 
      var_list = discm_only_train_vars) 
     tower_discm_only_grads.append(discm_only_grads) 

     full_grads = full_opt.compute_gradients(full_loss) 
     tower_full_grads.append(full_grads) 

# average_gradients is the same code from the cifar10_multi_gpu_train.py. 
We haven't changed it. Just iterates over gradients and averages 
them...this is part of the problem... 
gen_only_grads = average_gradients(tower_gen_only_grads) 
gen_only_train = gen_only_opt.apply_gradients(gen_only_grads, 
global_step=global_step) 

discm_only_grads = average_gradients(tower_discm_only_grads) 
discm_only_train = discm_only_opt.apply_gradients(discm_only_grads, 
    global_step=global_step) 

full_grads = average_gradients(tower_full_grads) 
full_train = full_opt.apply_gradients(full_grads, global_step=global_step) 

을 우리는 "compute_gradients를 호출하는 경우 : 당신에게 우리가 무슨 일을하는지에 대한 아이디어) 우리가 그라데이션을 계산하면

, 그것은) 중요한 부분을 강조하려고이 (의사 같이 보입니다를 제공 full_loss) "로 설정하면 알고리즘이 여러 GPU에서 제대로 작동합니다. 이것은 cifar10_multi_gpu_train.py 예제의 코드와 매우 같습니다. 까다로운 부분은 1 단계 또는 2 단계에서 네트워크를 제한해야 할 때입니다.

Compute_gradients (full_loss)에는 기본값 인 None이있는 var_list 매개 변수가 있습니다. 즉, 모든 변수를 교육합니다. Tower_1에있을 때 Tower_0 변수를 훈련시키지 않는 것을 어떻게 알 수 있습니까? compute_gradients (discm_only_loss, var_list = discm_only_train_vars)를 다룰 때 네트워크의 해당 부분에 대한 교육을 제한하기 위해 올바른 변수를 수집하는 방법을 알아야하기 때문에 질문합니다. 한 스레드가이 문제에 관해 이야기했지만 발견 된 내용이 정확하지 않거나 불완전하다는 것을 알았습니다 - "freeze" some variables/scopes in tensorflow: stop_gradient vs passing variables to minimize.

왜냐하면 compute_gradients의 코드를 보면 var_list가 채워져있는 이유는 None이 전달 될 때 trainable 변수와 trainable 리소스 변수가 조합 된 것입니다. 그래서 그 점도 제한되었습니다. 이 기능은 여러 GPU로 분할하지 않으면 제대로 작동합니다.

질문 1 : 이제 네트워크를 타워로 분할 했으므로 현재 타워를 수집해야합니까? 이런 선을 추가해야합니까? (? 그리고 그 변수의 교육을 놓치지 않도록) 타워에 대한 적절한 변수를 양성하기 위해

discm_only_train_vars= tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, "Tower_{}/discriminator".format(i)) 
discm_only_train_vars= discm_only_train_vars + tf.get_collection(tf.GraphKeys.TRAINABLE_RESOURCE_VARIABLES, "Tower_{}/discriminator".format(i)) 

질문 2 : 아마 같은 대답 질문 1. "compute_gradients을 얻기로 (gen_only_loss) "는 좀 더 세게입니다 ... 타워형이 아닌 버전에서는 gen_only_loss가 판별자를 절대 건드리지 않았으므로 필요했던 그래프의 텐서를 활성화 시켰습니다. 내가 "compute_gradients"를 호출 할 때 그러나, 우뚝 솟은 버전에서, 그것은 아직 활성화되지 않은 텐서에 대한 기울기를 반환 - 그래서 일부 항목은 [(없음, tf.Variable), (없음, tf.Variable)]. 이로 인해 average_gradients는 None 값을 Tensor로 변환 할 수 없기 때문에 충돌합니다. 이것은 내가 이것들을 제한 할 필요가 있다고 생각하게 만든다.

이 모든 것에 대한 혼란스러운 점은 cifar 예제와 my_full 예제가 특정 타워에 대한 교육에 신경 쓰지 않는다는 것입니다. 그러나 일단 var_list를 지정하면 compute_gradients가 알고있는 모든 마법을 탑이 사라질 때 훈련 할 변수는 무엇입니까? 다른 변수를 잡는 것에 대해 걱정할 필요가 있습니까?

답변

0

질문 1의 경우 수동으로 나누면 수집 할 책임이 있습니다.

질문 2의 경우 호출을 compute_gradients로 제한하거나 결과를 필터링 할 수 있습니다.

관련 문제