Tensorflow练手项目 - 使用CNN进行手写数字识别

首先书写如下的代码

代码有详细的注释,这里就不一一解释了


#coding=utf-8
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import  input_data
#引入数据集
mnist=input_data.read_data_sets('MNIST_data',one_hot=True)

#用于输出准确度的函数
def compute_accuary(v_xs,v_ys):
    global  prediction
    y_pre=sess.run(prediction,feed_dict={xs:v_xs,keep_prob:1}) #这里会带入要预测的x_xs参数,使用run方法带动整个由输入到输出的过程,产生预测softmax输出y_pre(都是概率值)

    correct_prediction=tf.equal(tf.argmax(y_pre,1),tf.argmax(v_ys,1))#这里每次会获得y_pre和v_ys最大项的索引看是不是相同,相同的话cooe--矩阵对应位置为1
    #print 'correct_prediction:'+correct_prediction
    accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))#根据矩阵中1的比例得到准确率
    results=sess.run(accuracy,feed_dict={xs:v_xs,ys:v_ys,keep_prob:1})#用于启动上面的计算过程
    return results


#初始化权重量
def weight_variable(shape):
    #truncated_normal用于从截断的正太分布中输出随机值   stddev是标准差  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):
    #定义一个卷积操作        莫烦这里进行卷积操作时层大小是不发生变化的,估计是因为设置了SAME的原因
    #第一个参数input:指需要做卷积的输入图像,它要求是一个Tensor,具有[batch, in_height, in_width, in_channels]
    # 这样的shape,具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],注意这是一个4维的Tensor,要求类型为float32和float64其中之一
    # 第二个参数filter:相当于CNN中的卷积核,它要求是一个Tensor,具有[filter_height, filter_width, in_channels,out_channels]
    # 这样的shape,具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维
    # 第三个参数strides:卷积时在图像每一维的步长,这是一个一维的向量,长度4,  每步这里水平,竖直都是夸的1步
    # 第四个参数padding:string类型的量,只能是"SAME", "VALID"  其中之一,这个值决定了不同的卷积方式  VALID是小于等于方式的抽取,SAME是大于等于抽取,不足的地方用0进行填充,能保留更多信息
    return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')


def max_pool_2x2(x):
    #一个池化操作
    # 第一个参数value:需要池化的输入,一般池化层接在卷积层后面,所以输入通常是feature map,依然是[batch, height,width, channels]这样的shape
    # 第二个参数ksize:池化窗口的大小,取一个四维向量,一般是[1, height, width, 1],因为我们不想在batch(批)和channels(通道)上做池化,所以这两个维度设为了1
    # 第三个参数strides:和卷积类似,窗口在每一个维度上滑动的步长,一般也是[1, stride, stride, 1]
    # 第四个参数padding:和卷积类似,可以取'VALID'或者'SAME'返回一个Tensor,类型不变,shape仍然是[batch, height,width, channels]这种形式
    return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')

#定义用于保存数据的占位符placeholder     None是指维度 默认是一维
xs=tf.placeholder(tf.float32,[None,784])#28*28 这是单通道上的
ys=tf.placeholder(tf.float32,[None,10])
keep_prob=tf.placeholder(tf.float32) #这里定义占位符是后面 进行dropout时的比例
x_image=tf.reshape(xs,[-1,28,28,1])# 指定图像信息的形式   -1是指指定先不管图像维度n_samples,  1是channel因为这是黑白的指定1就行了
##############################定义图结构 图像->卷积层->池化层->卷积层->池化层->全连接层->全连接层#####################
#定义第一个小结构 先卷积再池化
W_conv1=weight_variable([5,5,1,32]) #定义第一个连线上的W,patch大小为5*5,线W的总数很大,输入厚度是1(图像是是1维的),输出是32维对应是32张平铺的图
b_conv1=bias_variable([32])#每个池化层feature map对应一个b偏差值
h_conv1=tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)#传入参数进行卷积运算   并进行非线性转换  池化层神经元数量:28*28*32
h_pool1=max_pool_2x2(h_conv1)#一次指定窗口的池化  变成14*14*32
#定义第二个小结构 先卷积再池化
W_conv2=weight_variable([5,5,32,64]) #定义第一个连线上的W,patch大小为5*5,线W的总数很大,输入厚度是1(图像是是1维的
b_conv2=bias_variable([64])#每个池化层feature map对应一个b偏差值
h_conv2=tf.nn.relu(conv2d(h_pool1,W_conv2)+b_conv2)#传入参数进行卷积运算   并进行非线性转换  池化层神经元数量:14*14*64
h_pool2=max_pool_2x2(h_conv2)#一次指定窗口的池化  变成7*7*64
#定义第一个全连接层      全连接的方式会先对讲pool结果进行格式重置   之后使用一般的乘法得到目标矩阵
W_fc1=weight_variable([7*7*64,1024]) #因为这是一种全连接的方式,因此这里可以 可以用入神经元数 出神经数这样的方式指定,毕竟最后要构建的W数量是7*7*64*1024
b_fc1=bias_variable([1024])
h_pool2_flat=tf.reshape(h_pool2,[-1,7*7*64]) #先对h_pool进行转换成一维度simple 由64维变成1维  大小7*7*64
h_fc1=tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1)+b_fc1) #矩阵相乘
h_fc1_drop=tf.nn.dropout(h_fc1,keep_prob)
#第二个全连接层
W_fc2=weight_variable([1024,10]) #因为这是一种全连接的方式,因此这里可以 可以用入神经元数 出神经数这样的方式指定,毕竟最后要构建的W数量是7*7*64*1024
b_fc2=bias_variable([10])
prediction=tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2)+b_fc2) #  使用softmax正好能够转化得到概率
############################################################################################################

#定义损失函数和训练方式
cross_entropy=tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),reduction_indices=[1]))# 定义交叉商reduction_indices指定维度
train_step=tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
sess=tf.Session()
sess.run(tf.global_variables_initializer())
for i in range(1,1000):
    print('i:',i)
    batch_xs,batch_ys=mnist.train.next_batch(100)
    #print 'i:',batch_xs,'   ',batch_ys
    sess.run(train_step,feed_dict={xs:batch_xs,ys:batch_ys,keep_prob:0.5})
    if i%10==0:
        print(compute_accuary(mnist.test.images[:1000], mnist.test.labels[:1000]))



可以如下发现伴随着训练的进行,模型在测试机上的准确率如下:

 

最后模型在训练100000次后结束,最后得分在0.95左右。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值