tensorflow实战之手写体识别

本人由于一直从事语义理解引擎开发工作,更多的是接触人机交互系统的优化,模型的落地上线,业务的效果优化等工作,deepLearning接触的不是很多,本篇开始,从零开始学习深度学习知识,深入理解交互系统的整体,从模型到架构。这里主要是用于记录 自己从网上开源的或者其他大神的blog学习。

一.简介

MNIST是开源的一个手写体识别的数据集,该数据集中包含了大量的手写图片,我们这里需要通过对模型的训练,对给出一张图片进行分类,主要包括三个部分:

(1).训练数据集,55000个样本,mnist.train

(2).测试数据集,10000个样本,mnist.test

(3).验证数据集,5000个样本,mnist.validation

tensorflow实战之手写体识别_第1张图片

从某位大神blog中盗图一张,如下:

tensorflow实战之手写体识别_第2张图片

 

每张图片是28*28=784个像素点,白色地方是0,黑色地方都是表示有数字,下面的左边是数字1,右边是图片的像素点

tensorflow实战之手写体识别_第3张图片

二.具体的分类过程(代码)

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

mnist = input_data.read_data_sets("MNIST_data",one_hot=True) #one_hot=True 样本标签标记为one-hot 编码

print('输入数据:',mnist.train.images)
print('输入数据的尺寸:',mnist.train.images.shape)

im = mnist.train.images[0]  #第一张图片
im = im.reshape(-1,28)


tf.reset_default_graph()   #清除默认图形堆栈并重置全局默认图形
#定义占位符
x=tf.placeholder(tf.float32,[None,784])   #图像28*28=784
y=tf.placeholder(tf.float32,[None,10])    #标签10类

#定义学习参数
w=tf.Variable(tf.random_normal([784,10])) #权值,初始化为正太随机值
b=tf.Variable(tf.zeros([10]))             #偏置,初始化为0
#定义输出

pred=tf.nn.softmax(tf.matmul(x,w)+b)      #相当于单层神经网络,激活函数为softmax
#损失函数
loss=tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1))  #reduction_indices指定计算维度
#优化函数
optimizer=tf.train.GradientDescentOptimizer(0.01).minimize(loss) ##loss是优化目标函数
#定义训练参数
training_epochs=200   #训练次数
batch_size=100       #每次训练图像数量
display_step=10       #打印训练信息周期
#保存模型
saver=tf.train.Saver()
model_path="data/521model.ckpt"
#开始训练
with tf.Session() as sess :
    sess.run(tf.global_variables_initializer())   #初始化所有参数
    for epoch in range(training_epochs) :
        avg_cost=0.0                               #平均损失
        total_batch=int(mnist.train.num_examples/batch_size)   #计算总的训练批次
        for i in range(total_batch) :
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)  #抽取数据
            _, c=sess.run([optimizer,loss], feed_dict={x:batch_xs, y:batch_ys})  #运行
            avg_cost+=c/total_batch
        if (epoch+1) % display_step == 0 :
            print("Epoch:",'%04d'%(epoch+1),"cost=","{:.9f}".format(avg_cost))
    print("Finished!")
    #测试集测试准确度
    correct_prediction=tf.equal(tf.argmax(pred,1),tf.argmax(y,1))
    accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))  ###correct_prediction bool值转换成float
    print("Accuracy:",accuracy.eval({x:mnist.test.images,y:mnist.test.labels}))
    #保存模型
    save_path=saver.save(sess,model_path)
    print("Model saved in file: %s" % save_path)

运行的结果如下:

tensorflow实战之手写体识别_第4张图片

三.具体步骤分析

1.定义占位符

x=tf.placeholder(tf.float32,[None,784])   #图像28*28=784
y=tf.placeholder(tf.float32,[None,10])    #标签10类

图片像素是28*28=784,这里主要是把二维的像素矩阵,扁平化的生成为一维,标签的分类为0到9,一共是10,None主要是不确定输入的batch大小

2.定义学习参数

w=tf.Variable(tf.random_normal([784,10])) #权值,初始化为正太随机值
b=tf.Variable(tf.zeros([10]))             #偏置,初始化为0

tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

(1).shape为输出张量的形状,必须要选择

(2).mean 正态分布的均值,默认是0

(3).stddev 表示正态分布的标准差,默认是1.0

(4).dtype是输出类型

(5).seed是随机数种子,设置之后 每次生成的随机数都一样

(6).name表示的是操作的名称

tf.zeros( shape, dtype=tf.float32, name=None )

(1). shape 表示输出的形状大小,必须

(2).dtype 表示的是类型

(3).name表示的是操作名称

3.定义输出层

pred=tf.nn.softmax(tf.matmul(x,w)+b)

激活函数是softmax,相当于单层的神经网络

4.定义误差loss和训练

交叉熵(Cross Entropy):是loss中的一种,也是损失函数或代价函数,用于描述模型预测值和真实值之间的差距,一般常见的loss为均方平方差(Mean Squared Error),交叉熵描述两个概率分布之间的距离。。当交叉熵越小,越说明二者之间越接近。

本篇计算公式为 tf.reduce_mean(-tf.reduce_sum(ys * tf.log(pred))

#损失函数
loss=tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1))  #reduction_indices指定计算维度
#优化函数
optimizer=tf.train.GradientDescentOptimizer(0.01).minimize(loss) ##loss是优化目标函数

四.使用LSTM进行模型分类

# coding:utf-8
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
from tensorflow.contrib import rnn
mnist=input_data.read_data_sets("MNIST_data/",one_hot=True)


#parameters set 

lr = 0.01
train_iter = 100000
batch_size = 100
n_inputs = 28
n_steps = 28
n_hidden_unites = 128
n_classes = 10
n_batch = mnist.train.num_examples//batch_size


x_ = tf.placeholder(tf.float32,[None,784])
y_ = tf.placeholder(tf.float32,[None,10])

weights = tf.Variable(tf.truncated_normal([n_hidden_unites,n_classes],stddev=0.1))  ### 128*10
bias = tf.Variable(tf.constant(0.1,shape=[n_classes])) ##常量设置  [0.1,0.1,0.1,....0.1]

### y = wx + b

def RnnModel(x,w,b):
	input = tf.reshape(x,[-1,n_steps,n_inputs]) ##shape  28*28
	lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden_unites)
	outputs,finally_class = tf.nn.dynamic_rnn(lstm_cell,input,dtype=tf.float32)
	y = finally_class[1] ## the step is import 
	
	results = tf.nn.softmax(tf.matmul(y,w) + b)
	
	return results
	
	
if __name__ == '__main__':
	
	predict = RnnModel(x_,weights,bias)
	loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = predict, labels = y_))
	train_step = tf.train.AdamOptimizer(1e-3).minimize(loss)
	
	
	correct_prediction = tf.equal(tf.argmax(y_, 1), tf.argmax(predict, 1)) ###tf.argmax(y,1) 每一行的最大值元素输出数组[]
	accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) ##计算正确率 tf.cast是类型转换
	init = tf.global_variables_initializer()
	
	with tf.Session() as sess:
		sess.run(init)
		for epoch in range(20):
			for iter in range(n_batch):
				batch_xs, batch_ys = mnist.train.next_batch(batch_size)
				sess.run(train_step,feed_dict={x_: batch_xs,y_:batch_ys})
				
			acc = sess.run(accuracy,feed_dict={x_:mnist.test.images,y_:mnist.test.labels})
			print("Iter " + str(epoch) + ", Testing Accuracy=" + str(acc))
	

tensorflow实战之手写体识别_第5张图片

你可能感兴趣的:(tensorflow学习,tensorflow)