python+tensorflow CNN卷积神经网络手写字体识别
導入所需的庫模塊:
import os import cv2 import numpy as np import tensorflow as tf2 import matplotlib.pyplot as plt import tensorflow.compat.v1 as tfimport 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_sizeb=(n+1)*batch_sizelimdata=len(data[0])if b>limdata:b=limdataa=b-batch_sizedata_x=data[0][a:b]data_y=data[1][a:b]return data_x,data_y這里是為了將數據集切割成小批量數據,完成訓練,小批量訓練結果更好。
CNN網絡:
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]]=1for i in range(len(y_te0)):y_te[i][y_te0[i]]=1x_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)+b4FC=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=outsaver=tf.train.Saver()saver.save(sess,r".\savefile\CNN\FigureCNN.ckpt")下面做詳細分析。
首先要導入手寫數據庫,tensorflow2.0自帶手寫字體數據庫,用下面語句導入:
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”。
下面改變輸出標簽的格式:
此外,數據輸入格式也要做改變,輸入數據是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)+b4FC=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=outsaver=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]]=1for i in range(len(y_te0)):y_te[i][y_te0[i]]=1x_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()returnOtem=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-picpic=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]]=1for i in range(len(y_te0)):y_te[i][y_te0[i]]=1x_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()returnOtem=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-picpic=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 tfdef nextBatch(data,batch_size,n):#小批量梯度下降法獲取當前數據集函數#data為全部數據[X,Y],batch_size為當前子數據集大小,n為第n個子數據集a=n*batch_sizeb=(n+1)*batch_sizelimdata=len(data[0])if b>limdata:b=limdataa=b-batch_sizedata_x=data[0][a:b]data_y=data[1][a:b]return data_x,data_ydef 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]]=1for i in range(len(y_te0)):y_te[i][y_te0[i]]=1x_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)+b4FC=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=outsaver=tf.train.Saver()saver.save(sess,r".\savefile\CNN\FigureCNN.ckpt")returndef 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]]=1for i in range(len(y_te0)):y_te[i][y_te0[i]]=1x_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()returnOtem=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-picpic=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()returnif __name__=="__main__":tf.disable_v2_behavior()os.environ['TF_CPP_MIN_LOG_LEVEL']='2'main_train()main_test()運行結果:
總結
以上是生活随笔為你收集整理的python+tensorflow CNN卷积神经网络手写字体识别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 「CH2401」送礼物 解题报告
- 下一篇: 关于理想,无问西东