Tensorflow CIFAR10多GPU - 为何会出现组合损失?

时间:2017-02-13 02:48:32

标签: tensorflow

在受过多个GPU训练的TensorFlow CIFAR10 example中,每个"塔"的损失似乎合并,并且梯度是根据这个组合损失计算的。

    # Build the portion of the Graph calculating the losses. Note that we will
    # assemble the total_loss using a custom function below.
    _ = cifar10.loss(logits, labels)

    # Assemble all of the losses for the current tower only.
    losses = tf.get_collection('losses', scope)

    # Calculate the total loss for the current tower.
    total_loss = tf.add_n(losses, name='total_loss')

    # Attach a scalar summary to all individual losses and the total loss; do the
    # same for the averaged version of the losses.
    for l in losses + [total_loss]:
        # Remove 'tower_[0-9]/' from the name in case this is a multi-GPU training
        # session. This helps the clarity of presentation on tensorboard.
        loss_name = re.sub('%s_[0-9]*/' % cifar10.TOWER_NAME, '', l.op.name)
        tf.contrib.deprecated.scalar_summary(loss_name, l)

    return total_loss

我是TensorFlow的新用户,但根据我的理解,每次调用cifar10.loss时,都会运行tf.add_to_collection('losses', cross_entropy_mean),并且当前批次的损失将存储在集合中。

然后调用losses = tf.get_collection('losses', scope) all 从集合中检索损失。然后tf.add_n op正在添加所有检索到的损失张量来自这个"塔"在一起。

我预计当前的培训步骤/批次中的损失只是 ,而不是所有批次。

我误解了什么吗?或者是否有理由将损失合并在一起?

2 个答案:

答案 0 :(得分:1)

如果启用了重量衰减,它还会将其添加到损失集合中。 因此,对于每个塔(范围),它将添加所有损失:cross_entropy_mean和weight_decay。

然后计算每个塔(范围)的梯度。最后,不同塔(范围)的所有梯度将在average_gradients中得到平均值。

答案 1 :(得分:1)

  

为什么要合并损失

您所引用的示例是多个gpus上的数据并行性的示例。数据并行性有助于使用更大的batch_size训练更深层次的模型。在此设置中,您需要将gpus中的损失组合在一起,因为每个gpus都持有输入批处理的一部分(与该输入部分对应的丢失和渐变)。以下示例从tensorflow data parallism example提供了一个示例。

注意:在模型并行性的情况下,模型的不同子图在单独的gpus上运行,中间输出由主控器收集。

例如

如果你想使用批量大小256训练模型,对于更深层次的模型(例如,resnet / inception),它可能不适合单个gpu(例如8 GB内存),所以您可以将批次拆分为两个批次为128的批次,并使用单独的gpus上的两个批次进行模型的正向传递,并计算损失和梯度。收集每个gpus的计算(损失梯度)并进行平均。平均梯度用于更新模型参数。

enter image description here