最近,我尝试学习如何在多个GPU上使用Tensorflow来加快训练速度。我找到了有关基于Cifar10数据集的训练分类模型的官方教程。但是,我发现本教程使用队列读取图像。出于好奇,我如何通过向Session输入价值来使用多个GPU?似乎很难解决将同一数据集的不同值提供给不同GPU的问题。谢谢大家!以下代码是官方教程的一部分。
foreach($rows as &$row) {
$row['zip'] = json_decode($row['zip'], true);
}
答案 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_batch
和session.run
张量,因为您可以feed_dict任何张量(而不仅仅是占位符)。您仍然需要将张量存储在某个地方,以便能够从run
调用中引用它们。