2016-07-23 1 views
1

Я пытаюсь пройти начальный код Tensorflow для нескольких графических процессоров (на 1 машине). Я смущен, потому что мы получаем несколько потерь от различных башен, иначе графических процессоров, как я понимаю, но loss переменной определена, как представляется, только в последней башне, а не сумма убытков от всех башен:Tensorflow Inception Несколько уроков обучения графическому процессору не суммируются?

for step in xrange(FLAGS.max_steps): 
    start_time = time.time() 
    _, loss_value = sess.run([train_op, loss]) 
    duration = time.time() - start_time 

где loss Последнее определяется конкретно для каждой башни:

for i in xrange(FLAGS.num_gpus): 
    with tf.device('/gpu:%d' % i): 
    with tf.name_scope('%s_%d' % (inception.TOWER_NAME, i)) as scope: 
     # Force all Variables to reside on the CPU. 
     with slim.arg_scope([slim.variables.variable], device='/cpu:0'): 
     # Calculate the loss for one tower of the ImageNet model. This 
     # function constructs the entire ImageNet model but shares the 
     # variables across all towers. 
     loss = _tower_loss(images_splits[i], labels_splits[i], num_classes, 
          scope) 

Может кто-нибудь объяснить, где шаг должен объединить потери от различных башен? Или мы просто потеря одиночной башни, как представитель других потерь башни?

Вот ссылка на код: https://github.com/tensorflow/models/blob/master/inception/inception/inception_train.py#L336

ответ

1

Для целей мониторинга, принимая во внимание все башни работают, как и ожидалось, потеря одной башне является представителем в среднем потери всех башен. Это связано с тем, что между партией и башней нет никакой связи.

Но train_op использует градиенты от всех башен, согласно line 263, 278, поэтому техническая подготовка учитывает партии со всех башен, как и должно быть.

Обратите внимание, что среднее значение потерь будет иметь меньшую дисперсию, чем потеря одиночной башни, но они будут иметь одинаковое ожидание.

1

Да, в соответствии с этим кодом потери не суммируются или не усредняются по всему gpus. Потери на gpu используются внутри каждого gpu (башни) для вычисления градиента. Синхронизированы только градиенты. Таким образом, тест isnan выполняется только для части данных, обработанных последним gpu. Это не имеет решающего значения, но может быть ограничением.

Если действительно нужно, я думаю, что вы можете сделать так, чтобы получить усредненные потери перекрестное GPUs:

per_gpu_loss = [] 
for i in xrange(FLAGS.num_gpus): 
    with tf.device('/gpu:%d' % i): 
     with tf.name_scope('%s_%d' % (inception.TOWER_NAME, i)) as scope: 
      ... 
      per_gpu_loss.append(loss) 

mean_loss = tf.reduce_mean(per_gpu_loss, name="mean_loss") 
tf.summary.scalar('mean_loss', mean_loss) 

, а затем заменить потери в sess.run в mean_loss:

_, loss_value = sess.run([train_op, mean_loss]) 

loss_value сейчас в среднем по потерям, обрабатываемым всеми gpus.