您的位置:首页 > 理论基础 > 计算机网络

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

2017-09-17 18:05 477 查看
上学期钻研了下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 tf
hello = 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_import
from __future__ import division
from __future__ import print_function

import gzip
import os
import tempfile

import numpy
from six.moves import urllib
from six.moves import xrange

import tensorflow as tf
from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets

class 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官网
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息