项目:手写数字识别~单层(全连接层)实现手写数字识别:
先验知识:
(1)了解数据集mnist的获取,可以通过API获取数据集
from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets("E:/Python/Pycharm/CNN/TensorFlow/data/mnist/",one_hot=True)
(2)批次训练API:mnist.train.next_batch();
(3)所有的实例定义和变量收集,全局初始化变量都需要在会话之前进行
(4)权重,偏值的定义必须用变量来定义API
(5)训练:得出模型model;测试:根据model进行相关测试
(6)更新参数组成的分布是符合正态分布的
(7)训练的准确率有上限的原因:建立的网络只有全连接层且算法简单,需要设计更复杂的网络来打破ACC的上限
一.训练过程
项目流程:
0 | 项目流程 |
1 | 准备数据 |
2 | 全连接结果计算 |
3 | 损失优化 |
4 | 模型评估(计算准确性) |
1.准备数据或是定义数据占位符能够实时提供数据: (1)特征值[none,784] 目标值[none,10],10:one-hot; (2)placeholder:运行时实时提供数据
with tf.variable_scope("data"):
x=tf.placeholder(tf.float32,[None,784])
y_true=tf.placeholder(tf.int32,[None,10])
2.建立全连接层的神经网络结果计算,建立模型:
随机初始化:权重和偏值,变量定义 w[784,10],b[10] y_predict=tf.matmul(x,w)+b
with tf.variable_scope("fc_model"):
#随机即初始化权重和偏值
weight=tf.Variable(tf.random_normal([784,10],mean=0.0,stddev=1.0),name="W")
bias=tf.Variable(tf.constant(0.0,shape=[10]))
#预测none个样本输出结果[none,784]*[784,10]+[10]=[none,10]
y_predict=tf.matmul(x,weight)+bias
之后不断通过梯度向下更新 3.计算损失: (1)loss平均样本损失:每个样本都有一个交叉熵损失;求出所有样本损失,求平均
#3.求出所有样本损失,求平均值
with tf.variable_scope("soft_cross"):
#求平均交叉熵损失
loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))
(2)梯度下降优化:指定学习率,优化损失
#梯度下降求出损失
with tf.variable_scope("optimizer"):
train_op=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
4.模型评估:计算准确率,通过比较概率最大的位置
#计算准确率
with tf.variable_scope("acc"):
equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))
accuracy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
通过以上四步,我们的框架基本搭建完成,接下来就可以去开启会话了
开启回话:
with tf.Session() as sess:
在会话之前必须执行(1)
(1)定义一个初始化变量op,并在会话中初始化
init_op=tf.global_variables_initializer()
sess.run(init_op)
(2)迭代步数训练,更新参数预测
for i in range(2000):
取出真实存在的特征值和目标值
mnist_x,mnist_y=mnist.train.next_batch(50)
运行train_op:实时提供数据
sess.run(train_op,feed_dict={x:mnist_x ,y_true:mnist_y})
打印损失和准确率,运行acc,必须提供feed_dict={}
print("训练第%d步,准确率为%f"%(i,sess.run(accuracy,feed_dict={x:mnist_x ,y_true:mnist_y})))
需要观察准确率和损失如何变化,还需要收集变量,会话之前完成
(1)收集变量,单维度变量
tf.summary.scalar("losses",loss)
tf.summary.scalar("acc",accuracy)
(2)高纬度收集:w,b
#高纬度变量收集
tf.summary.histogram("weight",weight)
tf.summary.histogram("bias",bias)
(3)定义一个合并变量的op,等下要运行op,把值拿出来写到文件中
merge=tf.summary.merge_all()
接下来,在会话中建立event文件:把值写入文件中,tensorboard再从文件中读取
filewriter=tf.summary.FileWriter("E:/Python/Pycharm/CNN/TensorFlow/events/test/",graph=sess.graph)
filewriter:是要把运行变量的值run(merge)写进去,把每步训练的值都写入进去,在打印准确率之前
summary=sess.run(merge,feed_dict={x:mnist_x ,y_true:mnist_y})
filewriter.add_summary(summary,i)
接下来可以通过tensorboard命令来可视化观察:这里不做展示,大家可以自己动手试一试,
结果是准确率上升,损失率下降(梯度下降优化损失,更新参数)更新参数组成的分布是符合正态分布的
tensorboard --logdir="当前文件夹目录"
保存模型:
(1)定义一个保存模型的实例(在会话之前定义);
#定义一个保存模型的实例
saver=tf.train.Saver()
(2)保存
saver.save(sess,"E:/Python/Pycharm/CNN/TensorFlow/ckpt/fc_model")
训练工作完成:在指定的2000步优化结束后得到模型fc_model
##########################################################################################################################################################
##########################################################################################################################################################
##########################################################################################################################################################
##########################################################################################################################################################
##########################################################################################################################################################
接下来:测试
二.测试过程
训练完成保存模型,可以测试一下,把特征值找出来,看测试集的准确率
建立的网络,算法简单,不断训练准确率是有上限,需要更复杂的网络
测试代码:可以照着训练过程,编写一个if,else结构即可,判断训练和测试
(1)加载模型fc_model
(2)取出批次测试数据
(3)可视化打印
for i in range(100):
saver.restore(sess,"E:/Python/Pycharm/CNN/TensorFlow/ckpt/fc_model")
#取出真实存在的特征值目标值
x_test,y_test=mnist.test.next_batch(1)
print("第%d张图片,手写数字目标:%d,预测结果为为%d,准确率为%f"%(i,tf.argmax(y_test,1).eval(),tf.argmax(sess.run(y_predict,feed_dict={x:x_test,y_true:y_test}),1).eval(),sess.run(accuracy,feed_dict={x:x_test,y_true:y_test})))
三.完整代码
import tensorflow as tf
import os
from tensorflow.examples.tutorials.mnist import input_data
tf.app.flags.DEFINE_string("model_dir","E:/Python/Pycharm/CNN/TensorFlow/ckpt/mode/model","模型文件加载的路径")
tf.app.flags.DEFINE_integer("is_train",0,"指定程序预测或是训练")
FLAGS=tf.app.flags.FLAGS
def full_connectes():
#获取真实数据
mnist=input_data.read_data_sets("E:/Python/Pycharm/CNN/TensorFlow/data/mnist/",one_hot=True)
#1.建立数据的占位符x[none,784] y_true[none,10]
with tf.variable_scope("data"):
x=tf.placeholder(tf.float32,[None,784])
y_true=tf.placeholder(tf.int32,[None,10])
#2.建立·全连接层的神经网络w[784,10],b[10]
with tf.variable_scope("fc_model"):
#随机即初始化权重和偏值
weight=tf.Variable(tf.random_normal([784,10],mean=0.0,stddev=1.0),name="W")
bias=tf.Variable(tf.constant(0.0,shape=[10]))
#预测none个样本输出结果[none,784]*[784,10]+[10]=[none,10]
y_predict=tf.matmul(x,weight)+bias
#3.求出所有样本损失,求平均值
with tf.variable_scope("soft_cross"):
#求平均交叉熵损失
loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))
#4.梯度下降求出损失
with tf.variable_scope("optimizer"):
train_op=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
#5.计算准确
with tf.variable_scope("acc"):
equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))
accuracy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
#收集变量
tf.summary.scalar("losses",loss)
tf.summary.scalar("acc",accuracy)
#高纬度变量收集
tf.summary.histogram("weight",weight)
tf.summary.histogram("bias",bias)
#定义一个合并变量
merge=tf.summary.merge_all()
#定义一个保存模型的实例
saver=tf.train.Saver()
init_op=tf.global_variables_initializer()
#开启回话训练
with tf.Session() as sess:
#初始化变量
sess.run(init_op)
#建立evevt文件,写入
filewriter=tf.summary.FileWriter("E:/Python/Pycharm/CNN/TensorFlow/events/test/",graph=sess.graph)
# #加载模型,覆盖模型当中随机定义的参数,从上次训练的参数结果开始
# if os.path.exists("E:/Python/Pycharm/CNN/TensorFlow/ckpt/mode/"):
# # saver.restore(sess,"E:/Python/Pycharm/CNN/TensorFlow/ckpt/model")
# saver.restore(sess,FLAGS.model_dir)
if FLAGS.is_train==1:
#迭代步数训练,更新参数预测
for i in range(2000):
#取出真实存在的特征值目标值
mnist_x,mnist_y=mnist.train.next_batch(50)
sess.run(train_op,feed_dict={x:mnist_x ,y_true:mnist_y})
#写入每步训练的值
summary=sess.run(merge,feed_dict={x:mnist_x ,y_true:mnist_y})
filewriter.add_summary(summary,i)
print("训练第%d步,准确率为%f"%(i,sess.run(accuracy,feed_dict={x:mnist_x ,y_true:mnist_y})))
saver.save(sess,"E:/Python/Pycharm/CNN/TensorFlow/ckpt/fc_model")
else:
for i in range(100):
saver.restore(sess,"E:/Python/Pycharm/CNN/TensorFlow/ckpt/fc_model")
#取出真实存在的特征值目标值
x_test,y_test=mnist.test.next_batch(1)
print("第%d张图片,手写数字目标:%d,预测结果为为%d,准确率为%f"%(i,tf.argmax(y_test,1).eval(),tf.argmax(sess.run(y_predict,feed_dict={x:x_test,y_true:y_test}),1).eval(),sess.run(accuracy,feed_dict={x:x_test,y_true:y_test})))
if __name__=="__main__":
full_connectes()