TensorFlow安装与入门: 使用CNN训练MNIST

来源:互联网 发布:js mouseover 编辑:程序博客网 时间:2024/05/22 03:02

上学期钻研了下Python3人工神经网络,如多层感知器、卷积神经网络等算法原理,这学期要在此基础上使用深度学习研究运动状态识别的问题。这两天看了下TensorFlow这个框架,官网的文档写的非常详细,Google大法好啊!在这里记录下遇到的小问题,以及参考官网的说明写的使用CNN训练MNIST的Python代码。

TensorFlow安装

TensorFlow是一个使用数据流图进行数值计算的开源软件库。图中的节点代表数学运算, 而图中的边则代表在这些节点之间传递的多维数组(张量)。这种灵活的架构可让您使用一个 API 将计算工作部署到桌面设备、服务器或者移动设备中的一个或多个 CPU 或 GPU。

按照官网的说明,安装Tensorflow(GPU版,Windows平台)需要安装以下软件:

  • NVIDIA一块计算能力大于3的显卡
  • CUDA® Toolkit 8.0
  • cuDNN v6.1
  • Python 3.5

我台式机显卡是GeForce GTX 750,对应的计算能力为5.0,就凑合着先用。上述环境安装好后可以直接使用Python自带的pip3工具安装Tensorflow:

pip3 install --upgrade tensorflow-gpu

完毕后运行下面的Python脚本已测试是否安装成功:

import tensorflow as tfhello = tf.constant('Hello, TensorFlow!')sess = tf.Session()print(sess.run(hello))

如果能顺利运行并且输出 Hello, TensorFlow! ,那么就安装完成了。
安装的时候要注意添加环境变量(官网上也提示了)。但最终,我的代码并没有输出 Hello, TensorFlow! ,而是提示了什么DLL错误,网上也有很多人遇到了这种错误,解决办法就是 将cuDNN安装文件夹下的 bin/cudnn64_6.dll文件拷贝到CUDA® Toolkit 8.0安装目录的CUDA/v8.0/bin目录下。

在看官网文档的时候刚开始没弄明白Tensor Ranks, Shapes是啥回事,后来看了几段代码才整明白。张量的Ranks有点像矩阵的维度,指表示一个值的位置时所需要的坐标数量,而shape我的理解是度量了张量各个rank方向上的长度。
比如张量[[1,2],[3,4]]的rank等于2,shape为[2,2];张量[[1,2],[3,4],[5,6]]的rank等于2,shape为[3,2]。

使用CNN训练MNIST

Tensorflow官网给了一个训练MNIST的详细步骤:[Deep MNIST for Experts](https://www.tensorflow.org/get_started/mnist/pros)
我在此基础上将其封装成了一个类,就当是在熟悉Tensorflow和Python3 :

from __future__ import absolute_importfrom __future__ import divisionfrom __future__ import print_functionimport gzipimport osimport tempfileimport numpyfrom six.moves import urllibfrom six.moves import xrangeimport tensorflow as tffrom tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_setsclass Mnist():    # 第一层卷积输出特征数量    out_features1 = 12    # 第二层卷积输出特征数量    out_features2 = 24    # 全连接层神经元数量    con_neurons = 512    def __init__(self, path):        self.sess = tf.Session()        self.data = read_data_sets(path, one_hot=True)    """权重初始化函数"""    def weight_variable(self, shape):        # 输出的随机数满足 截尾正态分布        initial = tf.truncated_normal(shape, stddev=0.1)        return tf.Variable(initial)    """偏置初始化函数"""    def bias_variable(self, shape):        initial = tf.constant(0.1, shape=shape)        return tf.Variable(initial)    """二维卷积函数"""    def conv2d(self, x, W):        # input : 输入数据[batch, in_height, in_width, in_channels]        # filter : 卷积窗口[filter_height, filter_width, in_channels, out_channels]        # strides: 卷积核每次移动步数,对应着输入的维度方向        # padding='SAME' : 输入和输出的张量形状相同        return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')    """池化函数"""    def max_pool_2x2(self, x):        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')    """构建卷积层"""    def create_conv_layer(self, input, input_features, out_features):        W_conv = self.weight_variable([5, 5, input_features, out_features])        b_conv = self.bias_variable([out_features])        h_conv = tf.nn.relu(self.conv2d(input, W_conv) + b_conv)        h_pool = self.max_pool_2x2(h_conv)        return h_pool    """构建密集连接层"""    def create_con_layer(self, h_pool_flat, input_freatures, con_neurons):        W_fc = self.weight_variable([input_freatures, con_neurons])        b_fc = self.bias_variable([con_neurons])        h_fc1 = tf.nn.relu(tf.matmul(h_pool_flat, W_fc) + b_fc)        return h_fc1    """神经网络构建"""    def build(self):        # 输入        self.x = tf.placeholder(tf.float32, shape=[None, 784])        x_image = tf.reshape(self.x, [-1, 28, 28, 1])        # 输出        self.y_ = tf.placeholder(tf.float32, shape=[None, 10])        # 第一层        h_pool1 = self.create_conv_layer(x_image, 1, self.out_features1)        # 第二层        h_pool2 = self.create_conv_layer(h_pool1, self.out_features1, self.out_features2)        # 密集连接层        h_pool2_flat_freatures = 7*7*self.out_features2        h_pool2_flat = tf.reshape(h_pool2, [-1, h_pool2_flat_freatures])        h_fc = self.create_con_layer(h_pool2_flat, h_pool2_flat_freatures, self.con_neurons)        # Dropout        self.keep_prob = tf.placeholder("float")        h_fc1_drop = tf.nn.dropout(h_fc, self.keep_prob)        # 输出层        W_fc = self.weight_variable([self.con_neurons, 10])        b_fc = self.bias_variable([10])        y_conv = tf.matmul(h_fc1_drop, W_fc) + b_fc        # 评价        correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(self.y_, 1))        self.accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))        # 训练方法        cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=self.y_, logits=y_conv))        self.train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)    """训练"""    def train(self):        self.sess.run(tf.global_variables_initializer())        for i in range(2000):            batch = self.data.train.next_batch(50)            if i % 100 == 0:                print('Training step %d:' % i)                self.eval(batch[0], batch[1], 1.0)            self.sess.run(self.train_step, {self.x: batch[0], self.y_: batch[1], self.keep_prob: 0.5})    """评价"""    def eval(self, x, y, keep_prob):        train_accuracy = self.sess.run(self.accuracy, {self.x: x, self.y_: y, self.keep_prob: keep_prob})        print('     accuracy %g' % train_accuracy)        return train_accuracy    """关闭会话"""    def close(self):        self.sess.close()""" START """mnist = Mnist('MNIST_data/')mnist.build()mnist.train()print('\n----- Test -----')mnist.eval(mnist.data.test.images, mnist.data.test.labels, 1.0)mnist.close()

这段代码应该能直接运行,但是参数和官网有所区别(显卡太渣了,按照官网的参数跑会报OOM错误),最后的测试准确率也就0.9683(只迭代了2000次,调成20000次后会更接近于官网的结果)。不过这段代码涉及到了很多Tensorflow的基本知识,比如会话、占位符、图、构建图、Feed等等。

总之要继续努力,室友警告这一块是个大坑。。。万一毕不了业怎么办-_-||

参考链接:
Tensorflow官网

原创粉丝点击