GPU资源对神经网络模型的训练很重要,应充分利用电脑的显卡资源,加快模型的训练速度。这里是本人安装tensorflow-gpu的过程,记录了安装的步骤以及在每个步骤中参考的资料以及所遇到的坑。

大体步骤:
1. 使用pip安装tensorflow-gpu。
2. 安装CUDA。
3. 下载CUDNN并把copy其中相应的文件到CUDA所在目录的相应目录下。
4. 检查系统环境变量。

一开始可能会不知道CUDA和CUDNN是什么,下面科普一下:

CUDA:它所作用的对象是显卡,也就是GPU,有了它,程序开发人员就能够编码控制和使用GPU了,现在已经支持多种编程语言,比如C、C++和Fortran。下面这段话来自官方网页。

CUDA is a parallel computing platform and programming model invented by NVIDIA. It enables dramatic increases in computing performance by harnessing the power of the graphics processing unit (GPU).

但是,能够编程使用和控制GPU进行相应的逻辑工作,比如进行神经网络学习,这还不够,因为不够方便,如果有专门的工具包或者算法包,直接调用就好了,比如像JDK。于是有了CUDNN。

CUDNN 是CUDA Deep Neural Network library 的缩写,也就是基于CUDA的神经网络软件包。可以类比JAVA中的JDK,也可以类比开源图像处理工具包openCV。下面这段话来自官方网页。

The NVIDIA CUDA® Deep Neural Network library (cuDNN) is a GPU-accelerated library of primitives for deep neural networks. cuDNN provides highly tuned implementations for standard routines such as forward and backward convolution, pooling, normalization, and activation layers. cuDNN is part of the NVIDIA Deep Learning SDK.

具体步骤:
1. 参考下面链接中的指导文档安装tensorflow-gpu。
Tensorflow gpu 官方安装指南: https://www.tensorflow.org/install/install_windows
这一步可能需要一点python的知识。这里从略。

  1. 下载CUDA并安装:
    各个版本的CUDA :https://developer.nvidia.com/cuda-toolkit-archive
  2. 下载CUDNN
    CUDNN库下载地址:https://developer.nvidia.com/cudnn
    下载好之后,解压,里面有三个文件夹,分别把里面三个文件夹里面的文件复制到CUDA所安装的目录对于的同名文件夹中。在下载软件包的时候,需要注意cuda8对应 cudnn6,cuda9 对应cudnn7。同时也要注意tensorflow-gpu的版本,本人的是1.4.0, 对应cuda8和cudnn6.

cudnn 8 download address: https://developer.nvidia.com/compute/machine-learning/cudnn/secure/v6/prod/8.0_20170307/cudnn-8.0-windows10-x64-v6.0-zip

  1. 检查一下系统的环境变量,(这一步基本可以省略)本人检查的时候,发现变量被自动添加进去了。到了这一步,最好重启一下电脑,或者使用其他方式在不用重启就能让环境变量生效。

(1)报错:

ImportError: Could not find 'cudart64_80.dll'. TensorFlow requires that this DLL be installed in a directory that is named in your %PATH% environment variable. Download and install CUDA 8.0 from this URL: https://developer.nvidia.com/cuda-toolkit

原因:没有找到cudart64_80.dll文件,因为当前tensorflow-gpu对应的是cuda 8.

解决:下载安装cuda 8(安装好之后最好重启一下电脑,让系统环境变量生效)

(2)下载安装好cuda 8之后:报错如下(新的错误):

Could not find 'cudnn64_6.dll'

原因:没找到文件。cuda8对应 cudnn6,cuda9 对应cudnn7.

解决:下载cudnn6,重新把cudnn6中的三个文件复制到cuda8相应的文件夹当中。

(3)最后可以正常运行起来了, 使用的数据集是MNIST。运行结果如下:

tensorflow测试gpu安装成功 tensorflow gpu安装_CUDA


上图表示,本人电脑的GUP才1G,型号才是GT 730的。因为GPU的内存过小,当本人测试cycleGan的时候,出现了下面的内存不够用的错误。OOM表示out of memory。解决方法是修改程序或者减少数据集或者增加电脑显卡配置。然而现在我只能选择前面两者。

ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[1,257,257,64]

简单测试:

不使用GPU所使用的时间:

tensorflow测试gpu安装成功 tensorflow gpu安装_cuda_02

使用了GPU的时间:

tensorflow测试gpu安装成功 tensorflow gpu安装_gpu_03


后者竟然是前者的两倍。也就是使用了GPU之后,反而用了更多时间。(瞬间被打脸了)。为什么? 测试所用的数据量太小了。

结束! 感谢!

最后是测试的代码:

"""A very simple MNIST classifier.
See extensive documentation at
https://www.tensorflow.org/get_started/mnist/beginners
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import sys
import time;

from tensorflow.examples.tutorials.mnist import input_data

import tensorflow as tf

FLAGS = None


def main(_):
    time_start = time.time();

    # Import data
    mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)

    # Create the model
    x = tf.placeholder(tf.float32, [None, 784])
    W = tf.Variable(tf.zeros([784, 10]))
    b = tf.Variable(tf.zeros([10]))
    y = tf.matmul(x, W) + b

    # Define loss and optimizer
    y_ = tf.placeholder(tf.float32, [None, 10])

    # The raw formulation of cross-entropy,
    #
    #   tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(tf.nn.softmax(y)),
    #                                 reduction_indices=[1]))
    #
    # can be numerically unstable.
    #
    # So here we use tf.nn.softmax_cross_entropy_with_logits on the raw
    # outputs of 'y', and then average across the batch.
    cross_entropy = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))
    train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

    sess = tf.InteractiveSession()
    tf.global_variables_initializer().run()
    # Train
    for _ in range(100000):
        batch_xs, batch_ys = mnist.train.next_batch(100)
        sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

    # Test trained model
    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

    time_end = time.time();
    print("using time: ", (time_end - time_start));


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--data_dir', type=str, default='d:/tmp/tensorflow/mnist/input_data',
                        help='Directory for storing input data')
    FLAGS, unparsed = parser.parse_known_args()
    tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)