import os
import cv2
import numpy as np
import tensorflow as tf2
import matplotlib.pyplot as plt
import tensorflow.compat.v1 as tf
import tensorflow.compat.v1 as tf
这句话是为了将tensorflow 2.x转为1.x,tensorflow1.x更能表现网络结构
import os
是调用系统,可有可无,为了不显示警告内容所以调用该模块
def nextBatch(data,batch_size,n):#小批量梯度下降法获取当前数据集函数
#data为全部数据[X,Y],batch_size为当前子数据集大小,n为第n个子数据集
a=n*batch_size
b=(n+1)*batch_size
limdata=len(data[0])
if b>limdata:
b=limdata
a=b-batch_size
data_x=data[0][a:b]
data_y=data[1][a:b]
return data_x,data_y
这里是为了将数据集切割成小批量数据,完成训练,小批量训练结果更好。
def main_train():
(x_tr0,y_tr0),(x_te0,y_te0)=tf2.keras.datasets.mnist.load_data()#手写数据库
y_tr=np.zeros((len(y_tr0),10))
y_te=np.zeros((len(y_te0),10))
for i in range(len(y_tr0)):
y_tr[i][y_tr0[i]]=1
for i in range(len(y_te0)):
y_te[i][y_te0[i]]=1
x_tr=x_tr0.reshape(-1,28,28,1)
x_te=x_te0.reshape(-1,28,28,1)
training_epochs=100#训练步数
batch_count=20#小批量训练子集数量
L=32#卷积层1所提取特征个数
M=64#卷积层2所提取特征个数
N=128#卷积层3所提取特征个数
O=625#全连接就层神经元数
# with tf.device('/cpu:0'):
with tf.device('/gpu:0'):
Xin=tf.placeholder(tf.float32,[None,28,28,1],name='Xin')#28×28维输入特征
Yout=tf.placeholder(tf.float32,[None,10],name="Yout")#10类分类结果标签
W1=tf.Variable(tf.random_normal([3,3,1,L],stddev=0.01))#卷积层1的卷积核权值张量,卷积核大小3×3,输入数据为1通道,输出特征为32通道
W2=tf.Variable(tf.random_normal([3,3,L,M],stddev=0.01))#卷积层2的卷积核权值张量,卷积核大小3×3,输入数据为32通道,输出特征为64通道
W3=tf.Variable(tf.random_normal([3,3,M,N],stddev=0.01))#卷积层3的卷积核权值张量,卷积核大小3×3,输入数据为64通道,输出特征为128通道
W4=tf.Variable(tf.random_normal([N*4*4,O],stddev=0.01))#全连接层权值张量,输入数据为128×4×4个,输出为625个,这里需要把上一层的高维张量扁平化
W5=tf.Variable(tf.random_normal([O,10],stddev=0.01))#输出层权值张量,输入数据为625,输出为10类
b1=tf.Variable(tf.random_normal([L],stddev=0.01))#卷积层1的输出特征阈值,输出特征为32通道,每个通道共享一个阈值
b2=tf.Variable(tf.random_normal([M],stddev=0.01))#卷积层2的输出特征阈值,输出特征为64通道,每个通道共享一个阈值
b3=tf.Variable(tf.random_normal([N],stddev=0.01))#卷积层3的输出特征阈值,输出特征为128通道,每个通道共享一个阈值
b4=tf.Variable(tf.random_normal([O],stddev=0.01))#全连接层阈值
b5=tf.Variable(tf.random_normal([10],stddev=0.01))#输出层阈值
'''卷积层一'''
conv1a=tf.nn.conv2d(Xin,W1,strides=[1,1,1,1],padding='SAME')
conv1b=tf.nn.bias_add(conv1a,b1)
conv1c=tf.nn.relu(conv1b)
'''池化层一'''
conv1=tf.nn.max_pool(conv1c,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
'''卷积层二'''
conv2a=tf.nn.conv2d(conv1,W2,strides=[1,1,1,1],padding='SAME')
conv2b=tf.nn.bias_add(conv2a,b2)
conv2c=tf.nn.relu(conv2b)
'''池化层二'''
conv2=tf.nn.max_pool(conv2c,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
'''卷积层三'''
conv3a=tf.nn.conv2d(conv2,W3,strides=[1,1,1,1],padding='SAME')
conv3b=tf.nn.bias_add(conv3a,b3)
conv3c=tf.nn.relu(conv3b)
'''池化层三'''
conv3d=tf.nn.max_pool(conv3c,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
conv3=tf.reshape(conv3d,[-1,W4.get_shape().as_list()[0]])#扁平化
'''全连接层'''
FCa=tf.matmul(conv3,W4)+b4
FC=tf.nn.relu(FCa)
'''输出层'''
Y_=tf.matmul(FC,W5)+b5
Y=tf.nn.softmax(Y_,name="output")#经历softmax分类激活函数后的数值
'''损失'''
cross_entropy=tf.nn.softmax_cross_entropy_with_logits(logits=Y_, labels=Yout)
loss=tf.reduce_mean(cross_entropy)*100#交叉损失
correct_prediction=tf.equal(tf.argmax(Y,1),tf.argmax(Yout,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32),name='accuracy')#正确率
'''优化器'''
trainer=tf.train.RMSPropOptimizer(learning_rate=0.001,momentum=0.9).minimize(loss)
init=tf.global_variables_initializer()#变量初始化赋值器
with tf.Session() as sess:
sess.run(init)#变量初始化
out_init=sess.run(accuracy,feed_dict={Xin:x_tr[0:20000],Yout:y_tr[0:20000]})#计算初始误差
print("初始准确率为:{:.4f}%".format(out_init*100))#输出初始误差
for epoch in range(training_epochs):#训练步数
print("当前训练步为第{}步".format(epoch+1))
batch_size=int(len(y_tr)/batch_count)#当前子集大小
for i in range(batch_count):#对每个子集遍历训练
batch_x,batch_y=nextBatch([x_tr[0:20000],y_tr[0:20000]],batch_size,i)#当前子集的训练集特征和标签数据
sess.run(trainer,feed_dict={Xin:batch_x,Yout:batch_y})
out=sess.run(accuracy,feed_dict={Xin:x_tr[0:20000],Yout:y_tr[0:20000]})#计算当前误差
print("当前准确率为:{:.4f}%".format(out*100))#当前初始误差
'''当前会话存储'''
if out>out_init:
out_init=out
saver=tf.train.Saver()
saver.save(sess,r".\savefile\CNN\FigureCNN.ckpt")
下面做详细分析。
首先要导入手写数据库,tensorflow2.0自带手写字体数据库,用下面语句导入:
(x_tr0,y_tr0),(x_te0,y_te0)=tf2.keras.datasets.mnist.load_data()
x_tr0,y_tr0是60000个训练集的图片和标签。图片是28×28像素,标签是该图像所对应的数字。
x_te0,y_te0是10000个测练集的图片和标签。图片是28×28像素,标签是该图像所对应的数字。
在神经网络中,我们输出是10类,利用softmax函数做输出,因此标签的形式应为10位的,数字0应为“1000000000”,数字1为“0100000000”,数字2为“0010000000”,…,数字9为“0000000001”。
下面改变输出标签的格式:
y_tr=np.zeros((len(y_tr0),10))
y_te=np.zeros((len(y_te0),10))
for i in range(len(y_tr0)):
y_tr[i][y_tr0[i]]=1
for i in range(len(y_te0)):
y_te[i][y_te0[i]]=1
此外,数据输入格式也要做改变,输入数据是28×28像素黑白图片,读入信息是2阶矩阵,在网络中改为3阶矩阵,这里进行形式变换:
x_tr=x_tr0.reshape(-1,28,28,1)
x_te=x_te0.reshape(-1,28,28,1)
接下来输入网络计算的相关参数:
training_epochs=100#训练步数
batch_count=20#小批量训练子集数量
L=32#卷积层1所提取特征个数
M=64#卷积层2所提取特征个数
N=128#卷积层3所提取特征个数
O=625#全连接就层神经元数
接下来,神经网络可以使用cpu计算,也可以使用gpu计算,cpu计算格式为:
with tf.device('/cpu:0'):
gpu计算格式为:
with tf.device('/gpu:0'):
如果不写这两句话,按照安装的tensorflow版本默认计算。我安装的tensorflow是gpu版本,默认进行gpu计算。
下面,定义网络的权值阈值:
W1=tf.Variable(tf.random_normal([3,3,1,L],stddev=0.01))#卷积层1的卷积核权值张量,卷积核大小3×3,输入数据为1通道,输出特征为32通道
W2=tf.Variable(tf.random_normal([3,3,L,M],stddev=0.01))#卷积层2的卷积核权值张量,卷积核大小3×3,输入数据为32通道,输出特征为64通道
W3=tf.Variable(tf.random_normal([3,3,M,N],stddev=0.01))#卷积层3的卷积核权值张量,卷积核大小3×3,输入数据为64通道,输出特征为128通道
W4=tf.Variable(tf.random_normal([N*4*4,O],stddev=0.01))#全连接层权值张量,输入数据为128×4×4个,输出为625个,这里需要把上一层的高维张量扁平化
W5=tf.Variable(tf.random_normal([O,10],stddev=0.01))#输出层权值张量,输入数据为625,输出为10类
b1=tf.Variable(tf.random_normal([L],stddev=0.01))#卷积层1的输出特征阈值,输出特征为32通道,每个通道共享一个阈值
b2=tf.Variable(tf.random_normal([M],stddev=0.01))#卷积层2的输出特征阈值,输出特征为64通道,每个通道共享一个阈值
b3=tf.Variable(tf.random_normal([N],stddev=0.01))#卷积层3的输出特征阈值,输出特征为128通道,每个通道共享一个阈值
b4=tf.Variable(tf.random_normal([O],stddev=0.01))#全连接层阈值
b5=tf.Variable(tf.random_normal([10],stddev=0.01))#输出层阈值
下面构建CNN网络:
Xin=tf.placeholder(tf.float32,[None,28,28,1],name='Xin')#28×28维输入特征
Yout=tf.placeholder(tf.float32,[None,10],name="Yout")#10类分类结果标签
'''卷积层一'''
conv1a=tf.nn.conv2d(Xin,W1,strides=[1,1,1,1],padding='SAME')
conv1b=tf.nn.bias_add(conv1a,b1)
conv1c=tf.nn.relu(conv1b)
'''池化层一'''
conv1=tf.nn.max_pool(conv1c,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
'''卷积层二'''
conv2a=tf.nn.conv2d(conv1,W2,strides=[1,1,1,1],padding='SAME')
conv2b=tf.nn.bias_add(conv2a,b2)
conv2c=tf.nn.relu(conv2b)
'''池化层二'''
conv2=tf.nn.max_pool(conv2c,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
'''卷积层三'''
conv3a=tf.nn.conv2d(conv2,W3,strides=[1,1,1,1],padding='SAME')
conv3b=tf.nn.bias_add(conv3a,b3)
conv3c=tf.nn.relu(conv3b)
'''池化层三'''
conv3d=tf.nn.max_pool(conv3c,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
conv3=tf.reshape(conv3d,[-1,W4.get_shape().as_list()[0]])#扁平化
'''全连接层'''
FCa=tf.matmul(conv3,W4)+b4
FC=tf.nn.relu(FCa)
'''输出层'''
Y_=tf.matmul(FC,W5)+b5
Y=tf.nn.softmax(Y_,name="output")#经历softmax分类激活函数后的数值
tf.placeholder()占位符是用于接收外界输入
tf.nn.conv2d()进行卷积操作
tf.nn.bias_add()偏置的加法操作
tf.nn.relu()Relu函数,用作卷积层激活函数
tf.nn.max_pool()最大池化函数,池化是用于减少特征量,避免数据爆炸,但是也减少其中的信息量
tf.reshape()用于改变数据形态,全连接层之前要将数据扁平化,变为一维,便于输出计算
Y_=tf.matmul(FC,W5)+b5 这是全连接层的计算,权值相乘,阈值相加
tf.nn.softmax()是softmax函数,计算输出的概率
下面定义损失函数以及正确率计算函数:
cross_entropy=tf.nn.softmax_cross_entropy_with_logits(logits=Y_, labels=Yout)
loss=tf.reduce_mean(cross_entropy)*100#交叉损失
correct_prediction=tf.equal(tf.argmax(Y,1),tf.argmax(Yout,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32),name='accuracy')#正确率
下面定义优化器:
trainer=tf.train.RMSPropOptimizer(learning_rate=0.001,momentum=0.9).minimize(loss)
这里是RMS优化算法,参数包括学习率和动量
下面进行数据训练计算:
with tf.Session() as sess:
sess.run(init)#变量初始化
out_init=sess.run(accuracy,feed_dict={Xin:x_tr[0:20000],Yout:y_tr[0:20000]})#计算初始准确率
print("初始准确率为:{:.4f}%".format(out_init*100))#输出初始准确率
for epoch in range(training_epochs):#训练步数
print("当前训练步为第{}步".format(epoch+1))
batch_size=int(len(y_tr)/batch_count)#当前子集大小
for i in range(batch_count):#对每个子集遍历训练
batch_x,batch_y=nextBatch([x_tr[0:20000],y_tr[0:20000]],batch_size,i)#当前子集的训练集特征和标签数据
sess.run(trainer,feed_dict={Xin:batch_x,Yout:batch_y})
out=sess.run(accuracy,feed_dict={Xin:x_tr[0:20000],Yout:y_tr[0:20000]})#计算当前误差
print("当前准确率为:{:.4f}%".format(out*100))#当前初始误差
x_tr[0:20000]和y_tr[0:20000]的说明:我的gpu是gtx1050Ti,显存是4G,两万张图片数据的输入是网络中数据的显存极限,再多的数据量就溢出了,不能完成训练。因此,我选择前两万张训练集数据作为输入,这个根据每个人的电脑不一样而不同。
with tf.Session() as sess:是构建会话且自动关闭
为了防止模型丢失,需要将模型存储下来。我们存储准确率最好的会话:
if out>out_init:
out_init=out
saver=tf.train.Saver()
saver.save(sess,r".\savefile\CNN\FigureCNN.ckpt")
def main_test():
(x_tr0,y_tr0),(x_te0,y_te0)=tf2.keras.datasets.mnist.load_data()#手写数据库
y_tr=np.zeros((len(y_tr0),10))
y_te=np.zeros((len(y_te0),10))
for i in range(len(y_tr0)):
y_tr[i][y_tr0[i]]=1
for i in range(len(y_te0)):
y_te[i][y_te0[i]]=1
x_tr=x_tr0.reshape(-1,28,28,1)
x_te=x_te0.reshape(-1,28,28,1)
road=[r".\savefile\CNN\FigureCNN.ckpt.meta",r".\savefile\CNN\FigureCNN.ckpt"]
sess=tf.InteractiveSession()
new_saver=tf.train.import_meta_graph(road[0])
new_saver.restore(sess,road[1])
tf.get_default_graph().as_graph_def()
Xin=sess.graph.get_tensor_by_name('Xin:0')
Yout=sess.graph.get_tensor_by_name("Yout:0")
accuracy=sess.graph.get_tensor_by_name('accuracy:0')
Y=sess.graph.get_tensor_by_name('output:0')
Ote=sess.run(accuracy,feed_dict={Xin:x_te,Yout:y_te})
print("测试集准确率为:{:.4f}%".format(Ote*100))
Ote=sess.run(accuracy,feed_dict={Xin:x_tr[30000:40000],Yout:y_tr[30000:40000]})
print("训练集集准确率为:{:.4f}%".format(Ote*100))
u=eval(input("输入0-9999之间的一个整数:"))
if (u<0) or (u>9999):
print('错误!')
sess.close()
return
Otem=sess.run(Y,feed_dict={Xin:[x_te[u]]})
print('手写的数字为:{}'.format(Otem.argmax()))
plt.imshow(x_te[u].reshape(28,28))
plt.show()#手写数字展示
for i in [0,2,4,5,9]:
roadpic=r'.\picturefile\handwriting'+str(i)+'.jpg'
pic=cv2.imread(roadpic,flags=0)
pic1=255-pic
pic=pic1.reshape(-1,28,28,1)
Otem=sess.run(Y,feed_dict={Xin:pic})
print('手写的数字为:{}'.format(Otem.argmax()))
plt.imshow(pic1)
plt.show()#手写数字展示
sess.close()
return
下面进行详细分析,先导入数据和测试集输出数据变换形态:
(x_tr0,y_tr0),(x_te0,y_te0)=tf2.keras.datasets.mnist.load_data()#手写数据库
y_tr=np.zeros((len(y_tr0),10))
y_te=np.zeros((len(y_te0),10))
for i in range(len(y_tr0)):
y_tr[i][y_tr0[i]]=1
for i in range(len(y_te0)):
y_te[i][y_te0[i]]=1
x_tr=x_tr0.reshape(-1,28,28,1)
x_te=x_te0.reshape(-1,28,28,1)
读取已存储的模型:
road=[r".\savefile\CNN\FigureCNN.ckpt.meta",r".\savefile\CNN\FigureCNN.ckpt"]
sess=tf.InteractiveSession()
new_saver=tf.train.import_meta_graph(road[0])
new_saver.restore(sess,road[1])
tf.get_default_graph().as_graph_def()
Xin=sess.graph.get_tensor_by_name('Xin:0')
Yout=sess.graph.get_tensor_by_name("Yout:0")
accuracy=sess.graph.get_tensor_by_name('accuracy:0')
Y=sess.graph.get_tensor_by_name('output:0')
计算测试集和训练集其他数据的准确率:
Ote=sess.run(accuracy,feed_dict={Xin:x_te,Yout:y_te})
print("测试集准确率为:{:.4f}%".format(Ote*100))
Ote=sess.run(accuracy,feed_dict={Xin:x_tr[30000:40000],Yout:y_tr[30000:40000]})
print("训练集集准确率为:{:.4f}%".format(Ote*100))
随机选择测试集的一个数据,输出模型预测结果并查看这个数据,看看结果:
u=eval(input("输入0-9999之间的一个整数:"))
if (u<0) or (u>9999):
print('错误!')
sess.close()
return
Otem=sess.run(Y,feed_dict={Xin:[x_te[u]]})
print('手写的数字为:{}'.format(Otem.argmax()))
plt.imshow(x_te[u].reshape(28,28))
plt.show()#手写数字展示
将自己写的28×28的图片预测结果:
for i in [0,2,4,5,9]:
roadpic=r'.\picturefile\handwriting'+str(i)+'.jpg'
pic=cv2.imread(roadpic,flags=0)
pic1=255-pic
pic=pic1.reshape(-1,28,28,1)
Otem=sess.run(Y,feed_dict={Xin:pic})
print('手写的数字为:{}'.format(Otem.argmax()))
plt.imshow(pic1)
plt.show()#手写数字展示
roadpic是图片的位置,共5张自己制作的图片:
'''
Created on 2021年11月2日
@author: 紫薇星君
'''
import os
import cv2
import numpy as np
import tensorflow as tf2
import matplotlib.pyplot as plt
import tensorflow.compat.v1 as tf
def nextBatch(data,batch_size,n):#小批量梯度下降法获取当前数据集函数
#data为全部数据[X,Y],batch_size为当前子数据集大小,n为第n个子数据集
a=n*batch_size
b=(n+1)*batch_size
limdata=len(data[0])
if b>limdata:
b=limdata
a=b-batch_size
data_x=data[0][a:b]
data_y=data[1][a:b]
return data_x,data_y
def main_train():
(x_tr0,y_tr0),(x_te0,y_te0)=tf2.keras.datasets.mnist.load_data()#手写数据库
y_tr=np.zeros((len(y_tr0),10))
y_te=np.zeros((len(y_te0),10))
for i in range(len(y_tr0)):
y_tr[i][y_tr0[i]]=1
for i in range(len(y_te0)):
y_te[i][y_te0[i]]=1
x_tr=x_tr0.reshape(-1,28,28,1)
x_te=x_te0.reshape(-1,28,28,1)
training_epochs=100#训练步数
batch_count=20#小批量训练子集数量
L=32#卷积层1所提取特征个数
M=64#卷积层2所提取特征个数
N=128#卷积层3所提取特征个数
O=625#全连接就层神经元数
# with tf.device('/cpu:0'):
with tf.device('/gpu:0'):
Xin=tf.placeholder(tf.float32,[None,28,28,1],name='Xin')#28×28维输入特征
Yout=tf.placeholder(tf.float32,[None,10],name="Yout")#10类分类结果标签
W1=tf.Variable(tf.random_normal([3,3,1,L],stddev=0.01))#卷积层1的卷积核权值张量,卷积核大小3×3,输入数据为1通道,输出特征为32通道
W2=tf.Variable(tf.random_normal([3,3,L,M],stddev=0.01))#卷积层2的卷积核权值张量,卷积核大小3×3,输入数据为32通道,输出特征为64通道
W3=tf.Variable(tf.random_normal([3,3,M,N],stddev=0.01))#卷积层3的卷积核权值张量,卷积核大小3×3,输入数据为64通道,输出特征为128通道
W4=tf.Variable(tf.random_normal([N*4*4,O],stddev=0.01))#全连接层权值张量,输入数据为128×4×4个,输出为625个,这里需要把上一层的高维张量扁平化
W5=tf.Variable(tf.random_normal([O,10],stddev=0.01))#输出层权值张量,输入数据为625,输出为10类
b1=tf.Variable(tf.random_normal([L],stddev=0.01))#卷积层1的输出特征阈值,输出特征为32通道,每个通道共享一个阈值
b2=tf.Variable(tf.random_normal([M],stddev=0.01))#卷积层2的输出特征阈值,输出特征为64通道,每个通道共享一个阈值
b3=tf.Variable(tf.random_normal([N],stddev=0.01))#卷积层3的输出特征阈值,输出特征为128通道,每个通道共享一个阈值
b4=tf.Variable(tf.random_normal([O],stddev=0.01))#全连接层阈值
b5=tf.Variable(tf.random_normal([10],stddev=0.01))#输出层阈值
'''卷积层一'''
conv1a=tf.nn.conv2d(Xin,W1,strides=[1,1,1,1],padding='SAME')
conv1b=tf.nn.bias_add(conv1a,b1)
conv1c=tf.nn.relu(conv1b)
'''池化层一'''
conv1=tf.nn.max_pool(conv1c,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
'''卷积层二'''
conv2a=tf.nn.conv2d(conv1,W2,strides=[1,1,1,1],padding='SAME')
conv2b=tf.nn.bias_add(conv2a,b2)
conv2c=tf.nn.relu(conv2b)
'''池化层二'''
conv2=tf.nn.max_pool(conv2c,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
'''卷积层三'''
conv3a=tf.nn.conv2d(conv2,W3,strides=[1,1,1,1],padding='SAME')
conv3b=tf.nn.bias_add(conv3a,b3)
conv3c=tf.nn.relu(conv3b)
'''池化层三'''
conv3d=tf.nn.max_pool(conv3c,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
conv3=tf.reshape(conv3d,[-1,W4.get_shape().as_list()[0]])#扁平化
'''全连接层'''
FCa=tf.matmul(conv3,W4)+b4
FC=tf.nn.relu(FCa)
'''输出层'''
Y_=tf.matmul(FC,W5)+b5
Y=tf.nn.softmax(Y_,name="output")#经历softmax分类激活函数后的数值
'''损失'''
cross_entropy=tf.nn.softmax_cross_entropy_with_logits(logits=Y_, labels=Yout)
loss=tf.reduce_mean(cross_entropy)*100#交叉损失
correct_prediction=tf.equal(tf.argmax(Y,1),tf.argmax(Yout,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32),name='accuracy')#正确率
'''优化器'''
trainer=tf.train.RMSPropOptimizer(learning_rate=0.001,momentum=0.9).minimize(loss)
init=tf.global_variables_initializer()#变量初始化赋值器
with tf.Session() as sess:
sess.run(init)#变量初始化
out_init=sess.run(accuracy,feed_dict={Xin:x_tr[0:20000],Yout:y_tr[0:20000]})#计算初始误差
print("初始准确率为:{:.4f}%".format(out_init*100))#输出初始误差
for epoch in range(training_epochs):#训练步数
print("当前训练步为第{}步".format(epoch+1))
batch_size=int(len(y_tr)/batch_count)#当前子集大小
for i in range(batch_count):#对每个子集遍历训练
batch_x,batch_y=nextBatch([x_tr[0:20000],y_tr[0:20000]],batch_size,i)#当前子集的训练集特征和标签数据
sess.run(trainer,feed_dict={Xin:batch_x,Yout:batch_y})
out=sess.run(accuracy,feed_dict={Xin:x_tr[0:20000],Yout:y_tr[0:20000]})#计算当前误差
print("当前准确率为:{:.4f}%".format(out*100))#当前初始误差
'''当前会话存储'''
if out>out_init:
out_init=out
saver=tf.train.Saver()
saver.save(sess,r".\savefile\CNN\FigureCNN.ckpt")
return
def main_test():
(x_tr0,y_tr0),(x_te0,y_te0)=tf2.keras.datasets.mnist.load_data()#手写数据库
y_tr=np.zeros((len(y_tr0),10))
y_te=np.zeros((len(y_te0),10))
for i in range(len(y_tr0)):
y_tr[i][y_tr0[i]]=1
for i in range(len(y_te0)):
y_te[i][y_te0[i]]=1
x_tr=x_tr0.reshape(-1,28,28,1)
x_te=x_te0.reshape(-1,28,28,1)
road=[r".\savefile\CNN\FigureCNN.ckpt.meta",r".\savefile\CNN\FigureCNN.ckpt"]
sess=tf.InteractiveSession()
new_saver=tf.train.import_meta_graph(road[0])
new_saver.restore(sess,road[1])
tf.get_default_graph().as_graph_def()
Xin=sess.graph.get_tensor_by_name('Xin:0')
Yout=sess.graph.get_tensor_by_name("Yout:0")
accuracy=sess.graph.get_tensor_by_name('accuracy:0')
Y=sess.graph.get_tensor_by_name('output:0')
Ote=sess.run(accuracy,feed_dict={Xin:x_te,Yout:y_te})
print("测试集准确率为:{:.4f}%".format(Ote*100))
Ote=sess.run(accuracy,feed_dict={Xin:x_tr[30000:40000],Yout:y_tr[30000:40000]})
print("训练集集准确率为:{:.4f}%".format(Ote*100))
u=eval(input("输入0-9999之间的一个整数:"))
if (u<0) or (u>9999):
print('错误!')
sess.close()
return
Otem=sess.run(Y,feed_dict={Xin:[x_te[u]]})
print('手写的数字为:{}'.format(Otem.argmax()))
plt.imshow(x_te[u].reshape(28,28))
plt.show()#手写数字展示
for i in [0,2,4,5,9]:
roadpic=r'.\picturefile\handwriting'+str(i)+'.jpg'
pic=cv2.imread(roadpic,flags=0)
pic1=255-pic
pic=pic1.reshape(-1,28,28,1)
Otem=sess.run(Y,feed_dict={Xin:pic})
print('高攀手写的数字为:{}'.format(Otem.argmax()))
plt.imshow(pic1)
plt.show()#手写数字展示
sess.close()
return
if __name__=="__main__":
tf.disable_v2_behavior()
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
main_train()
main_test()