在受过多个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正在添加所有检索到的损失张量来自这个"塔"在一起。
我预计当前的培训步骤/批次中的损失只是 ,而不是所有批次。
我误解了什么吗?或者是否有理由将损失合并在一起?
答案 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的计算(损失梯度)并进行平均。平均梯度用于更新模型参数。