神經(jīng)網(wǎng)絡(luò)--基礎(chǔ)篇(二)解析:零基礎(chǔ)入門深度學(xué)習(xí)(3) - 神經(jīng)網(wǎng)絡(luò)和反向傳播算法Part2

參考的文章《零基礎(chǔ)入門深度學(xué)習(xí)(3) - 神經(jīng)網(wǎng)絡(luò)和反向傳播算法》:https://www.zybuluo.com/hanbingtao/note/476663


接上一篇,參考文章里面這一部分作者太不負(fù)責(zé)任了。。。代碼沒寫全就跑路了。。這一部分分為兩塊:傳統(tǒng)方法代碼,向量化方法代碼。


傳統(tǒng)方法篇

先介紹傳統(tǒng)方法。再次吐槽,作者給的讀取圖像的代碼,太不合時(shí)宜了,Python2.7簡(jiǎn)直了,我用Python3.6怎么跑也跑不通,后來發(fā)現(xiàn)了這個(gè),(可能適用于Py3.5)

這篇文章作者也是用Python3(3.5)在跑原代碼也遇到了問題,他自己解決了,我本以為看到了一線生機(jī),激動(dòng)得我不要不要的,誰成想3.6和3.5也是難以逾越的鴻溝。。。我又一次陷入了無奈中,最后我忽然想到了git?hub,果不其然,找到了另一種讀取mnist數(shù)據(jù)集的方法。。。github萬歲?。?!放鏈接!

github:https://github.com/sivapvarma/MNIST.py/blob/master/mnist.py

我copy了代碼做了些許修改和標(biāo)注:

github:https://github.com/leiseraiesecqd/DL/blob/master/read.py


然后就是要分析一下mnist數(shù)據(jù)集到底長啥樣:

train_data_set,

train_labels


test_data_set,


test_labels


數(shù)據(jù)類型全部是:

我們讀取train_set中的一張,探索其結(jié)構(gòu)(只是截取了部分截圖):是一個(gè)28*28的結(jié)構(gòu),也就是一個(gè)大[? ]里有28個(gè)小[? ],每個(gè)小[? ]里面有28個(gè)元素。train_set有60000個(gè)這樣的大[? ]。

我們讀取train_label中前五個(gè)元素:可見是個(gè)1*60000的結(jié)構(gòu),也就是一個(gè)[? ]里有60000個(gè)元素組成。


目前,對(duì)于dataset和label我們沒動(dòng)。接下來,要reshap了,這是一門學(xué)問!?。?wù)必要自己學(xué)會(huì)探索。先說一下為啥要reshape,因?yàn)槲覀兊木W(wǎng)絡(luò)結(jié)構(gòu)定義為輸入層784個(gè)節(jié)點(diǎn),輸出層10個(gè)節(jié)點(diǎn)。

(1)dataset的處理

將每張圖片展成1*728的向量。train_data_set[0].reshape(1,784)取一張照片然后可以看到(截取了部分)如下圖:也就是一個(gè)大[? ]里面有一個(gè)小[ ],這個(gè)小[ ]里有784個(gè)元素。下一個(gè)問題,對(duì)整個(gè)dataset怎么處理?用 train_data_set.reshape(60000,784),結(jié)構(gòu)變成了一個(gè)大[? ]里面有60000個(gè)小[ ],每個(gè)小[ ]有784的元素。整個(gè)數(shù)據(jù)集shape是(60000,784).

(2)label的處理

接下來,我們需要對(duì)labe做兩步處理。

第一、進(jìn)行one-hot encoding,也就是那個(gè)norm函數(shù),是每個(gè)元素表示成,如[0,1,0,0,0,0,0,0,0,0,0]的結(jié)構(gòu),十個(gè)元素對(duì)應(yīng)輸出層的10個(gè)節(jié)點(diǎn),這樣子我們?cè)偃rain_label的前五個(gè)元素,就變成如圖。一個(gè)大[ ]里有60000個(gè)小[? ],每個(gè)小[? ]里面有10個(gè)有元素。此時(shí)對(duì)于整個(gè)數(shù)據(jù)集,它的shape是(60000,10)

