Tensorflow启动多个GPU训练损失没有总结?

时间:2016-07-23 20:29:25

标签: neural-network tensorflow conv-neural-network

我正在尝试通过Tensorflow的多个GPU启动代码(在一台机器上)。我很困惑,因为据我所知,我们从不同的塔(又称GPU)中获得了多次损失,但评估的loss变量似乎只是最后一个塔而不是所有塔的损失总和: / p>

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

2 个答案:

答案 0 :(得分:1)

出于监测目的,考虑到所有塔的工作符合预期,单塔的损失与所有塔的损失平均值一样具有代表性。这是因为它被分配给批次和塔之间没有关系。

train_op使用所有塔的渐变,按照line 263278,因此技术培训会考虑所有塔的批次,应该如此。

请注意,损失的平均值将比单塔的损失具有更低的差异,但它们将具有相同的预期。

答案 1 :(得分: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中的loss替换为mean_loss:

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

loss_value现在是所有gpus处理的损失的平均值。