使用feed_dict时,Tensorflow中的多GPU训练(数据并行)

时间:2017-04-05 21:19:49

标签: tensorflow

我想使用多个GPU来利用数据并行性来训练我的Tensorflow模型。

我目前正在使用以下方法培训Tensorflow模型:

x_ = tf.placeholder(...)
y_ = tf.placeholder(...)
y = model(x_)
loss = tf.losses.sparse_softmax_cross_entropy(labels=y_, logits=y)
optimizer = tf.train.AdamOptimizer()
train_op = tf.contrib.training.create_train_op(loss, optimizer)
for i in epochs:
   for b in data:
      _ = sess.run(train_op, feed_dict={x_: b.x, y_: b.y})

我想利用多个GPU以数据并行方式训练此模型。即我想将我的批次分成两半并在我的两个GPU之一上运行每一批。

cifar10_multi_gpu_train似乎提供了一个很好的例子,可以创建从多个GPU上运行的图形中获取的损失,但是我没有找到使用feed_dict时执行此类培训的良好示例placeholder而不是数据加载器队列。

更新

似乎:https://timsainb.github.io/multi-gpu-vae-gan-in-tensorflow.html可能会提供一个很好的例子。他们似乎从average_gradients引入cifar10_multi_gpu_train.py并创建一个占位符,然后为每个GPU切片。 我认为您还需要将create_train_op分为三个阶段:compute_gradientsaverage_gradients然后apply_gradients

1 个答案:

答案 0 :(得分:1)

我知道在多GPU模式下提供数据的三种方式。

  1. 如果所有输入都具有相同的形状,则可以在CPU上构建占位符x,然后使用tf.splitx拆分为xs。然后在每个GPU塔上,输入xs[i]作为输入。
with tf.device("/cpu:0"):
    encoder_inputs = tf.placeholder(tf.int32, [None, None], name="encoder_inputs")
    encoder_length = tf.placeholder(tf.int32, [None,], name="encoder_length")

    # make sure batch % num_gpu == 0
    inputs = tf.split(encoder_inputs, axis=0)  # axis=0, split on batch dimension
    lens = tf.split(encoder_length, axis=0)

with tf.variable_scope(tf.get_variable_scope()):
    for i in range(num_gpus):
        with tf.device("/gpu:%d"%i):
            with tf.name_scope("tower_%d"%i):
                loss = compute_loss(inputs[i], lens[i])

  1. 如果输入的形状不同,则需要在具有范围的每个GPU上构建占位符x

def init_placeholder(self):
    with tf.variable_scope("inputs"):   # use a scope
        encoder_inputs = tf.placeholder(tf.int32, [None, None], name="encoder_inputs")
        encoder_length = tf.placeholder(tf.int32, [None,], name="encoder_length")
    return encoder_inputs, encoder_length

with tf.variable_scope(tf.get_variable_scope()):
    for g, gpu in enumerate(GPUS):
        with tf.device("/gpu:%d"%gpu):
            with tf.name_scope("tower_%d"%g):
                x, x_len = model.init_placeholder()  # these placeholder Tensor are on GPU
                loss = model.compute_loss(x, x_len)
  1. 使用tf.data.Dataset来馈送数据。 google官方cifar10_multi_gpu_train.py使用Queue,与这种方式类似。