Tensorflow实现手写数字识别

运行环境

系统:Ubuntu18.04
环境:Python2.7,Tensorflow1.3.0
查看Tensorflow的版本以及安装路径使用tf.__version__tf.__path__
在这里插入图片描述

训练模型

前向传播

mnist_forward.py

#coding:utf-8
import tensorflow as tf

INPUT_NODE=784#输入的节点数是768
OUTPUT_NODE=10
LAYER1_NODE=500



def get_weight(shape,regularizer):
	w=tf.Variable(tf.truncated_normal(shape,stddev=0.1))
	if regularizer !=None:
	tf.add_to_collection('losses',tf.contrib.layers.l2_regularizer(regularizer)(w))#如果使用正则化,那么将每一个正则化损失加入到w中
	return w

def get_bias(shape):
	b=tf.Variable(tf.zeros(shape))
	return b

def forward(x,regularizer):
	w1=get_weight([INPUT_NODE,LAYER1_NODE],regularizer)
	b1=get_bias([LAYER1_NODE])
	y1=tf.nn.relu(tf.matmul(x,w1)+b1)
	
	w2=get_weight([LAYER1_NODE,OUTPUT_NODE],regularizer)
	b2=get_bias([OUTPUT_NODE])
	y=tf.matmul(y1,w2)+b2

	
	return y

反向传播

mnist_backward.py

#coding:utf-8
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import mnist_forward
import os



BATCH_SIZE=200
LEARNING_RATE_BASE=0.1
LEARNING_RATE_DECAY=0.99
REGULARIZER=0.0001
STEPS=50000
MOVING_AVERAGE_DECAY=0.99
MODEL_SAVE_PATH='./model/'
MODEL_NAME="mnist_model"

def backward(mnist):
    x=tf.placeholder(tf.float32,[None,mnist_forward.INPUT_NODE])
    y_=tf.placeholder(tf.float32,[None,mnist_forward.OUTPUT_NODE])
    y=mnist_forward.forward(x,REGULARIZER)#前向传播
    global_step=tf.Variable(0,trainable=False)

    

    #交叉熵定义损失函数,并且加上正则化参数

    '''

    计算labels和logits之间的交叉熵,y_是标准,y是计算得到的

    label是一个分类标签,是分类的概率,比如[0.3,0.3,0.3,0.1],每一行必须是一个概率分布,

    在这里是找到y_中数值最大的索引号

    '''
	ce=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_,1))
    cem=tf.reduce_mean(ce)
    loss=cem+tf.add_n(tf.get_collection("losses"))
    #指数衰减学习率
    learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,mnist.train.num_examples/BATCH_SIZE,LEARNING_RATE_DECAY,staircase=True)

    

    train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)

    #滑动平均
    ema=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)
    ema_op=ema.apply(tf.trainable_variables())

    with tf.control_dependencies([train_step,ema_op]):
        train_op=tf.no_op(name="train")

    saver=tf.train.Saver()#实例化saver

    with tf.Session() as sess:
        init_op=tf.global_variables_initializer()
        sess.run(init_op)

        ckpt=tf.train.get_checkpoint_state(MODEL_SAVE_PATH)#tf.train.get_checkpoint_state函数通过checkpoint文件找到模型文件名

        if ckpt and ckpt.model_checkpoint_path:
            saver.restore(sess,ckpt.model_checkpoint_path)#表示模型存储的位置,不需要提供模型的名字,它会去查看checkpoint文件,看看最新的是谁,叫做什么,然后恢复模型,其中global_step也会恢复


        for i in range(STEPS):
            xs,ys=mnist.train.next_batch(BATCH_SIZE)#当然可以通过迭代的形式以一定BATCH_SIZE读取数据,返回两个值,一个是图像数据,一个是图像数据对应的类别信息
            _,loss_value,step=sess.run([train_op,loss,global_step],feed_dict={x:xs,y_:ys})

            if i%1000==0:
                print "After %d training steps,loss on training batch is %g" %(step,loss_value)
                saver.save(sess,os.path.join(MODEL_SAVE_PATH,MODEL_NAME),global_step=global_step)

def main():
	mnist=input_data.read_data_sets("./input_data/Mnist_data",one_hot=True)
    backward(mnist)

    

if __name__=='__main__':
    main()

执行python mnist_backward.py来训练并保存模型。
训练过程如下:
在这里插入图片描述
可以看到损失值已经很小了。

