【问题标题】:Tensorflow CIFAR10 Multi GPU - Why Combined Loss?Tensorflow CIFAR10 多 GPU - 为什么要合并损失?
【发布时间】:2017-08-17 01:03:35
【问题描述】:

在 TensorFlow CIFAR10 example 中,在多个 GPU 上进行训练,损失似乎是为每个“塔”组合的,梯度是根据这个组合的损失计算的。

    # 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),并且所有从集合中检索损失。然后tf.add_n op 将从这个“塔”中检索到的所有损失张量加在一起。

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

我是不是误会了什么?还是有理由将损失合并在一起?

【问题讨论】:

  • 你想从大批量中损失,这是通过将批量分成几个较小的批次来实现的,每个 GPU 一个,然后使用add_n恢复全部损失
  • 感谢您的评论。我知道您正在将批次分成更小的批次,但您只会从 current 塔中获得损失:losses = tf.get_collection('losses', scope) 按范围过滤张量
  • 哦,我明白你的意思了。 losses 集合中是否有不止一项损失?我预计会有一次损失,所以add_n 将是一个空操作
  • 好问题,据我了解tf.get_collection 将返回所有 损失,因为您每次调用cifar10.loss 时都会添加到集合中。在该函数显式调用tf.add_to_collection 的幕后,并没有清除我能找到的集合
  • 我认为它只是在单个 GPU case 中获得总损失,但只是在 tf.get_collections 范围内。

标签: tensorflow


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    为什么要合并损失

    您所指的示例是多个 GPU 上的数据并行示例。数据并行有助于用更大的 batch_size 训练更深层次的模型。在此设置中,您需要结合来自 gpus 的损失,因为每个 gpus 都持有输入批次的一部分(损失和梯度对应于该输入部分)。以下示例提供了一个插图,来自tensorflow data parallism example

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

    示例

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

    【讨论】:

      猜你喜欢
      • 2016-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-25
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      相关资源
      最近更新 更多