日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

用python实现数字图片识别神经网络--实现网络训练功能

發(fā)布時間:2023/12/20 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用python实现数字图片识别神经网络--实现网络训练功能 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

上節(jié)我們完成了神經(jīng)網(wǎng)絡(luò)基本框架的搭建,當(dāng)時剩下了最重要的一個接口train,也就是通過讀取數(shù)據(jù)自我學(xué)習(xí),進而改進網(wǎng)絡(luò)識別效率的功能尚未實現(xiàn),從本節(jié)開始,我們著手實現(xiàn)該功能。

自我訓(xùn)練過程分兩步走,第一步是計算輸入訓(xùn)練數(shù)據(jù),給出網(wǎng)絡(luò)的計算結(jié)果,這點跟我們前面實現(xiàn)的query()功能很像。第二步是將計算結(jié)果與正確結(jié)果相比對,獲取誤差,采購采用我們前面描述的誤差反向傳播法更新網(wǎng)絡(luò)里的每條鏈路權(quán)重。

我們先用代碼完成第一步,代碼如下:

def train(self, inputs_list, targets_list):#根據(jù)輸入的訓(xùn)練數(shù)據(jù)更新節(jié)點鏈路權(quán)重'''把inputs_list, targets_list轉(zhuǎn)換成numpy支持的二維矩陣.T表示做矩陣的轉(zhuǎn)置'''inputs = numpy.array(inputs_list, ndmin=2).Ttargets = numpy.array(targets_list, nmin=2).T#計算信號經(jīng)過輸入層后產(chǎn)生的信號量hidden_inputs = numpy.dot(self.wih, inputs)#中間層神經(jīng)元對輸入的信號做激活函數(shù)后得到輸出信號hidden_outputs = self.activation_function(hidden_inputs)#輸出層接收來自中間層的信號量final_inputs = numpy.dot(self.who, hidden_outputs)#輸出層對信號量進行激活函數(shù)后得到最終輸出信號final_outputs = self.activation_function(final_inputs)

函數(shù)的實現(xiàn)跟我們在上一節(jié)對query函數(shù)的實現(xiàn)邏輯是一樣的,不同在于它多了兩個輸入函數(shù)inputs_list和targets_list,這兩個參數(shù)分別代表輸入的訓(xùn)練數(shù)據(jù),已經(jīng)訓(xùn)練數(shù)據(jù)對應(yīng)的正確結(jié)果。函數(shù)中有一點知道注意的是,我們要把輸入的參數(shù)轉(zhuǎn)換成numpy類型的二維矩陣,輸入的inputs_list類型是二維列表,它跟二維矩陣不同,如果不轉(zhuǎn)換成numpy支持的二維矩陣,那么numpy導(dǎo)出的很多計算函數(shù)就無法使用,例如做矩陣點乘的dot函數(shù),舉個例子:

l = [[1,2],[3,4]] print("origin l is {0}".format(l)) ll = numpy.array(l, ndmin=2) print(ll)

l對應(yīng)的就是一個二維列表,它調(diào)用numpy.array轉(zhuǎn)換格式后,輸出如下:

上面代碼根據(jù)輸入數(shù)據(jù)計算出結(jié)果后,我們先要獲得計算誤差,誤差就是用正確結(jié)果減去網(wǎng)絡(luò)的計算結(jié)果。在代碼中對應(yīng)的就是(targets - final_outputs).我們前面講過,在誤差回傳時,要根據(jù)鏈路的權(quán)重來把誤差分配給每條鏈路,然后節(jié)點再把由它發(fā)出的每條鏈路分配到的誤差加總起來,例如下面網(wǎng)絡(luò):

中間層節(jié)點1對應(yīng)的誤差是兩條鏈路分配到的誤差之后,中間層節(jié)點1到最外層節(jié)點1鏈路會分配到一部分誤差,中間層節(jié)點1和最外層節(jié)點2之間的鏈路會分配到一部分誤差,這兩部分誤差合在一起就是中間層節(jié)點1的得到的誤差。由此,中間層節(jié)點對應(yīng)的誤差就可以通過下面公式計算:

回憶一下Weight(hidden_output)矩陣格式,它是一個二維數(shù)組,對應(yīng)著中間層節(jié)點到做外層節(jié)點的鏈路權(quán)重所組成的矩陣二維矩陣,對應(yīng)于上面網(wǎng)絡(luò)就是:

[w(11), w(21)W(12), w(22) ]

errors(output)對應(yīng)于上面網(wǎng)絡(luò)就是:

[e1,e2 ]

把上面矩陣做轉(zhuǎn)置后在與errors向量做點乘就是:

[ [ w(11), w(12) e1 w(21), w(22) * e2 ] ] = [w(11)*e1+w(12)*e2 , w(21)*e1 + w(22)*e2]

其中w(11)*e1+w(12)*e2就是中間層節(jié)點1根據(jù)反向傳播后得到的誤差。當(dāng)我們要改進中間層到最外層間鏈路權(quán)重時,我們需要output_errors,當(dāng)我們要修改輸入層與中間層的鏈路權(quán)重時,我們需要hidden_errors,相應(yīng)代碼實現(xiàn)如下:

#計算誤差 output_errors = targets - final_outputs hidden_errors = numpy.dot(self.who.T, output_errors)

前面我們已經(jīng)推導(dǎo)出鏈路權(quán)重更新的公式:

上面公式最前面的a對應(yīng)的就是學(xué)習(xí)率,sigmoid對應(yīng)的就是代碼中的self.activation_function,其中的’*’表示普通數(shù)值乘法,而符號’.’表示向量乘法,計算出上面的權(quán)重更新后,原有權(quán)重要加上這個更新數(shù)值。我們用代碼實現(xiàn)如下:

