深入淺出神經(jīng)網(wǎng)絡(luò)的改進(jìn)方法!
點(diǎn)擊上方“小白學(xué)視覺(jué)”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)
高爾夫球員剛開(kāi)始學(xué)習(xí)打高爾夫球時(shí),通常會(huì)花很長(zhǎng)時(shí)間練習(xí)揮桿。慢慢地,他們才會(huì)在此基礎(chǔ)上練習(xí)其他擊球方式,學(xué)習(xí)削球、左曲球和右曲球。本章仍著重介紹反向傳播算法,這就是我們的“揮桿基本功”——神經(jīng)網(wǎng)絡(luò)中大部分工作、學(xué)習(xí)和研究的基礎(chǔ)。

大多數(shù)人不喜歡被他人指出錯(cuò)誤。我以前剛學(xué)習(xí)彈鋼琴不久,就在聽(tīng)眾前做了一次首秀。我很緊張,開(kāi)始時(shí)錯(cuò)將八度音階的曲段演奏得很低。我不知所措,因?yàn)檠葑酂o(wú)法繼續(xù)下去了,直到有人指出了其中的錯(cuò)誤。我當(dāng)時(shí)非常尷尬。不過(guò),盡管不愉快,我們卻能因?yàn)槊黠@的錯(cuò)誤而快速地學(xué)到正確的知識(shí)。下次我肯定能演奏正確!然而當(dāng)錯(cuò)誤不明確的時(shí)候,學(xué)習(xí)會(huì)變得非常緩慢。學(xué)習(xí)速度下降的原因?qū)嶋H上也是一般的神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)緩慢的原因,并不僅僅是特有的。
引入交叉熵代價(jià)函數(shù)
如何解決這個(gè)問(wèn)題呢?研究表明,可以使用交叉熵代價(jià)函數(shù)來(lái)替換二次代價(jià)函數(shù)。
將交叉熵看作代價(jià)函數(shù)有兩點(diǎn)原因。第一,它是非負(fù)的,C > 0。可以看出(57)的求和中的所有單獨(dú)項(xiàng)都是負(fù)數(shù),因?yàn)閷?duì)數(shù)函數(shù)的定義域是(0, 1)。求和前面有一個(gè)負(fù)號(hào)。
第二,如果對(duì)于所有的訓(xùn)練輸入x,神經(jīng)元實(shí)際的輸出都接近目標(biāo)值,那么交叉熵將接近0。假設(shè)在本例中,y = 0而a ≈ 0,這是我們想要的結(jié)果。方程(57)中的第一個(gè)項(xiàng)會(huì)消去,因?yàn)?em style="font-style: italic;color: rgb(39, 39, 39);">y = 0,而第二項(xiàng)實(shí)際上就是?ln(1 ? a) ≈ 0;反之,y = 1而a ≈ 1。所以實(shí)際輸出和目標(biāo)輸出之間的差距越小,最終交叉熵的值就越小。
綜上所述,交叉熵是非負(fù)的,在神經(jīng)元達(dá)到較高的正確率時(shí)接近0。我們希望代價(jià)函數(shù)具備這些特性。其實(shí)二次代價(jià)函數(shù)也擁有這些特性,所以交叉熵是很好的選擇。然而交叉熵代價(jià)函數(shù)有一個(gè)比二次代價(jià)函數(shù)更好的特性:它避免了學(xué)習(xí)速度下降的問(wèn)題。
代價(jià)函數(shù)曲線要比二次代價(jià)函數(shù)訓(xùn)練開(kāi)始部分陡峭很多。這個(gè)交叉熵導(dǎo)致的陡度正是我們期望的,當(dāng)神經(jīng)元開(kāi)始出現(xiàn)嚴(yán)重錯(cuò)誤時(shí)能以最快的速度學(xué)習(xí)。
使用交叉熵來(lái)對(duì)MNIST數(shù)字進(jìn)行分類
如果程序使用梯度下降算法和反向傳播算法進(jìn)行學(xué)習(xí),那么交叉熵作為其中一部分易于實(shí)現(xiàn)。我們會(huì)使用一個(gè)包含30個(gè)隱藏神經(jīng)元的網(wǎng)絡(luò),小批量的大小也設(shè)置為10,將學(xué)習(xí)率設(shè)置為,訓(xùn)練30輪。network2.py的接口和network.py的略有區(qū)別,但用法還是很好懂的。可以在Python shell中使用help(network2.Network.SGD)這樣的命令來(lái)查看network2.py的接口文檔。
>>> import mnist_loader
>>> training_data, validation_data, test_data = \
... mnist_loader.load_data_wrapper()
>>> import network2
>>> net = network2.Network([784, 30, 10], cost=network2.CrossEntropyCost)
>>> net.large_weight_initializer()
>>> net.SGD(training_data, 30, 10, 0.5, evaluation_data=test_data,
... monitor_evaluation_accuracy=True)
注意,net.large_weight_initializer()命令使用第1章介紹的方式來(lái)初始化權(quán)重和偏置。這里需要執(zhí)行該命令,因?yàn)楹竺娌艜?huì)改變默認(rèn)的權(quán)重初始化命令。運(yùn)行上面的代碼,神經(jīng)網(wǎng)絡(luò)的準(zhǔn)確率可以達(dá)到95.49%,這跟第1章中使用二次代價(jià)函數(shù)得到的結(jié)果(95.42%)相當(dāng)接近了。
對(duì)于使用100個(gè)隱藏神經(jīng)元,而交叉熵及其他參數(shù)保持不變的情況,準(zhǔn)確率達(dá)到了96.82%。相比第1章使用二次代價(jià)函數(shù)的結(jié)果(96.59%)有一定提升。看起來(lái)是很小的變化,但考慮到誤差率已經(jīng)從3.41%下降到3.18%了,消除了原誤差的1/14,這其實(shí)是可觀的改進(jìn)。
交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺(jué)、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺(jué)SLAM“。請(qǐng)按照格式備注,否則不予通過(guò)。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~

