一、單隱藏層神經網絡構建與應用
主要內容:
1.1載入數據
1.2建立模型
1.3訓練模型
1.4評估模型
1.5應用模型
1.1載入數據
1.2建立模型
1.2.1構建輸入層
#定義標簽數據占位符 x= tf.placeholder(tf.float32, [None, 784], name='X') #圖片大小28*28 y= tf.placeholder(tf.float32, [None, 10], name='Y')
1.2.2構建隱藏層
H1_NN=256 #自定義隱藏層神經元數量 W1 = tf.Variable(tf.random_normal([784,H1_NN])) #全連接x1,x2... b1 = tf.Variable(tf.zeros([H1_NN])) #偏置項 Y1 = tf.nn.relu(tf.matmul(x,W1)+b1)
1.2.3構建輸出層
W2 = tf.Variable(tf.random_normal([H1_NN,10])) b2 = tf.Variable(tf.zeros([10])) forward = tf.matmul(Y1, W2) + b2 pred=tf.nn.softmax(forward) #多分類預測結果
1.3訓練模型
1.3.1定義損失函數、設置訓練參數、選擇優化器、定義准確率
loss_function = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1)) #定義交叉熵損失函數 #設置訓練參數 train_epochs = 40 #訓練輪數 batch_size=50 #單次訓練樣本數(批次大小) total_batch= int(mnist.train.num_examples/batch_size)#一輪訓練有多少批次 display_step=1 #顯示粒度 learning_rate=0.01 #學習率 #選擇優化器 optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss_function) #定義准確率 correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(pred,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))#准確率,將布爾值轉化為浮點數,並計算平均值
1.3.2訓練過程

#記錄訓練開始時間 startTime = time() sess = tf.Session() sess.run(tf.global_variables_initializer()) for epoch in range(train_epochs): for batch in range(total_batch): xs, ys = mnist.train.next_batch(batch_size) # 讀取批次數據 sess.run(optimizer,feed_dict={x:xs,y:ys}) # 執行批次訓練 #total_batch個批次訓練完成后,使用驗證數據計算課差與准確率;驗證集沒有分批 loss,acc = sess.run([loss_function,accuracy],feed_dict={x:mnist.validation.images,y:mnist.validation.labels}) #打印訓練過程中的詳細信息 if (epoch+1) % display_step == 0: print("Train Epoch:",'%02d' %(epoch+1),"Loss=","{:.9f}".format(loss),"Accuracy=","{:.4f}".format(acc)) duration = time()-startTime #顯示運行總時間 print("Train Finished takes:","{:.2f}".format(duration))
運行結果為:
分析原因,定義交叉熵損失函數時,有一個log項,log(0)引起的數據不穩定
# loss_function = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1)) #定義交叉熵損失函數 #TensorFlow提供了softmax_cross_entropy_with_logits函數,用於避免因為log(0)值為NaN造成的數據不穩定 loss_function = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=forward,labels=y)) #注意第一個參數是不做Softmax的前向計算結果
修改后,運行結果為:
從上述打印結果可以看出包含256個神經元的單隱層神經網絡的分類性能比僅包含一個網絡更優。
1.4評估模型
#使用測試集評估模型 accu_test = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels}) print("Test Accuracy:",accu_test)
1.5應用模型
1.5.1進行預測
#由於pred預測結果是one-hot編碼格式,所以需要轉換為0-9數字 prediction_result = sess.run(tf.argmax(pred,1),feed_dict={x:mnist.test.images}) print(prediction_result[0:10]) #查看預測結果中的前10項
1.5.2找出預測錯誤
compare_lists = prediction_result==np.argmax(mnist.test.labels,1) print(compare_lists) err_lists=[i for i in range(len(compare_lists)) if compare_lists[i]==False] print(err_lists, len(err_lists)) #最后一項即為多少個預測錯了
...........
可見一共有279個預測錯誤,但這樣返回預測錯誤的下標不夠直觀,接下來進行修改。
修改一:
#定義一個輸出錯誤分類的函數 def print_predict_errs(labels, prediction): #標簽列表,預測值列表 count = 0 compare_lists =(prediction==np.argmax(labels,1)) err_lists = [i for i in range(len(compare_lists)) if compare_lists [i]==False] for x in err_lists: print("index="+str(x) + "標簽值=",np.argmax(labels[x]),"預測值=",prediction[x]) count += 1 print("總計:"+str(count)) print_predict_errs(labels=mnist.test.labels,prediction=prediction_result)
運行結果:
以文本顯示,仍然不夠直觀,進一步修改。
修改二(+可視化):
對https://www.cnblogs.com/HuangYJ/p/11642475.html中6.1節可視化函數修改,以便只顯示預測錯誤的樣本

#可視化 def plot_images_labels_prediction(images,labels,prediction,num=10): #圖像列表,標簽列表,預測值列表,從第index個開始顯示 , 缺省一次顯示10幅 j = 0 fig = plt.gcf() #獲取當前圖表,get current figure fig.set_size_inches(10,12) #1英寸等於2.54cm compare_lists = prediction_result == np.argmax(mnist.test.labels, 1) err_lists = [i for i in range(len(compare_lists)) if compare_lists[i] == False] if num > 25: num = 25 #最多顯示25個子圖 for i in range(0, num): ax = plt.subplot(5,5,i+1) #獲取當前要處理的子圖 ax.imshow(np.reshape(images[err_lists[j]], (28, 28)),cmap='binary') # 顯示第index個圖像 title = "label=" + str(np.argmax(labels[err_lists[j]]))# 構建該圖上要顯示的 if len(prediction)>0: title += ",predict="+ str(prediction[err_lists[j]]) ax.set_title(title, fontsize=10) #顯示圖上title信息 ax.set_xticks([]) #不顯示坐標軸 ax.set_yticks([]) j += 1 plt.show() plot_images_labels_prediction(mnist.test.images,mnist.test.labels,prediction_result,25) #最多顯示25張
顯示前25個預測錯誤的樣本,預測結果為:
全部代碼為:

