python 神經網路學習
最新在朋友的推薦下看了《python神經網路程式設計》,深有啟發,本文以深入淺出的道理,簡單明瞭的介紹了一種神經網路的原理及python實現過程及全部程式碼,通過學習,至少基本掌握了相關知識,為後面學習打下基礎,有幾點心得分享如下:
在《python神經網路程式設計》一書中,裡面核心的演算法思維方式就是線性代數和微積分,尤其是線性代數矩陣的乘法,是神經網路計算的核心內容,幸好大學時這塊基礎很好,所裡整本書看起來不費力氣。
2、嘗試一步一步實現所有功能
在《python神經網路程式設計》一書中,作者手把手教你如何用python實現神經網路的過程,並用圖片識別來叫我們進行訓練和應用,從而較好的掌握其中的應用場景。建議讀者應該逐步實現相關功能,並瞭解去原理,適當進行程式碼的優化和展示。由於不同的應用環境、程式設計環境,實際上展示回有一些區別,需要自己反覆琢磨和百度查詢。沒有沒有python經驗,直接入手有可能比較麻煩,建議可以找一本python書籍看看,我看的是劉瑜老師的《Python程式設計從零基礎到專案實戰》,該書深入淺出的介紹了python基礎語法,並就實際各種應用場景進行了基礎的普及和嘗試,是初學者的福音。
3、優化並提出自己的想法
在數字識別過程中,《python神經網路程式設計》一書只提供了單一的程式碼執行方法,這樣沒有辦法系統的進行資料測試和資料分析,我就嘗試用多重迴圈的方式進行改進,從而達到任意隱藏節點層數、任意世代次數,任意學習效率的組合測試和輸出,並加入每一次的執行時間,輸出每一次的執行結果,從而試圖尋找其中的規律,找到最優值。並對每次執行結果進行記錄,以便以後學習和分析。
4、分享自己的程式碼
以下是完整的實現程式碼,歡迎大家留言,討論,共同學習,共同進步,後續繼續分享自己的心得。現在最大的問題就是筆記本計算機計算不過來了,需要更大、更好的執行環境,也希望如果有人測試完成了能夠分享出來。
import numpy # scipy.special for the sigmoid function expit import scipy.special # neural network class definition import matplotlib.pyplot import time import datetime # 2018年12月16日對《python神經網路程式設計》一書程式碼進行優化,並進行測試,lucoaixi class neuralNetwork: #initialise the neural network def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate): #set number if nodes in each input,hidden,output layer self.inodes = inputnodes self.hnodes = hiddennodes self.onodes = outputnodes # link weight matrices,wih and who # weight insides the arrays are w_i_j,where link is fron node i to node j in the next layer # w11 w21 #w12 w22 etc self.wih = numpy.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.inodes)) self.who = numpy.random.normal(0.0,pow(self.onodes,-0.5),(self.onodes,self.hnodes)) # learning rate self.lr = learningrate #activation funtion is the sigmoid function self.activation_function =lambda x:scipy.special.expit(x) pass #train the neural network def train(self,inputs_list,targets_list): # convet inputs list to 2d array inputs = numpy.array(inputs_list,ndmin=2).T targets = numpy.array(targets_list,ndmin=2).T #calculate signals into hidden layer hidden_inputs = numpy.dot(self.wih,inputs) #calculate the signals emerging from hidden layer hidden_outputs =self.activation_function(hidden_inputs) #calculate signals into final output layer final_inputs = numpy.dot(self.who,hidden_outputs) #calculate the signals emerging from final output layer final_outputs =self.activation_function(final_inputs) # putput layer error is the (target-actual) output_errors = targets - final_outputs #output layer error is the output_errors,split by weights,recombined at hidden nodes hidden_errors = numpy.dot(self.who.T,output_errors) #update the weights for the links between the hidden and output layers self.who +=self.lr * numpy.dot((output_errors*final_outputs*(1.0-final_outputs)),numpy.transpose(hidden_outputs)) #update the weights for the links between the input and hidden layers self.wih +=self.lr * numpy.dot((hidden_errors*hidden_outputs*(1.0-hidden_outputs)),numpy.transpose(inputs)) pass #query the neural network def query(self,inputs_list): #convet inputs list to 2d array inputs = numpy.array(inputs_list,ndmin=2).T #calculate signals into hidden layer hidden_inputs = numpy.dot(self.wih,inputs) #calculate the signals emerging from hidden layer hidden_outputs =self.activation_function(hidden_inputs) #calculate signals into final output layer final_inputs = numpy.dot(self.who,hidden_outputs) #calculate the signals emerging from final output layer final_outputs =self.activation_function(final_inputs) return final_outputs #begin process 程序開始 #初始化訓練資料和測試資料 #load the mnist training data CSV file into a list training_data_file =open("C:/test/mnist_train.csv",'r') training_data_list = training_data_file.readlines() training_data_file.close() #load the mnist test data CSV file into a list #test_data_file = open("C:/test/mnist_train_100.csv",'r') test_data_file =open("C:/test/mnist_test.csv",'r') test_data_list = test_data_file.readlines() test_data_file.close() #初始化 輸入點數、隱藏層節點數、輸出節點數 #number of input,hidden and output nodes input_nodes =784 hidden_nodes1= ['10','20','40','80','100','200','300','400','500','600','700','800','900','1000'] #hidden_nodes2= ['10','20','40','80','100','120','150','200'] hidden_nodes2= ['200','300','400','500','600','700','800','900','1000' ]#測試200-1000個隱藏節點 hidden_nodes =100 output_nodes =10 # 初始化學習率 is 0.3 #learning_rate = ['0.1','0.2','0.3','0.4', '0.5', '0.6','0.7','0.8','0.9'] learning_rate = ['0.1','0.2','0.3']#測試學習率0.1、0.2、0.3 #dataSet = dataSet.astype('float64') #初始化世代次數 epochs =10 #程式開始 start = time.time() print('begin:',time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) print('世代次數cs,','學習率lr,','隱藏層節點數hn,','執行時長tm,',"執行結果out") for iin range(len(hidden_nodes2)): for ein range(epochs): for lrin range(len(learning_rate)): start = time.time() n = neuralNetwork(input_nodes,int(hidden_nodes2[i]), output_nodes,float(learning_rate[lr])) # go through all records in the training data set for recordin training_data_list: # split the record by the ',' connas all_values = record.split(',') # scale and shift the inputs inputs = (numpy.asfarray(all_values[1:]) /255.0 *0.99) +0.01 # create the target output values(all 0.01,except the desired label which is 0.99) targets = numpy.zeros(output_nodes) +0.01 # all_values[0] is the target lable for this record targets[int(all_values[0])] =0.99 n.train(inputs, targets) pass pass # 測試這個神經網路 # 計分卡記錄網路執行情況,初始值為空 scorecard = [] # 在測試資料集中計算所有的記錄值 for recordin test_data_list: all_values = record.split(',') correct_lable =int(all_values[0]) # print(correct_lable,'correct_lable') inputs = (numpy.asfarray(all_values[1:]) /255.0 *0.99) +0.01 outputs = n.query(inputs) lable = numpy.argmax(outputs) # print(lable,"networks's answer") if (lable == correct_lable): scorecard.append(1) else: scorecard.append(0) pass pass end = time.time() seconds = end - start # print(scorecard) scorecard_array = numpy.asarray(scorecard) print('cs=',e+1,',lr=',learning_rate[lr],',hn=',hidden_nodes2[i],',tm=',int(seconds),",out=", scorecard_array.sum() / scorecard_array.size) pass #結束 end = time.time() seconds = end - start print(seconds) print('end:',time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
以下是未執行完的資料:
begin: 2018-12-16 13:36:10
世代次數cs, 學習率lr, 隱藏層節點數hn, 執行時長tm, 執行結果out
cs= 1 ,lr= 0.1 ,hn= 200 ,tm= 154 ,out= 0.9593
cs= 1 ,lr= 0.2 ,hn= 200 ,tm= 152 ,out= 0.9568
cs= 1 ,lr= 0.3 ,hn= 200 ,tm= 148 ,out= 0.9519
cs= 2 ,lr= 0.1 ,hn= 200 ,tm= 147 ,out= 0.9582
cs= 2 ,lr= 0.2 ,hn= 200 ,tm= 145 ,out= 0.9581
cs= 2 ,lr= 0.3 ,hn= 200 ,tm= 144 ,out= 0.9541
cs= 3 ,lr= 0.1 ,hn= 200 ,tm= 144 ,out= 0.9583
cs= 3 ,lr= 0.2 ,hn= 200 ,tm= 144 ,out= 0.9573
cs= 3 ,lr= 0.3 ,hn= 200 ,tm= 144 ,out= 0.9507
cs= 4 ,lr= 0.1 ,hn= 200 ,tm= 145 ,out= 0.9595
cs= 4 ,lr= 0.2 ,hn= 200 ,tm= 145 ,out= 0.9554
cs= 4 ,lr= 0.3 ,hn= 200 ,tm= 144 ,out= 0.9513
cs= 5 ,lr= 0.1 ,hn= 200 ,tm= 144 ,out= 0.9599
cs= 5 ,lr= 0.2 ,hn= 200 ,tm= 144 ,out= 0.9562
cs= 5 ,lr= 0.3 ,hn= 200 ,tm= 146 ,out= 0.9421
cs= 6 ,lr= 0.1 ,hn= 200 ,tm= 147 ,out= 0.9556
cs= 6 ,lr= 0.2 ,hn= 200 ,tm= 147 ,out= 0.9591
cs= 6 ,lr= 0.3 ,hn= 200 ,tm= 147 ,out= 0.9552
cs= 7 ,lr= 0.1 ,hn= 200 ,tm= 192 ,out= 0.959
cs= 7 ,lr= 0.2 ,hn= 200 ,tm= 202 ,out= 0.9577
cs= 7 ,lr= 0.3 ,hn= 200 ,tm= 198 ,out= 0.9506
cs= 8 ,lr= 0.1 ,hn= 200 ,tm= 192 ,out= 0.9601
cs= 8 ,lr= 0.2 ,hn= 200 ,tm= 195 ,out= 0.9534
cs= 8 ,lr= 0.3 ,hn= 200 ,tm= 192 ,out= 0.9583
cs= 9 ,lr= 0.1 ,hn= 200 ,tm= 1010 ,out= 0.9571
cs= 9 ,lr= 0.2 ,hn= 200 ,tm= 185 ,out= 0.9558
cs= 9 ,lr= 0.3 ,hn= 200 ,tm= 186 ,out= 0.9522
cs= 10 ,lr= 0.1 ,hn= 200 ,tm= 190 ,out= 0.9586
cs= 10 ,lr= 0.2 ,hn= 200 ,tm= 191 ,out= 0.9594
cs= 10 ,lr= 0.3 ,hn= 200 ,tm= 189 ,out= 0.9467
cs= 1 ,lr= 0.1 ,hn= 300 ,tm= 264 ,out= 0.9613
cs= 1 ,lr= 0.2 ,hn= 300 ,tm= 260 ,out= 0.9607
cs= 1 ,lr= 0.3 ,hn= 300 ,tm= 261 ,out= 0.9561
cs= 2 ,lr= 0.1 ,hn= 300 ,tm= 264 ,out= 0.9602
cs= 2 ,lr= 0.2 ,hn= 300 ,tm= 277 ,out= 0.9587
cs= 2 ,lr= 0.3 ,hn= 300 ,tm= 282 ,out= 0.9498
cs= 3 ,lr= 0.1 ,hn= 300 ,tm= 281 ,out= 0.9608
cs= 3 ,lr= 0.2 ,hn= 300 ,tm= 2198 ,out= 0.9569
cs= 3 ,lr= 0.3 ,hn= 300 ,tm= 248 ,out= 0.9446
cs= 4 ,lr= 0.1 ,hn= 300 ,tm= 256 ,out= 0.9601
cs= 4 ,lr= 0.2 ,hn= 300 ,tm= 256 ,out= 0.9599
cs= 4 ,lr= 0.3 ,hn= 300 ,tm= 293 ,out= 0.956
cs= 5 ,lr= 0.1 ,hn= 300 ,tm= 308 ,out= 0.9586
cs= 5 ,lr= 0.2 ,hn= 300 ,tm= 220 ,out= 0.9566
cs= 5 ,lr= 0.3 ,hn= 300 ,tm= 220 ,out= 0.9559
cs= 6 ,lr= 0.1 ,hn= 300 ,tm= 218 ,out= 0.9586
cs= 6 ,lr= 0.2 ,hn= 300 ,tm= 217 ,out= 0.9576
cs= 6 ,lr= 0.3 ,hn= 300 ,tm= 217 ,out= 0.9551
cs= 7 ,lr= 0.1 ,hn= 300 ,tm= 205 ,out= 0.9594
cs= 7 ,lr= 0.2 ,hn= 300 ,tm= 207 ,out= 0.96
cs= 7 ,lr= 0.3 ,hn= 300 ,tm= 232 ,out= 0.9581
cs= 8 ,lr= 0.1 ,hn= 300 ,tm= 223 ,out= 0.958
cs= 8 ,lr= 0.2 ,hn= 300 ,tm= 221 ,out= 0.9528
cs= 8 ,lr= 0.3 ,hn= 300 ,tm= 222 ,out= 0.9537
cs= 9 ,lr= 0.1 ,hn= 300 ,tm= 222 ,out= 0.9589
cs= 9 ,lr= 0.2 ,hn= 300 ,tm= 219 ,out= 0.9574
cs= 9 ,lr= 0.3 ,hn= 300 ,tm= 219 ,out= 0.9563
cs= 10 ,lr= 0.1 ,hn= 300 ,tm= 218 ,out= 0.9598
cs= 10 ,lr= 0.2 ,hn= 300 ,tm= 217 ,out= 0.9558
cs= 10 ,lr= 0.3 ,hn= 300 ,tm= 218 ,out= 0.956
cs= 1 ,lr= 0.1 ,hn= 400 ,tm= 288 ,out= 0.9609
cs= 1 ,lr= 0.2 ,hn= 400 ,tm= 297 ,out= 0.9598
cs= 1 ,lr= 0.3 ,hn= 400 ,tm= 298 ,out= 0.9562
cs= 2 ,lr= 0.1 ,hn= 400 ,tm= 294 ,out= 0.9597
cs= 2 ,lr= 0.2 ,hn= 400 ,tm= 281 ,out= 0.959
cs= 2 ,lr= 0.3 ,hn= 400 ,tm= 312 ,out= 0.9561
cs= 3 ,lr= 0.1 ,hn= 400 ,tm= 300 ,out= 0.9598
cs= 3 ,lr= 0.2 ,hn= 400 ,tm= 304 ,out= 0.9603
cs= 3 ,lr= 0.3 ,hn= 400 ,tm= 292 ,out= 0.9507
cs= 4 ,lr= 0.1 ,hn= 400 ,tm= 290 ,out= 0.9603
cs= 4 ,lr= 0.2 ,hn= 400 ,tm= 307 ,out= 0.9619
cs= 4 ,lr= 0.3 ,hn= 400 ,tm= 302 ,out= 0.9498
cs= 5 ,lr= 0.1 ,hn= 400 ,tm= 292 ,out= 0.9599
cs= 5 ,lr= 0.2 ,hn= 400 ,tm= 297 ,out= 0.9588
cs= 5 ,lr= 0.3 ,hn= 400 ,tm= 285 ,out= 0.9544
cs= 6 ,lr= 0.1 ,hn= 400 ,tm= 296 ,out= 0.9608
cs= 6 ,lr= 0.2 ,hn= 400 ,tm= 277 ,out= 0.9608
cs= 6 ,lr= 0.3 ,hn= 400 ,tm= 281 ,out= 0.9466
cs= 7 ,lr= 0.1 ,hn= 400 ,tm= 272 ,out= 0.9579
cs= 7 ,lr= 0.2 ,hn= 400 ,tm= 325 ,out= 0.9622
cs= 7 ,lr= 0.3 ,hn= 400 ,tm= 288 ,out= 0.9515
cs= 8 ,lr= 0.1 ,hn= 400 ,tm= 289 ,out= 0.96
cs= 8 ,lr= 0.2 ,hn= 400 ,tm= 288 ,out= 0.9607
cs= 8 ,lr= 0.3 ,hn= 400 ,tm= 287 ,out= 0.9556