第二、reshape變形。我們?nèi)nehot處理后的數(shù)據(jù)的第一個(gè)數(shù)據(jù)。train_labels[0].reshap(10,1),如圖:[? ]中每個(gè)元素都加了[? ] .這種數(shù)據(jù)才是我們需要的。而不是上圖那種,因?yàn)樯婕暗矫總€(gè)元素要和對(duì)應(yīng)的每個(gè)輸出節(jié)點(diǎn)的值相減。那么如何reshape全部呢?答案不是train_labels.reshap(10,60000),而是train_labels.reshape(60000,10,1). 顯然,此時(shí)整個(gè)數(shù)據(jù)集shape是(60000,10,1)。


休息一下,讓我們總結(jié)一下(10,)和(10,1)的區(qū)別:

前者:[ 1,2,3,4,5]

后者:[[1],[2],[3],[4],[5]]

小結(jié):對(duì)于深度學(xué)習(xí)框架,tensorflow。我們經(jīng)常調(diào)侃,每個(gè)tensor都在flow。其實(shí)對(duì)于數(shù)據(jù)結(jié)構(gòu)的理解相當(dāng)重要,數(shù)據(jù)在網(wǎng)絡(luò)里面是怎么跑的,這個(gè)理解是很重要的。拿本例子來說,輸入train_set是一個(gè)60000*784的結(jié)構(gòu),每次輸入,都輸入一張照片,即一個(gè)元素,這個(gè)元素里有784個(gè)數(shù)據(jù),對(duì)應(yīng)輸入層784個(gè)節(jié)點(diǎn);對(duì)應(yīng)的,trian_label是一個(gè)60000*10*1的結(jié)構(gòu),每次輸入一個(gè)元素,這個(gè)元素里有10個(gè)數(shù)據(jù),對(duì)應(yīng)輸出層10個(gè)節(jié)點(diǎn)。歸納起來,系統(tǒng)是一個(gè)一個(gè)樣本的跑,一個(gè)樣本包括一張照片和它對(duì)應(yīng)的label。test的樣本同理。


關(guān)于數(shù)據(jù)集我們就講這么多。下面就是另一個(gè)坑。關(guān)于我們之前寫好的那個(gè)network,他其實(shí)是跑不通的。。。作者太不負(fù)責(zé)任了。主要問題是networ.predict它返回的是一個(gè)map,這樣會(huì)和我們mnisy.py里面evaluate函數(shù)代碼不匹配,所以我做了修改network2.0.py,主要是把predict函數(shù)返回做了修改,使它返回預(yù)測(cè)值,而不是一個(gè)map。而中間過程真的是特別心塞,說到底,就是我對(duì)之前的作者寫的network知識(shí)照葫蘆畫瓢,沒有真正理解他每一步是怎么跑的。具體結(jié)構(gòu)解析在我的上一篇文章里有。http://www.lxweimin.com/writer#/notebooks/17670616/notes/18346188


再嘮叨一句,迭代次數(shù)和訓(xùn)練的樣本數(shù)不是一個(gè)東西,迭代一次,會(huì)把你輸入的樣本數(shù)跑完。而不是迭代一次,跑一個(gè)樣本。比如:我輸入20個(gè)樣本,迭代一次,那么我就把這20樣本跑完了,這樣算一完成一次迭代。還有,迭代次數(shù)設(shè)置是在訓(xùn)練的時(shí)候,測(cè)試時(shí)不用迭代,因?yàn)榫团芤槐榈贸鰷?zhǔn)確率。


最后附一下我的代碼(基于Py3.6)https://github.com/leiseraiesecqd/DL

本節(jié)內(nèi)容參考里面的read+network2.0.py+mnist.py

提示一下,由于cpu實(shí)在是弱雞,建議大家跑程序的時(shí)候先訓(xùn)練一個(gè)樣本,測(cè)試一個(gè)樣本;如果能跑通,再訓(xùn)練10張,測(cè)試10張。這樣就差不多了,重在理解。。如果你妄想把60000個(gè)訓(xùn)練集訓(xùn)練完,把10000個(gè)測(cè)試集測(cè)試完。那就等到幾年后吧。。。

ps:下一節(jié)我們講向量化編程。會(huì)使效率提升很多。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容