实战|TensorFlow 实践之手写体数字识别!

本文的主要目的是教会大家运用google开源的深度学习框架tensorflow来实现手写体数字识别,给出两种模型,一种是利用机器学习中的softmax regression作分类器,另一种将是搭建一个深度神经网络以达到99%正确率的手写体数字识别模型。 其次,理解tensorflow工作流程和运行机制。最后,也会让大家了解一下深度神经网络的搭建过程。

第一种模型
我们知道,做机器学习的项目离不开数据,行业里有句话叫做“得数据者,得天下”,虽有点言过其实,但事实上,足够的样本数据是你获得较好模型的前提之一。这里,用到的是大名鼎鼎的mnist,其官网是http://yann.lecun.com/exdb/mnist/,大家可以自由下载。google给出的下载源码是input_data.py,可以从https://github.com/xupeng082008/tensorflow_mnist下载。下载后的数据集分为训练集、验证集、测试集(也就是train_data,validation_data,test_dasta,记住,这样的划分很重要,它可以检验我们得到的模型在真实场景下的识别能力)。无论是训练、验证还是测试集,单个样本都是一帧包含手写数字的28x28图像以及其对应的标签。有了数据,我们开始建立模型。这里的模型是机器学习经常用到的softmax regression。
简单地用图片来表示一下:

用乘积形式表示如下:

在tensorflow中,它是这样实现的:
import tensorflow as tf
y=tf.nn.softmax(tf.matmul(x,w) + b)
x是输入(这里可以理解为28x28的图像拉伸为一个1x784向量),w是网络权重系数,b是偏置。
代码相当简单,好理解。

下面贴出该模型所有的代码并作出解释
import tensorflow as tf
import input_data

#加载数据,注意一下one_hot 在tensorflow中,
#表示一个列向量,其中一个不为0,剩下的为0
mnist=input_data.read_data_sets("Mnist_data/",one_hot=True)
#在tensorflow中,tf.placeholder表示一个占位符,x不是一个特定的值,
#在运行时,才有值
x = tf.placeholder("float",[None,784])
#在tensorflow中,tf.Variable表示变量,且可以用不同的方式初始化
w = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
#softmax模型
y = tf.nn.softmax(tf.matmul(x,w) + b)
y_ = tf.placeholder("float",[None,10])
#模型的损失是交叉熵,详情可以见原创 干货|深度学习——损失函数不同,
收敛效率不同
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
#随机梯度下降优化算法
#主要:TensorFlow 在这里实际上所做的是,它会在后台给述你的计算的那张图
#里面增加一系列新的计算操作单元用于实现反向传播算法和梯度下降算法.然后,
#它返回给你的只是一个单一的操作,当运行这个操作时,它用梯度下降算法训练
#你的模型,微调你的变量,不断减少成本
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
#这里的代码跟tensorflow运行机制相关
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
for i in range(1000):#1000 or more
    batch_xs,batch_ys = mnist.train.next_batch(100)
    sess.run(train_step,feed_dict={x:batch_xs,y_:batch_ys})

correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float"))
print sess.run(accuracy,feed_dict={x:mnist.test.images,y_:mnist.test.labels})

这里简单说说tensorflow运行机制相关,让读者有一个感性的认识:
tensorflow使用图(graphs)来表示模型的整个计算过程
tensorflow在会话(Session)中执行图所表示的运行过程
tensorflow使用张量(tensors)来代表数据,可以表示为输入向量,权重系数等等
tensorflow通过变量(Variables)维护变量的运行状态
tensorflow使用供给(feeds)和取回(fetches)将数据传入或传出等操作
总之,tensorflow是以图来表示整个程序运行系统,图中以节点为组织,在会话中执行运行,然后产生张量,这个张量是一个四维向量,在图中流动起来。可以理解前面部分代码是在构建,后面是在执行。
上面的代码执行情况如下:
迭代次数正确率100091.19%500092.21%2000092.27%
可以,softmax regression在这里达到的最好成绩92%左右,跟理想的还差很远。

第二种模型
这里,我们的模型是一个有着两个卷积层,2个全联接层,一个输出层组成,继续使用交叉熵损失函数,激活函数是relu,并且使用dropout技术,结构图如下:
Inputconv1pool1conv2pool2fc1dropoutfc2softmax

下面,我们来看看在tensorflow如何实现上面表格实现的深度神经网络
import tensorflow as tf 
import input_data

mnist=input_data.read_data_sets("Mnist_data/",one_hot=True)
sess = tf.InteractiveSession()
x  = tf.placeholder("float",shape=[None,784])
y_ = tf.placeholder("float",shape=[None,10])

w = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

#init weights and biases
#初始化权重系数、偏置,注意这里初始化不是用0来填充,以打破对称性
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)

#define convolution and pool function
#定义卷积、池化,tensorflow中有实现,具体实践,我们自行修改参数
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')
#conv and pool 
#the first conv_pool
#patchsize(5x5) input_channels(1) output_channels(32 feature_maps)
w_conv1 = weight_variable([5,5,1,32])
b_conv1 = bias_variable([32])
x_image = tf.reshape(x,[-1,28,28,1])

#1st hidden outputs
h_conv1 = tf.nn.relu(conv2d(x_image,w_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

#the second conv_pool
w_conv2 = weight_variable([5,5,32,64])
b_conv2 = bias_variable([64])

#2nd hidden outputs
h_conv2 = tf.nn.relu(conv2d(h_pool1,w_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

#fc全联接层
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)

#dropout使用dropout技术可以防止过拟合
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)

#readout layer
w_fc2 = weight_variable([1024,10])
b_fc2 = bias_variable([10])

#softmax output
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop,w_fc2) + b_fc2)

#define loss function
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
#optimizer method choice
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,"float"))
sess.run(tf.initialize_all_variables())
for i in range(10000):
    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})
下面给出一些训练过程中间图:

可以看出,训练识别率还是很不错的,我们看下最终迭代10000次的训练和测试结果:

测试集上的正确率是99%左右。
可见深度神经网络,在手写体识别项目上表现地相比于softmax regression,效果会好的多的多。

总结
我们学习了在tensorflow中实现softmax regression、一种深度神经网络的过程;简单了解了tensorflow的运行机制和内部参数、函数机构,相信看完大家可以手动设计一个神经网络将识别率继续提高。

代码:https://github.com/xupeng082008/tensorflow_mnist

原文发布于微信公众号 - IT派(transfer_3255716726)

原文发表时间:2018-04-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

TensorFlow和深度学习入门教程

前言 上月导师在组会上交我们用tensorflow写深度学习和卷积神经网络,并把其PPT的参考学习资料给了我们, 这是codelabs上的教程:《Tensor...

3556
来自专栏AI科技大本营的专栏

如何在Python中用LSTM网络进行时间序列预测

Matt MacGillivray 拍摄,保留部分权利 翻译 | AI科技大本营(rgznai100) 长短记忆型递归神经网络拥有学习长观察值序列的潜力。它似...

9034
来自专栏人工智能头条

李理:卷积神经网络之Batch Normalization的原理及实现

3052
来自专栏小詹同学

深度学习入门笔记系列 ( 五 )

本系列将分为 8 篇 。本次为第 5 篇 ,结合上一篇的应用实例 ,将前边学到一些基础知识用到手写数字的识别分类上 。

802
来自专栏机器学习算法与Python学习

干货|详解CNN五大经典模型:Lenet,Alexnet,Googlenet,VGG,DRL

文章来源:CSDN 作者:大饼博士X 关于卷积神经网络CNN,网络和文献中有非常多的资料,我在工作/研究中也用了好一段时间各种常见的model了,就想着简单整...

7786
来自专栏深度学习那些事儿

我的模型能跑多快——神经网络模型速度调研(一)

对于神经网络,我们更多谈的是其精度怎么样,有百分之零点几的提升。但是如果谈到速度的话,深度学习神经网络相比于传统的算法来说,速度恐怕没有那么快了。

4031
来自专栏游戏开发那些事

【Unity3d游戏开发】游戏中的贝塞尔曲线以及其在Unity中的实现

  RT,马三最近在参与一款足球游戏的开发,其中涉及到足球的各种运动轨迹和路径,比如射门的轨迹,高吊球,香蕉球的轨迹。最早的版本中马三是使用物理引擎加力的方式实...

4751
来自专栏Python疯子

python人工智能:完整的图片识别(非图片验证码),以及模型的使用

这个可以说是一个绝对的福利中的福利。一整套的AI图片识别以及模型的使用。 一直都在说人工智能,图像识别,又有几个人会呢,网上文章成山,前一段时间因工作需要,我...

1231
来自专栏Coding迪斯尼

深度学习:将新闻报道按照不同话题性质进行分类

1032
来自专栏自学笔记

聚类算法

p=2时就说平时计算的几何距离,当p趋向于正无穷的时候,其实求的就不是x,y的距离了,而是求x y中最长的一个了。因为如果x大于y,在指数增长下x回远大于y,所...

2662

扫码关注云+社区