Как использовать feed_dict в случае нескольких графических процессоров Tensorflow - PullRequest
0 голосов
/ 22 декабря 2018

В последнее время я пытаюсь научиться использовать Tensorflow на нескольких GPU для ускорения тренировок.Я нашел официальный учебник о модели классификации тренировок на основе набора данных Cifar10.Тем не менее, я обнаружил, что этот учебник читает изображение с помощью очереди.Из любопытства, как я могу использовать несколько графических процессоров, вводя значения в сессию?Кажется, мне трудно решить проблему, которая передает разные значения из одного набора данных в другой графический процессор.Спасибо всем!Следующий код является частью официального руководства.

images, labels = cifar10.distorted_inputs()
batch_queue = tf.contrib.slim.prefetch_queue.prefetch_queue(
      [images, labels], capacity=2 * FLAGS.num_gpus)
# Calculate the gradients for each model tower.
tower_grads = []
with tf.variable_scope(tf.get_variable_scope()):
  for i in xrange(FLAGS.num_gpus):
    with tf.device('/gpu:%d' % i):
      with tf.name_scope('%s_%d' % (cifar10.TOWER_NAME, i)) as scope:
        # Dequeues one batch for the GPU
        image_batch, label_batch = batch_queue.dequeue()
        # Calculate the loss for one tower of the CIFAR model. This function
        # constructs the entire CIFAR model but shares the variables across
        # all towers.
        loss = tower_loss(scope, image_batch, label_batch)

        # Reuse variables for the next tower.
        tf.get_variable_scope().reuse_variables()

        # Retain the summaries from the final tower.
        summaries = tf.get_collection(tf.GraphKeys.SUMMARIES, scope)

        # Calculate the gradients for the batch of data on this CIFAR tower.
        grads = opt.compute_gradients(loss)

        # Keep track of the gradients across all towers.
        tower_grads.append(grads)

Ответы [ 2 ]

0 голосов
/ 22 декабря 2018

Основная идея примера с несколькими графическими процессорами заключается в том, что вы явно назначаете операции для tf.device.В этом примере выполняется цикл по FLAGS.num_gpus устройствам и создается реплика для каждого из графических процессоров.

Если вы создадите операции-заполнители внутри цикла for, они будут назначены соответствующим устройствам.Все, что вам нужно сделать, это сохранить дескрипторы созданных заполнителей, а затем передать их все независимо в одном вызове 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.

0 голосов
/ 22 декабря 2018

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) 

Вы можете создать несколько итераторов для каждого GPU с помощью Dataset.shard() или более легко использовать API оценки.

Полный курс обучения см. здесь .

...