训练好的模型如下图所示:
在这里插入图片描述
model_checkpoint_path是最新模型的名字,其中checkpoint文件记录了model_checkpoint_path
在这里插入图片描述

测试模型

使用mnist自带的测试数据来进行测试准确率
mnist_test.py

#coding:utf-8
import time
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import mnist_forward
import mnist_backward
TEST_INTERVAL_SECS=5

def test(mnist):
    with tf.Graph().as_default() as g:
        x=tf.placeholder(tf.float32,[None,mnist_forward.INPUT_NODE])
        y_=tf.placeholder(tf.float32,[None,mnist_forward.OUTPUT_NODE])
        y=mnist_forward.forward(x,None)
        
        #滑动平均
        ema=tf.train.ExponentialMovingAverage(mnist_backward.MOVING_AVERAGE_DECAY)
        ema_restore=ema.variables_to_restore()
        saver=tf.train.Saver(ema_restore)

        

        #y和y_的差距,准确率的计算
        correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(y_,1))#argmax函数取最大值的索引号
        accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))       

        while True:
            with tf.Session() as sess:
                ckpt=tf.train.get_checkpoint_state(mnist_backward.MODEL_SAVE_PATH)
                if ckpt and ckpt.model_checkpoint_path:
                    saver.restore(sess,ckpt.model_checkpoint_path)#restore恢复,复原为sess                   global_step=ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
                    accuracy_score=sess.run(accuracy,feed_dict={x:mnist.test.images,y_:mnist.test.labels})
                    print sess.run(tf.argmax(y,1),feed_dict={x:mnist.test.images})#第二个参数为0时是对比每一列y轴最大值的坐标,为1是对比每一行x轴最大值的坐标
                    print("After %s training steps .test accuracy= %g" %(global_step,accuracy_score))
                else:
                    print "No checkpoint file found"
                    return
            time.sleep(TEST_INTERVAL_SECS)
def main():    mnist=input_data.read_data_sets('./input_data/Mnist_data',one_hot=True)
    test(mnist)
if __name__=="__main__":
    main()

运行结果:
在这里插入图片描述
可以看到,准确率已经达到0.9805。

使用图片进行验证模型

既然训练出了模型,那我们就用模型进行预测试试看。
代码如下:

#coding:utf-8
import tensorflow as tf
import numpy as np
import mnist_backward
import mnist_forward
from PIL import Image

def restore_model(PirArr):
	with tf.Graph().as_default() as g:
		x=tf.placeholder(tf.float32,[None,mnist_forward.INPUT_NODE])
		y=tf.argmax(mnist_forward.forward(PirArr,None),1)
		

		#滑动平均
		ema=tf.train.ExponentialMovingAverage(mnist_backward.MOVING_AVERAGE_DECAY)
		ema_restore=ema.variables_to_restore()
		saver=tf.train.Saver(ema_restore)	
		with tf.Session() as sess:
			ckpt=tf.train.get_checkpoint_state(mnist_backward.MODEL_SAVE_PATH)
			if ckpt and ckpt.model_checkpoint_path:
				saver.restore(sess,ckpt.model_checkpoint_path)
				result=sess.run(y,feed_dict={x:PirArr})
				return result
			else:
				print "模型不存在"
				return -1
def pre_pic(picname):
	img=Image.open(picname)
	reIm=img.resize((28,28),Image.ANTIALIAS)#ANRIALIAS去掉锯齿
	im_arr=np.array(reIm.convert('L'))#将图片变为黑白的,并将图片返回一个array
	threshold=50
	for i in range(28):
		for j in range(28):
			im_arr[i][j]=255-im_arr[i][j]
			if im_arr[i][j]<threshold:
				im_arr[i][j]=0
			else:
				im_arr[i][j]=255
	nm_arr=im_arr.reshape([1,784])
	nm_arr=nm_arr.astype(np.float32)
	img_ready=np.multiply(nm_arr,1.0/255.0)
	return img_ready

def application():
	testNUM=input("请输入准备识别的图片的个数:")
	for i in range(testNUM):
		testPic=raw_input("图片的路径和名字")
		testPirArr=pre_pic(testPic)
		preValue=restore_model(testPirArr)
		print "这个数字是:%d" %(preValue)
def main():
	application()

if __name__=="__main__":
	main()

然后输入以下两张图片:
在这里插入图片描述
得到结果:
在这里插入图片描述
这样就完成了tensorflow搭建的手写数字识别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值