參考的文章《零基礎(chǔ)入門深度學(xué)習(xí)(3) - 神經(jīng)網(wǎng)絡(luò)和反向傳播算法》:https://www.zybuluo.com/hanbingtao/note/476663
接上一篇,參考文章里面這一部分作者太不負(fù)責(zé)任了椿疗。锥咸。。代碼沒寫全就跑路了。。這一部分分為兩塊:傳統(tǒng)方法代碼,向量化方法代碼芬骄。
傳統(tǒng)方法篇
先介紹傳統(tǒng)方法。再次吐槽鹦聪,作者給的讀取圖像的代碼账阻,太不合時宜了,Python2.7簡直了椎麦,我用Python3.6怎么跑也跑不通宰僧,后來發(fā)現(xiàn)了這個,(可能適用于Py3.5)
這篇文章作者也是用Python3(3.5)在跑原代碼也遇到了問題观挎,他自己解決了琴儿,我本以為看到了一線生機(jī),激動得我不要不要的嘁捷,誰成想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)(只是截取了部分截圖):是一個28*28的結(jié)構(gòu),也就是一個大[? ]里有28個小[? ]龙致,每個小[? ]里面有28個元素蛀缝。train_set有60000個這樣的大[? ]。
我們讀取train_label中前五個元素:可見是個1*60000的結(jié)構(gòu)目代,也就是一個[? ]里有60000個元素組成屈梁。
目前,對于dataset和label我們沒動像啼。接下來俘闯,要reshap了潭苞,這是一門學(xué)問:龆场!此疹!務(wù)必要自己學(xué)會探索僧诚。先說一下為啥要reshape,因?yàn)槲覀兊木W(wǎng)絡(luò)結(jié)構(gòu)定義為輸入層784個節(jié)點(diǎn)蝗碎,輸出層10個節(jié)點(diǎn)湖笨。
(1)dataset的處理
將每張圖片展成1*728的向量。train_data_set[0].reshape(1,784)蹦骑,取一張照片然后可以看到(截取了部分)如下圖:也就是一個大[? ]里面有一個小[ ]慈省,這個小[ ]里有784個元素。下一個問題眠菇,對整個dataset怎么處理边败?用 train_data_set.reshape(60000,784),結(jié)構(gòu)變成了一個大[? ]里面有60000個小[ ]捎废,每個小[ ]有784的元素笑窜。整個數(shù)據(jù)集shape是(60000,784).
(2)label的處理
接下來,我們需要對labe做兩步處理登疗。
第一排截、進(jìn)行one-hot encoding,也就是那個norm函數(shù)辐益,是每個元素表示成断傲,如[0,1,0,0,0,0,0,0,0,0,0]的結(jié)構(gòu),十個元素對應(yīng)輸出層的10個節(jié)點(diǎn)智政,這樣子我們再取train_label的前五個元素认罩,就變成如圖。一個大[ ]里有60000個小[? ]女仰,每個小[? ]里面有10個有元素猜年。此時對于整個數(shù)據(jù)集抡锈,它的shape是(60000,10)
第二、reshape變形乔外。我們?nèi)nehot處理后的數(shù)據(jù)的第一個數(shù)據(jù)床三。train_labels[0].reshap(10,1),如圖:[? ]中每個元素都加了[? ] .這種數(shù)據(jù)才是我們需要的杨幼。而不是上圖那種撇簿,因?yàn)樯婕暗矫總€元素要和對應(yīng)的每個輸出節(jié)點(diǎn)的值相減。那么如何reshape全部呢差购?答案不是train_labels.reshap(10,60000)四瘫,而是train_labels.reshape(60000,10,1). 顯然,此時整個數(shù)據(jù)集shape是(60000,10,1)欲逃。
休息一下找蜜,讓我們總結(jié)一下(10,)和(10,1)的區(qū)別:
前者:[ 1,2,3,4,5]
后者:[[1],[2],[3],[4],[5]]
小結(jié):對于深度學(xué)習(xí)框架稳析,tensorflow洗做。我們經(jīng)常調(diào)侃,每個tensor都在flow彰居。其實(shí)對于數(shù)據(jù)結(jié)構(gòu)的理解相當(dāng)重要诚纸,數(shù)據(jù)在網(wǎng)絡(luò)里面是怎么跑的,這個理解是很重要的陈惰。拿本例子來說畦徘,輸入train_set是一個60000*784的結(jié)構(gòu),每次輸入抬闯,都輸入一張照片井辆,即一個元素,這個元素里有784個數(shù)據(jù)画髓,對應(yīng)輸入層784個節(jié)點(diǎn)掘剪;對應(yīng)的,trian_label是一個60000*10*1的結(jié)構(gòu)奈虾,每次輸入一個元素夺谁,這個元素里有10個數(shù)據(jù),對應(yīng)輸出層10個節(jié)點(diǎn)肉微。歸納起來匾鸥,系統(tǒng)是一個一個樣本的跑,一個樣本包括一張照片和它對應(yīng)的label碉纳。test的樣本同理勿负。
關(guān)于數(shù)據(jù)集我們就講這么多。下面就是另一個坑劳曹。關(guān)于我們之前寫好的那個network奴愉,他其實(shí)是跑不通的琅摩。。锭硼。作者太不負(fù)責(zé)任了房资。主要問題是networ.predict它返回的是一個map,這樣會和我們mnisy.py里面evaluate函數(shù)代碼不匹配檀头,所以我做了修改network2.0.py轰异,主要是把predict函數(shù)返回做了修改,使它返回預(yù)測值暑始,而不是一個map搭独。而中間過程真的是特別心塞,說到底廊镜,就是我對之前的作者寫的network知識照葫蘆畫瓢牙肝,沒有真正理解他每一步是怎么跑的。具體結(jié)構(gòu)解析在我的上一篇文章里有期升。http://www.reibang.com/writer#/notebooks/17670616/notes/18346188
再嘮叨一句惊奇,迭代次數(shù)和訓(xùn)練的樣本數(shù)不是一個東西,迭代一次播赁,會把你輸入的樣本數(shù)跑完。而不是迭代一次吼渡,跑一個樣本容为。比如:我輸入20個樣本,迭代一次寺酪,那么我就把這20樣本跑完了坎背,這樣算一完成一次迭代。還有寄雀,迭代次數(shù)設(shè)置是在訓(xùn)練的時候得滤,測試時不用迭代,因?yàn)榫团芤槐榈贸鰷?zhǔn)確率盒犹。
最后附一下我的代碼(基于Py3.6)https://github.com/leiseraiesecqd/DL懂更,
本節(jié)內(nèi)容參考里面的read+network2.0.py+mnist.py
提示一下,由于cpu實(shí)在是弱雞急膀,建議大家跑程序的時候先訓(xùn)練一個樣本沮协,測試一個樣本;如果能跑通卓嫂,再訓(xùn)練10張慷暂,測試10張。這樣就差不多了晨雳,重在理解行瑞。奸腺。如果你妄想把60000個訓(xùn)練集訓(xùn)練完,把10000個測試集測試完血久。那就等到幾年后吧洋机。。洋魂。
ps:下一節(jié)我們講向量化編程绷旗。會使效率提升很多。