輸入層節(jié)點(diǎn)數(shù)是確定的。因?yàn)镸NIST數(shù)據(jù)集每個(gè)訓(xùn)練數(shù)據(jù)是28*28的圖片,共784個(gè)像素,因此,輸入層節(jié)點(diǎn)數(shù)應(yīng)該是784,每個(gè)像素對應(yīng)一個(gè)輸入節(jié)點(diǎn)。
輸出層節(jié)點(diǎn)數(shù)也是確定的。因?yàn)槭?0分類,我們可以用10個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)對應(yīng)一個(gè)分類。輸出層10個(gè)節(jié)點(diǎn)中,輸出最大值的那個(gè)節(jié)點(diǎn)對應(yīng)的分類,就是模型的預(yù)測結(jié)果。
隱藏層節(jié)點(diǎn)數(shù)量是不好確定的,從1到100萬都可以。下面有幾個(gè)經(jīng)驗(yàn)公式:

因此,我們可以先根據(jù)上面的公式設(shè)置一個(gè)隱藏層節(jié)點(diǎn)數(shù)。如果有時(shí)間,我們可以設(shè)置不同的節(jié)點(diǎn)數(shù),分別訓(xùn)練,看看哪個(gè)效果最好就用哪個(gè)。我們先拍一個(gè),設(shè)隱藏層節(jié)點(diǎn)數(shù)為300吧。
對于3層784*300*10的全連接網(wǎng)絡(luò),總共有300*(784+1)+10*(300+1)=238510個(gè)參數(shù)!神經(jīng)網(wǎng)絡(luò)之所以強(qiáng)大,是它提供了一種非常簡單的方法去實(shí)現(xiàn)大量的參數(shù)。目前百億參數(shù)、千億樣本的超大規(guī)模神經(jīng)網(wǎng)絡(luò)也是有的。因?yàn)镸NIST只有6萬個(gè)訓(xùn)練樣本,參數(shù)太多了很容易過擬合,效果反而不好。
模型的訓(xùn)練和評估
MNIST數(shù)據(jù)集包含10000個(gè)測試樣本。我們先用60000個(gè)訓(xùn)練樣本訓(xùn)練我們的網(wǎng)絡(luò),然后再用測試樣本對網(wǎng)絡(luò)進(jìn)行測試,計(jì)算識別錯(cuò)誤率:

我們每訓(xùn)練10輪,評估一次準(zhǔn)確率。當(dāng)準(zhǔn)確率開始下降時(shí)(出現(xiàn)了過擬合)終止訓(xùn)練。
代碼實(shí)現(xiàn)
首先,我們需要把MNIST數(shù)據(jù)集處理為神經(jīng)網(wǎng)絡(luò)能夠接受的形式。MNIST訓(xùn)練集的文件格式可以參考官方網(wǎng)站,這里不在贅述。每個(gè)訓(xùn)練樣本是一個(gè)28*28的圖像,我們按照行優(yōu)先,把它轉(zhuǎn)化為一個(gè)784維的向量。每個(gè)標(biāo)簽是0-9的值,我們將其轉(zhuǎn)換為一個(gè)10維的one-hot向量:如果標(biāo)簽值為,我們就把向量的第維(從0開始編號)設(shè)置為0.9,而其它維設(shè)置為0.1。例如,向量[0.1,0.1,0.9,0.1,0.1,0.1,0.1,0.1,0.1,0.1]表示值2。
下面是處理MNIST數(shù)據(jù)的代碼:



網(wǎng)絡(luò)的輸出是一個(gè)10維向量,這個(gè)向量第個(gè)(從0開始編號)元素的值最大,那么就是網(wǎng)絡(luò)的識別結(jié)果。下面是代碼實(shí)現(xiàn):

我們使用錯(cuò)誤率來對網(wǎng)絡(luò)進(jìn)行評估,下面是代碼實(shí)現(xiàn):

最后實(shí)現(xiàn)我們的訓(xùn)練策略:每訓(xùn)練10輪,評估一次準(zhǔn)確率,當(dāng)準(zhǔn)確率開始下降時(shí)終止訓(xùn)練。下面是代碼實(shí)現(xiàn):

在我的機(jī)器上測試了一下,1個(gè)epoch大約需要9000多秒,所以要對代碼做很多的性能優(yōu)化工作。訓(xùn)練要很久很久,可以把它上傳到服務(wù)器上,在tmux的session里面去運(yùn)行。為了防止異常終止導(dǎo)致前功盡棄,我們每訓(xùn)練10輪,就把獲得參數(shù)值保存在磁盤上,以便后續(xù)可以恢復(fù)。(代碼略)
小結(jié)
至此,你已經(jīng)完成了又一次漫長的學(xué)習(xí)之旅。你現(xiàn)在應(yīng)該已經(jīng)明白了神經(jīng)網(wǎng)絡(luò)的基本原理,高興的話,你甚至有能力去動(dòng)手實(shí)現(xiàn)一個(gè),并用它解決一些問題。如果感到困難也不要?dú)怵H,這篇文章是一個(gè)重要的分水嶺,如果你完全弄明白了的話,在真正的『小白』和裝腔作勢的『大牛』面前吹吹牛是完全沒有問題的。
作為深度學(xué)習(xí)入門的系列文章,本文也是上半場的結(jié)束。在這個(gè)半場,你掌握了機(jī)器學(xué)習(xí)、神經(jīng)網(wǎng)絡(luò)的基本概念,并且有能力去動(dòng)手解決一些簡單的問題(例如手寫數(shù)字識別,如果用傳統(tǒng)的觀點(diǎn)來看,其實(shí)這些問題也不簡單)。而且,一旦掌握基本概念,后面的學(xué)習(xí)就容易多了。