#根據(jù)誤差計算鏈路權(quán)重的更新量,然后把更新加到原來鏈路權(quán)重上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))

上面代碼不好理解,可以把上面代碼對應(yīng)到下面公式:

上圖是我們以前講過的內(nèi)容,后面橫著的(O1,O2…)對應(yīng)代碼中的numpy.transpose(hidden_outputs),其中的E1, E2 …對應(yīng)的就是output_errors,而S1*(1-S1), S2*(1-S2)….對應(yīng)final_outputs*(1-final_outputs)。至此網(wǎng)絡(luò)自我訓(xùn)練的代碼就完成了,train函數(shù)的整體代碼如下:

def train(self, inputs_list, targets_list):#根據(jù)輸入的訓(xùn)練數(shù)據(jù)更新節(jié)點鏈路權(quán)重'''把inputs_list, targets_list轉(zhuǎn)換成numpy支持的二維矩陣.T表示做矩陣的轉(zhuǎn)置'''inputs = numpy.array(inputs_list, ndmin=2).Ttargets = numpy.array(targets_list, nmin=2).T#計算信號經(jīng)過輸入層后產(chǎn)生的信號量hidden_inputs = numpy.dot(self.wih, inputs)#中間層神經(jīng)元對輸入的信號做激活函數(shù)后得到輸出信號hidden_outputs = self.activation_function(hidden_inputs)#輸出層接收來自中間層的信號量final_inputs = numpy.dot(self.who, hidden_outputs)#輸出層對信號量進行激活函數(shù)后得到最終輸出信號final_outputs = self.activation_function(final_inputs)#計算誤差output_errors = targets - final_outputshidden_errors = numpy.dot(self.who.T, output_errors)#根據(jù)誤差計算鏈路權(quán)重的更新量,然后把更新加到原來鏈路權(quán)重上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

接下來我們就得拿實際數(shù)據(jù)來訓(xùn)練我們的神經(jīng)網(wǎng)絡(luò)了,在最開始時,我們曾經(jīng)用MNIST數(shù)字圖片來進行識別,現(xiàn)在我們使用一種cvs格式的數(shù)據(jù)來訓(xùn)練,其下載路徑如下:

https://raw.githubusercontent.com/makeyourownneuralnetwork/makeyourownneuralnetw ork/master/mnist_dataset/mnist_test_10.csv

上面數(shù)據(jù)下載后格式如下:

第一個數(shù)字表示的是圖片對應(yīng)的數(shù)字,根據(jù)上面例子,第一個數(shù)字是7,接下來有28*28 = 768個數(shù)字,對應(yīng)的其實是一張黑白圖片的像素點,經(jīng)過第一節(jié)的同學(xué)能看過這樣的數(shù)字圖片。根據(jù)鏈接把數(shù)據(jù)下載后,我們用代碼將其讀入程序中:

#open函數(shù)里的路徑根據(jù)數(shù)據(jù)存儲的路徑來設(shè)定 data_file = open("/Users/chenyi/Documents/人工智能/mnist_test_10.csv") data_list = data_file.readlines() data_file.close() len(data_list) data_list[0]

上面代碼運行后結(jié)果如下:

注意看,后面28*28個數(shù)值中,每個數(shù)字都不超過256,也就是數(shù)字表示的是像素點的灰度,值越大,顏色就越傾向于黑色。我們用代碼把數(shù)字畫出來,看看其是否真的對應(yīng)一個數(shù)子:

import numpy import matplotlib.pyplot %matplotlib inline #把數(shù)據(jù)依靠','區(qū)分,并分別讀入 all_values = data_list[0].split(',') #第一個值對應(yīng)的是圖片的表示的數(shù)字,所以我們讀取圖片數(shù)據(jù)時要去掉第一個數(shù)值 image_array = numpy.asfarray(all_values[1:]).reshape((28, 28)) matplotlib.pyplot.imshow(image_array, cmap='Greys', interpolation='None')

數(shù)據(jù)讀入時,每個數(shù)字其實都是字符,asfarray把all_values里面的數(shù)字字符全部轉(zhuǎn)換成浮點數(shù),reshape((28,28)),把含有768個元素的all_values列表轉(zhuǎn)換成28行28列的二維數(shù)組,上面代碼運行后結(jié)果如下:

從繪制的結(jié)果看,數(shù)據(jù)代表的確實是一個黑白圖片的手寫數(shù)字。數(shù)據(jù)讀取完畢后,我們再對數(shù)據(jù)格式做些調(diào)整,以便輸入到神經(jīng)網(wǎng)絡(luò)中進行分析。我們需要做的是將數(shù)據(jù)“正規(guī)化”,也就是把所有數(shù)值全部轉(zhuǎn)換到0.01到1.0之間,由于表示圖片的二維數(shù)組中,每個數(shù)大小不超過255,由此我們只要把所有數(shù)組除以255,就能讓數(shù)據(jù)全部落入到0和1之間,有些數(shù)值雖然很小,除以255后會變?yōu)?,這樣會導(dǎo)致鏈路權(quán)重更新出問題,所以我們需要把除以255后的結(jié)果先乘以0.99,然后再加上0.01,這樣所有數(shù)據(jù)就處于0.01到1之間。代碼實現(xiàn)為:

scaled_input = image_array / 255.0 * 0.99 + 0.01 print(scaled_input)

上面代碼運行后結(jié)果如下:

從下節(jié)開始,我們把處理好的數(shù)據(jù)傳入網(wǎng)絡(luò),看看它是怎么從數(shù)據(jù)中學(xué)習(xí),最終能練就識別手寫數(shù)字圖片的能力的。

總結(jié)

以上是生活随笔為你收集整理的用python实现数字图片识别神经网络--实现网络训练功能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。