Tensorflow多GPU情况下如何使用feed_dict

时间:2018-12-22 12:35:58

标签: python tensorflow distributed

最近,我尝试学习如何在多个GPU上使用Tensorflow来加快训练速度。我找到了有关基于Cifar10数据集的训练分类模型的官方教程。但是,我发现本教程使用队列读取图像。出于好奇,我如何通过向Session输入价值来使用多个GPU?似乎很难解决将同一数据集的不同值提供给不同GPU的问题。谢谢大家!以下代码是官方教程的一部分。

foreach($rows as &$row) {
    $row['zip'] = json_decode($row['zip'], true);
}

2 个答案:

答案 0 :(得分:0)

QueueRunner和基于队列的API相对过时,在Tensorflow docs中明确提到:

  

使用基于队列的API的输入管道可以很干净   由tf.data API

代替

因此,建议使用tf.data API。它针对多GPU和TPU进行了优化。

如何使用它?

dataset = tf.data.Dataset.from_tensor_slices((x_train,y_train))
iterator = dataset.make_one_shot_iterator()
x,y = iterator.get_next()
# define your model
logit = tf.layers.dense(x,2) # use x directrly in your model
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))
train_step = tf.train.AdamOptimizer().minimize(cost)
with tf.Session() as sess:
  sess.run(train_step) 

您可以使用Dataset.shard()或更轻松地使用估算器API为每个GPU创建多个迭代器。

有关完整的教程,请参见here

答案 1 :(得分:0)

多GPU示例的核心思想是您将操作明确分配给tf.device。该示例遍历FLAGS.num_gpus设备,并为每个GPU创建一个副本。

如果在for循环内创建占位符op,则会将它们分配给各自的设备。您需要做的就是保留已创建占位符的句柄,然后在单个session.run调用中将它们全部单独喂入。

placeholders = []
for i in range(FLAGS.num_gpus):
    with tf.device('/gpu:%d' % i):
        plc = tf.placeholder(tf.int32) 
        placeholders.append(plc)

with tf.Session() as sess:
    fd = {plc: i for i, plc in enumerate(placeholders)}
    sess.run(sum(placeholders), feed_dict=fd)  # this should give you the sum of all
                                               # numbers from 0 to FLAGS.num_gpus - 1

为解决您的特定示例,用两个占位符(用于batch_queue.dequeue()image_batch张量)的构造替换label_batch调用,将这些占位符存储在某个位置,然后将所需的值输入这些值。

另一种(有点怪异)的方法是在image_batch调用中直接覆盖label_batchsession.run张量,因为您可以feed_dict任何张量(而不仅仅是占位符)。您仍然需要将张量存储在某个地方,以便能够从run调用中引用它们。