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

Ale*_*erg 11 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})
Run Code Online (Sandbox Code Playgroud)

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

cifar10_multi_gpu_train似乎提供了一个很好的例子,可以创建从多个GPU上运行的图形中获取的损失,但我没有找到一个很好的例子,在使用时进行这种训练,feed_dictplaceholder不是数据加载器队列.

UPDATE

似乎:https://timsainb.github.io/multi-gpu-vae-gan-in-tensorflow.html可能会提供一个很好的例子.他们似乎average_gradients从中cifar10_multi_gpu_train.py创建了一个占位符,然后为每个GPU切片.我想你也需要分割create_train_op为三个阶段:compute_gradients,average_gradients然后apply_gradients.

小智 1

我知道在多 GPU 模型上提供数据的三种方法。

  1. 如果所有输入的形状相同,您可以x在 CPU 上构建占位符,然后用于tf.split拆分xxs. 然后在每个 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])

Run Code Online (Sandbox Code Playgroud)
  1. 如果您的输入具有不同的形状,则需要x在每个具有范围的 GPU 上构建占位符。

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)
Run Code Online (Sandbox Code Playgroud)
  1. 用于tf.data.Dataset提供数据。google官方cifar10_multi_gpu_train.py使用的Queue,和这种方式类似。