實現數字手寫圖片識別(純程式碼)
阿新 • • 發佈:2018-12-17
假設環境都OK
import scipy.special class NeuralNetWork: def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate): #初始化網路,設定網路值,中間層,和輸出層節點數 self.inodes=inputnodes self.hnodes=hiddennodes self.onodes=outputnodes #設定學習效率 self.lr=learningrate ''' 初始化權重矩陣,我們有兩個權重矩陣,一個是wish表示輸入層和中間層節點間鏈路權重形成的矩陣 ''' self.wih=numpy.random.rand(self.hnodes,self.inodes)-0.5 self.who=numpy.random.rand(self.onodes,self.hnodes)-0.5 #作者寫錯了 self.activation_function=lambda x:scipy.special.expit(x) pass def train(self,inputs_list,targets_list): #根據輸入的訓練資料更新節點鏈路權重 ''' 把inputs_list,targets_list轉化成numpy支援的二維矩陣 ''' print(inputs_list.shape) print(targets_list.shape) inputs=numpy.array(inputs_list,ndmin=2).T targets=numpy.array(targets_list,ndmin=2).T #計算訊號經過輸入層後產生的訊號量 hidden_inputs=numpy.dot(self.wih,inputs) #中間層神經元對輸入的訊號做啟用函式後得到輸出訊號 hidden_outputs=self.activation_function(hidden_inputs) #輸出層接收來自中間層的訊號量 final_inputs=numpy.dot(self.who,hidden_outputs) #輸出層對輸入的訊號做啟用函式後得到輸出訊號 final_outputs=self.activation_function(final_inputs) #計算誤差 output_errors=targets-final_outputs hidden_errors=numpy.dot(self.who.T,output_errors) #根據誤差計算鏈路權重的更新量,然後把更新加到原來鏈路權重上 self.who +=self.lr*numpy.dot((output_errors*final_outputs*(1-final_outputs)),numpy.transpose(hidden_outputs)) self.wih +=self.lr*numpy.dot((hidden_errors*hidden_outputs*(1-hidden_outputs)),numpy.transpose(inputs)) pass def query(self,inputs): #根據輸入資料計算並輸出答案 #計算中間層從輸入層接受到的訊號量 hidden_inputs=numpy.dot(self.wih,inputs) #計算中間層經過啟用函式後形成的輸出訊號量 hidden_outputs=self.activation_function(hidden_inputs) #計算最外層接受到的訊號量 final_inputs=numpy.dot(self.who,hidden_outputs) #計算中間層經過啟用函式後形成的輸出訊號量 final_outputs=self.activation_function(final_inputs) print(final_outputs) return final_outputs pass #初始化網路 input_nodes = 784 hidden_nodes = 100 output_nodes = 10 learning_rate = 0.3 n = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate) #讀入訓練資料 #open函式裡的路徑根據資料儲存的路徑來設定 training_data_file = open("/home/zbl/data/mnist_train.csv") trainning_data_list = training_data_file.readlines() print(len(trainning_data_list )) training_data_file.close() #把資料依靠','區分,並分別讀入 for record in trainning_data_list: all_values = record.split(',') inputs = (numpy.asfarray(all_values[1:]))/255.0 * 0.99 + 0.01 #設定圖片與數值的對應關係 targets = numpy.zeros(output_nodes) + 0.01 targets[int(all_values[0])] = 0.99 n.train(inputs, targets) #open函式里路徑 test_data_file = open("/home/zbl/data/mnist_test.csv") test_data_list = test_data_file.readlines() test_data_file.close() import numpy import matplotlib.pyplot %matplotlib inline #把資料依靠','區分,並分別讀入 all_values = test_data_list[6].split(',') #第一個值對應的是圖片的表示的數字,所以我們讀取圖片資料時要去掉第一個數值 image_array = numpy.asfarray(all_values[1:]).reshape((28, 28)) matplotlib.pyplot.imshow(image_array, cmap='Greys', interpolation='None') label = numpy.argmax(n.query(numpy.asfarray(all_values[1:]) / 255.0 * 0.99 + 0.01 )) #print(n.query(numpy.asfarray(all_values[1:]) / 255.0 * 0.99 + 0.01 ).type) print(label) scores = [] for record in test_data_list: all_values = record.split(',') correct_number = int(all_values[0]) print("該圖片對應的數字為:",correct_number) #預處理數字圖片 inputs = (numpy.asfarray(all_values[1:])) / 255.0 * 0.99 + 0.01 #讓網路判斷圖片對應的數字 outputs = n.query(inputs) #找到數值最大的神經元對應的編號 # print("out put is : ", outputs) label = numpy.argmax(outputs) print("out put reslut is : ", label) #print("網路認為圖片的數字是:", label) if label == correct_number: scores.append(1) else: scores.append(0) print(scores) scores_array = numpy.asarray(scores) print("perfermance = ", scores_array.sum() / scores_array.size)
注:測試集和訓練集需要單獨下載,放在本地。