Использование gpu vs cpu в примере tensorflow deep mnist

Программа, которую я использую, скопирована из здесь с некоторыми изменениями. Это мой код с попыткой повысить скорость обучения:

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

import tensorflow as tf

x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)

def conv2d(x, W):
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')

with tf.device('/gpu:0'):
  W_conv1 = weight_variable([5, 5, 1, 32])
  b_conv1 = bias_variable([32])
  x_image = tf.reshape(x, [-1, 28, 28, 1])
  h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
  h_pool1 = max_pool_2x2(h_conv1)

  W_conv2 = weight_variable([5, 5, 32, 64])
  b_conv2 = bias_variable([64])

  h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
  h_pool2 = max_pool_2x2(h_conv2)

  W_fc1 = weight_variable([7 * 7 * 64, 1024])
  b_fc1 = bias_variable([1024])

  h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
  h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

  keep_prob = tf.placeholder(tf.float32)
  h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

  W_fc2 = weight_variable([1024, 10])
  b_fc2 = bias_variable([10])

  y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2

  cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))
  train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
  correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
  accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

  with tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)) as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(20000):
      batch = mnist.train.next_batch(50)
      if i % 100 == 0:
        train_accuracy = accuracy.eval(feed_dict={
          x: batch[0], y_: batch[1], keep_prob: 1.0})
        print('step %d, training accuracy %g' % (i, train_accuracy))
      train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

  print('test accuracy %g' % accuracy.eval(feed_dict={
      x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

Что производит следующий вывод:

Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
step 0, training accuracy 0.22
step 100, training accuracy 0.76
step 200, training accuracy 0.88
...

Проблема в том, что время, затрачиваемое исходным кодом в учебнике (т.е. без with tf.device('/gpu:0'): в строке 26), и этим кодом не имеет измеримой разницы (около 10 секунд на каждый шаг) . Я успешно установил cuda-8.0 и cuDNN (после многих часов неудачных попыток). «$ nvidia-smi» возвращает следующий вывод:

Sun Jul  2 13:57:10 2017       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 375.26                 Driver Version: 375.26                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GT 710      Off  | 0000:01:00.0     N/A |                  N/A |
| N/A   49C    P0    N/A /  N/A |    406MiB /  2000MiB |     N/A      Default |
+-------------------------------+----------------------+----------------------+


+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|    0                  Not Supported                                         |
+-----------------------------------------------------------------------------+

Итак, вопрос:

1) Работа слишком мала, чтобы не было разницы в выборе процессора или видеокарты? 2) Или в моей реализации какая-то глупая ошибка?

Спасибо, что прочитали весь вопрос.


person Roofi    schedule 02.07.2017    source источник
comment
Это просто означает, что графический процессор используется по умолчанию, когда он доступен. Вы должны явно использовать ЦП для измерения разницы.   -  person P-Gn    schedule 02.07.2017
comment
Спасибо @ user1735003. Я попробовал то, что вы предложили (заменил gpu на cpu). В результате каждый шаг стал на 5 секунд длиннее. Это должно быть быстрее, верно? Кроме того, когда я скопировал исходный код с веб-сайта и сравнил его с вышеупомянутым кодом, не было заметной разницы. Можешь мне сказать почему?   -  person Roofi    schedule 02.07.2017


Ответы (1)


Тот факт, что вы можете запустить этот код без ошибок, говорит о том, что TensorFlow определенно может работать с графическим процессором. Проблема здесь в том, что когда вы запускаете TensorFlow как есть, по умолчанию он пытается работать на графическом процессоре. Есть несколько способов заставить его работать на процессоре.

  1. Запустите его следующим образом: CUDA_VISIBLE_DEVICES= python code.py. Обратите внимание, что когда вы сделаете это, и у вас все еще будет with tf.device('/gpu:0'), он сломается, поэтому удалите его.
  2. Изменить with tf.device('/gpu:0') на with tf.device('/cpu:0')

ИЗМЕНИТЬ вопрос в комментариях

См. >здесь для получения дополнительной информации о том, что означают allow_soft_placement и log_device_placement в ConfigProto.

person jkschin    schedule 02.07.2017
comment
Извините за неясность @jkschin, но оператор TensorFlow как есть по умолчанию, он пытается работать на графическом процессоре, остается верным, даже если я не упоминаю config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True) в скобках сеанса. - person Roofi; 02.07.2017
comment
Эти параметры не влияют на то, работает ли он на графическом процессоре или нет. См. >здесь для получения дополнительной информации. - person jkschin; 02.07.2017
comment
пожалуйста, добавьте свой последний комментарий в ответ (для будущих пользователей Google) @jkschin - person Roofi; 04.07.2017