Използване на gpu срещу 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
Това просто означава, че GPU се използва по подразбиране, когато е наличен. По-скоро трябва изрично да използвате процесора, за да измерите разликата.   -  person P-Gn    schedule 02.07.2017
comment
Благодаря @user1735003. Опитах това, което предложихте (замених gpu с cpu). Резултатът беше, че всяка стъпка беше с 5 секунди по-дълга. Трябва да е по-бързо, нали? Освен това, когато копирах оригиналния код от уебсайта и го сравних с гореспоменатия код, нямаше забележима разлика. можеш ли да ми кажеш защо   -  person Roofi    schedule 02.07.2017


Отговори (1)


Фактът, че можете да изпълнявате този код без грешки, предполага, че TensorFlow определено може да работи с GPU. Проблемът тук е, че когато стартирате TensorFlow такъв, какъвто е, по подразбиране той се опитва да работи на GPU. Има няколко начина, по които можете да го принудите да работи на процесора.

  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
Тези параметри не влияят на това дали се изпълнява на GPU или не. Вижте тук за повече информация. - person jkschin; 02.07.2017
comment
моля, добавете последния си коментар в отговора (за бъдещи потребители на Google) @jkschin - person Roofi; 04.07.2017