#Created by:Huang #Time:2019/10/15 0015. import tensorflow as tf import tensorflow.examples.tutorials.mnist.input_data as input_data import matplotlib.pyplot as plt import numpy as np from time import time mnist = input_data.read_data_sets("MNIST_data/",one_hot=True) #定義標簽數據占位符 x= tf.placeholder(tf.float32, [None, 784], name='X') #圖片大小28*28 y= tf.placeholder(tf.float32, [None, 10], name='Y') #隱藏層 H1_NN=256 #自定義隱藏層神經元數量 W1 = tf.Variable(tf.random_normal([784,H1_NN])) #全連接x1,x2... b1 = tf.Variable(tf.zeros([H1_NN])) #偏置項 Y1 = tf.nn.relu(tf.matmul(x,W1)+b1) #輸出層 W2 = tf.Variable(tf.random_normal([H1_NN,10])) b2 = tf.Variable(tf.zeros([10])) forward = tf.matmul(Y1, W2) + b2 pred=tf.nn.softmax(forward) #多分類預測結果 # loss_function = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1)) #定義交叉熵損失函數 #TensorFlow提供了softmax_cross_entropy_with_logits函數,用於避免因為log(0)值為NaN造成的數據不穩定 loss_function = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=forward,labels=y)) #注意第一個參數是不做Softmax的前向計算結果 #設置訓練參數 train_epochs = 40 #訓練輪數 batch_size=50 #單次訓練樣本數(批次大小) total_batch= int(mnist.train.num_examples/batch_size)#一輪訓練有多少批次 display_step=1 #顯示粒度 learning_rate=0.01 #學習率 #選擇優化器 optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss_function) #定義准確率 correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(pred,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))#准確率,將布爾值轉化為浮點數,並計算平均值 #記錄訓練開始時間 startTime = time() sess = tf.Session() sess.run(tf.global_variables_initializer()) for epoch in range(train_epochs): for batch in range(total_batch): xs, ys = mnist.train.next_batch(batch_size) # 讀取批次數據 sess.run(optimizer,feed_dict={x:xs,y:ys}) # 執行批次訓練 #total_batch個批次訓練完成后,使用驗證數據計算課差與准確率;驗證集沒有分批 loss,acc = sess.run([loss_function,accuracy],feed_dict={x:mnist.validation.images,y:mnist.validation.labels}) #打印訓練過程中的詳細信息 if (epoch+1) % display_step == 0: print("Train Epoch:",'%02d' %(epoch+1),"Loss=","{:.9f}".format(loss),"Accuracy=","{:.4f}".format(acc)) duration = time()-startTime #顯示運行總時間 print("Train Finished takes:","{:.2f}".format(duration)) #使用測試集評估模型 accu_test = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels}) print("Test Accuracy:",accu_test) #模型預測 #由於pred預測結果是one-hot編碼格式,所以需要轉換為0-9數字 prediction_result = sess.run(tf.argmax(pred,1),feed_dict={x:mnist.test.images}) print(prediction_result[0:10]) #查看預測結果中的前10項 # #找出預測錯誤 # compare_lists = prediction_result==np.argmax(mnist.test.labels,1) # print(compare_lists) # # err_lists=[i for i in range(len(compare_lists)) if compare_lists[i]==False] # print(err_lists, len(err_lists)) #最后一項即為多少個預測錯了 #定義一個輸出錯誤分類的函數 # def print_predict_errs(labels, prediction): #標簽列表,預測值列表 # count = 0 # compare_lists =(prediction==np.argmax(labels,1)) # err_lists = [i for i in range(len(compare_lists)) if compare_lists [i]==False] # for x in err_lists: # print("index="+str(x) + "標簽值=",np.argmax(labels[x]),"預測值=",prediction[x]) # count += 1 # print("總計:"+str(count)) # print_predict_errs(labels=mnist.test.labels,prediction=prediction_result) #可視化 def plot_images_labels_prediction(images,labels,prediction,num=10): #圖像列表,標簽列表,預測值列表,從第index個開始顯示 , 缺省一次顯示10幅 j = 0 fig = plt.gcf() #獲取當前圖表,get current figure fig.set_size_inches(10,12) #1英寸等於2.54cm compare_lists = prediction_result == np.argmax(mnist.test.labels, 1) err_lists = [i for i in range(len(compare_lists)) if compare_lists[i] == False] if num > 25: num = 25 #最多顯示25個子圖 for i in range(0, num): ax = plt.subplot(5,5,i+1) #獲取當前要處理的子圖 ax.imshow(np.reshape(images[err_lists[j]], (28, 28)),cmap='binary') # 顯示第index個圖像 title = "label=" + str(np.argmax(labels[err_lists[j]]))# 構建該圖上要顯示的 if len(prediction)>0: title += ",predict="+ str(prediction[err_lists[j]]) ax.set_title(title, fontsize=10) #顯示圖上title信息 ax.set_xticks([]) #不顯示坐標軸 ax.set_yticks([]) j += 1 plt.show() plot_images_labels_prediction(mnist.test.images,mnist.test.labels,prediction_result,25) #最多顯示25張