當(dāng)一個(gè)高爾夫球員剛開始學(xué)習(xí)打高爾夫時(shí),他們通常會(huì)在揮桿的練習(xí)上花費(fèi)大多數(shù)時(shí)間。慢慢地他們才會(huì)在基本的揮桿上通過變化發(fā)展其他的擊球方式,學(xué)習(xí)低飛球、左曲球和右曲球。類似的,我們現(xiàn)在仍然聚焦在反向傳播算法的理解上。這就是我們的“基本揮桿”——神經(jīng)網(wǎng)絡(luò)中大部分工作學(xué)習(xí)和研究的基礎(chǔ)。本章,我會(huì)解釋若干技術(shù)能夠用來提升我們關(guān)于反向傳播的初級(jí)的實(shí)現(xiàn),最終改進(jìn)網(wǎng)絡(luò)學(xué)習(xí)的方式。
本章涉及的技術(shù)包括:更好的代價(jià)函數(shù)的選擇——交叉熵 代價(jià)函數(shù);四中規(guī)范化方法(L1 和 L2 規(guī)范化,dropout 和訓(xùn)練數(shù)據(jù)的人工擴(kuò)展),這會(huì)讓我們的網(wǎng)絡(luò)在訓(xùn)練集之外的數(shù)據(jù)上更好地泛化;更好的權(quán)重初始化方法;還有幫助選擇好的超參數(shù)的啟發(fā)式想法。同樣我也會(huì)再給出一些簡(jiǎn)要的其他技術(shù)介紹。這些討論之間的獨(dú)立性比較大,所有你們可以隨自己的意愿挑著看。另外我還會(huì)在代碼中實(shí)現(xiàn)這些技術(shù),使用他們來提高在第一章中的分類問題上的性能。
當(dāng)然,我們僅僅覆蓋了大量已經(jīng)在神經(jīng)網(wǎng)絡(luò)中研究發(fā)展出的技術(shù)的一點(diǎn)點(diǎn)內(nèi)容。此處我們學(xué)習(xí)深度學(xué)習(xí)的觀點(diǎn)是想要在一些已有的技術(shù)上入門的最佳策略其實(shí)是深入研究一小部分最重要那些的技術(shù)點(diǎn)。掌握了這些關(guān)鍵技術(shù)不僅僅對(duì)這些技術(shù)本身的理解很有用,而且會(huì)深化你對(duì)使用神經(jīng)網(wǎng)絡(luò)時(shí)會(huì)遇到哪些問題的理解。這會(huì)讓你們做好在需要時(shí)快速掌握其他技術(shù)的充分準(zhǔn)備。
我們大多數(shù)人覺得錯(cuò)了就很不爽。在開始學(xué)習(xí)彈奏鋼琴不久后,我在一個(gè)聽眾前做了處女秀。我很緊張,開始時(shí)將八度音階的曲段演奏得很低。我很困惑,因?yàn)椴荒芾^續(xù)演奏下去了,直到有個(gè)人指出了其中的錯(cuò)誤。當(dāng)時(shí),我非常尷尬。不過,盡管不開心,我們卻能夠因?yàn)槊黠@的犯錯(cuò)快速地學(xué)習(xí)到正確的東西。你應(yīng)該相信下次我再演奏肯定會(huì)是正確的!相反,在我們的錯(cuò)誤不是很好的定義的時(shí)候,學(xué)習(xí)的過程會(huì)變得更加緩慢。
理想地,我們希望和期待神經(jīng)網(wǎng)絡(luò)可以從錯(cuò)誤中快速地學(xué)習(xí)。在實(shí)踐中,這種情況經(jīng)常出現(xiàn)么?為了回答這個(gè)問題,讓我們看看一個(gè)小例子。這個(gè)例子包含一個(gè)只有一個(gè)輸入的神經(jīng)元:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/41.png" alt="" />
我們會(huì)訓(xùn)練這個(gè)神經(jīng)元來做一件非常簡(jiǎn)單的事:讓輸入$$1$$轉(zhuǎn)化為 $$0$$。當(dāng)然,這很簡(jiǎn)單了,手工找到合適的權(quán)重和偏差就可以了,不需要什么學(xué)習(xí)算法。然而,看起來使用梯度下降的方式來學(xué)習(xí)權(quán)重和偏差是很有啟發(fā)的。所以,我們來看看神經(jīng)元如何學(xué)習(xí)。
為了讓事情確定化,我會(huì)首先將權(quán)重和偏差初始化為$$0.6$$和 $$0.9$$。這些就是一般的開始學(xué)習(xí)的選擇,并沒有任何刻意的想法。一開始的神經(jīng)元的輸出是 $$0.82$$,所以這離我們的目標(biāo)輸出 $$0.0$$ 還差得很遠(yuǎn)。點(diǎn)擊右下角的“運(yùn)行”按鈕來看看神經(jīng)元如何學(xué)習(xí)到讓輸出接近 $$0.0$$ 的。注意到,這并不是一個(gè)已經(jīng)錄好的動(dòng)畫,你的瀏覽器實(shí)際上是正在進(jìn)行梯度的計(jì)算,然后使用梯度更新來對(duì)權(quán)重和偏差進(jìn)行更新,并且展示結(jié)果。設(shè)置學(xué)習(xí)率 $$\eta=0.15$$ 進(jìn)行學(xué)習(xí)一方面足夠慢的讓我們跟隨學(xué)習(xí)的過程,另一方面也保證了學(xué)習(xí)的時(shí)間不會(huì)太久,幾秒鐘應(yīng)該就足夠了。代價(jià)函數(shù)是我們前面用到的二次函數(shù),$$C$$。這里我也會(huì)給出準(zhǔn)確的形式,所以不需要翻到前面查看定義了。注意,你可以通過點(diǎn)擊 “Run” 按鈕執(zhí)行訓(xùn)練若干次。
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/42.png" alt="1" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/43.png" alt="2" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/44.png" alt="3" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/45.png" alt="4" />
我們這里是靜態(tài)的例子,在原書中,使用的動(dòng)態(tài)示例,所以為了更好的效果,請(qǐng)參考原書的此處動(dòng)態(tài)示例。
正如你所見,神經(jīng)元快速地學(xué)到了使得代價(jià)函數(shù)下降的權(quán)重和偏差,給出了最終的輸出為 $$0.09$$。這雖然不是我們的目標(biāo)輸出 $$0.0$$,但是已經(jīng)挺好了。假設(shè)我們現(xiàn)在將初始權(quán)重和偏差都設(shè)置為 $$2.0$$。此時(shí)初始輸出為 $$0.98$$,這是和目標(biāo)值的差距相當(dāng)大的?,F(xiàn)在看看神經(jīng)元學(xué)習(xí)的過程。點(diǎn)擊“Run” 按鈕:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/46.png" alt="1" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/47.png" alt="2" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/48.png" alt="3" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/49.png" alt="4" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/50.png" alt="5" />
雖然這個(gè)例子使用的了同樣的學(xué)習(xí)率 $$\eta=0.15$$,我們可以看到剛開始的學(xué)習(xí)速度是比較緩慢的。對(duì)前 $$150$$ 左右的學(xué)習(xí)次數(shù),權(quán)重和偏差并沒有發(fā)生太大的變化。隨后學(xué)習(xí)速度加快,與上一個(gè)例子中類似了,神經(jīng)網(wǎng)絡(luò)的輸出也迅速接近$$0.0$$。
強(qiáng)烈建議參考原書的此處動(dòng)態(tài)示例感受學(xué)習(xí)過程的差異。
這種行為看起來和人類學(xué)習(xí)行為差異很大。正如我在此節(jié)開頭所說,我們通常是在犯錯(cuò)比較明顯的時(shí)候?qū)W習(xí)的速度最快。但是我們已經(jīng)看到了人工神經(jīng)元在其犯錯(cuò)較大的情況下其實(shí)學(xué)習(xí)很有難度。而且,這種現(xiàn)象不僅僅是在這個(gè)小例子中出現(xiàn),也會(huì)再更加一般的神經(jīng)網(wǎng)絡(luò)中出現(xiàn)。為何學(xué)習(xí)如此緩慢?我們能夠找到緩解這種情況的方法么?
為了理解這個(gè)問題的源頭,想想神經(jīng)元是按照偏導(dǎo)數(shù)($$\partial C/\partial w$$ 和 $$\partial C/\partial b$$)和學(xué)習(xí)率($$\eta$$)的乘積來改變權(quán)重和偏差的。所以,我們?cè)谡f“學(xué)習(xí)緩慢”時(shí),實(shí)際上就是說這些偏導(dǎo)數(shù)很小。理解他們?yōu)楹芜@么小就是我們面臨的挑戰(zhàn)。為了理解這些,讓我們計(jì)算偏導(dǎo)數(shù)看看。我們一直在用的是二次代價(jià)函數(shù),定義如下
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/51.png" alt="" />
其中 $$a$$ 是神經(jīng)元的輸出,其中訓(xùn)練輸入為 $$x=1$$,$$y=0$$ 則是目標(biāo)輸出。顯式地使用權(quán)重和偏差來表達(dá)這個(gè),我們有 $$a=\sigma(z)$$,其中 $$z=wx+b$$。使用鏈?zhǔn)椒▌t來求偏導(dǎo)數(shù)就有:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/52.png" alt="" />
其中我已經(jīng)將 $$x=1$$ 和 $$y=0$$ 代入了。為了理解這些表達(dá)式的行為,讓我們仔細(xì)看 $$\sigma'(z)$$ 這一項(xiàng)。首先回憶一下 $$\sigma$$ 函數(shù)圖像:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/53.png" alt="" />
我們可以從這幅圖看出,當(dāng)神經(jīng)元的輸出接近 $$1$$ 的時(shí)候,曲線變得相當(dāng)平,所以 $$\sigma'(z)$$ 就很小了。方程 (55) 和 (56) 也告訴我們 $$\partial C/\partial w$$ 和 $$\partial C/\partial b$$ 會(huì)非常小。這其實(shí)就是學(xué)習(xí)緩慢的原因所在。而且,我們后面也會(huì)提到,這種學(xué)習(xí)速度下降的原因?qū)嶋H上也是更加一般的神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)緩慢的原因,并不僅僅是在這個(gè)特例中特有的。
那么我們?nèi)绾谓鉀Q這個(gè)問題呢?研究表明,我們可以通過使用交叉熵代價(jià)函數(shù)來替換二次代價(jià)函數(shù)。為了理解什么是交叉熵,我們稍微改變一下之前的簡(jiǎn)單例子。假設(shè),我們現(xiàn)在要訓(xùn)練一個(gè)包含若干輸入變量的的神經(jīng)元,$$x_1,x_2,...$$ 對(duì)應(yīng)的權(quán)重為 $$w_1,w_2,...$$ 和偏差,$$b$$:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/54.png" alt="" />
神經(jīng)元的輸出就是 $$a=\sigma(z)$$,其中 $$z=\sum_jw_jx_j+b$$ 是輸入的帶權(quán)和。我們?nèi)缦露x交叉熵代價(jià)函數(shù):
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/55.png" alt="" />
其中 $$n$$ 是訓(xùn)練數(shù)據(jù)的總數(shù),對(duì)所有的訓(xùn)練數(shù)據(jù) $$x$$ 和 對(duì)應(yīng)的目標(biāo)輸出 $$y$$ 進(jìn)行求和。
公式(57)是否解決學(xué)習(xí)緩慢的問題并不明顯。實(shí)際上,甚至將這個(gè)定義看做是代價(jià)函數(shù)也不是顯而易見的!在解決學(xué)習(xí)緩慢前,我們來看看交叉熵為何能夠解釋成一個(gè)代價(jià)函數(shù)。
將交叉熵看做是代價(jià)函數(shù)有兩點(diǎn)原因。第一,它使非負(fù)的,$$C>0$$??梢钥闯觯?a) 公式(57)的和式中所有獨(dú)立的項(xiàng)都是非負(fù)的,因?yàn)閷?duì)數(shù)函數(shù)的定義域是 $$(0,1)$$;(b) 前面有一個(gè)負(fù)號(hào)。
第二,如果神經(jīng)元實(shí)際的輸出接近目標(biāo)值。假設(shè)在這個(gè)例子中,$$y=0$$ 而 $$a\approx 0$$。這是我們想到得到的結(jié)果。我們看到公式(57)中第一個(gè)項(xiàng)就消去了,因?yàn)?$$y=0$$,而第二項(xiàng)實(shí)際上就是 $$-\ln (1-a)\approx 0$$。反之,$$y=1$$ 而 $$a\approx 1$$。所以在實(shí)際輸出和目標(biāo)輸出之間的差距越小,最終的交叉熵的值就越低了。
綜上所述,交叉熵是非負(fù)的,在神經(jīng)元達(dá)到很好的正確率的時(shí)候會(huì)接近 $$0$$。這些其實(shí)就是我們想要的代價(jià)函數(shù)的特性。其實(shí)這些特性也是二次代價(jià)函數(shù)具備的。所以,交叉熵就是很好的選擇了。但是交叉熵代價(jià)函數(shù)有一個(gè)比二次代價(jià)函數(shù)更好的特性就是它避免了學(xué)習(xí)速度下降的問題。為了弄清楚這個(gè)情況,我們來算算交叉熵函數(shù)關(guān)于權(quán)重的偏導(dǎo)數(shù)。我們將 $$a=\sigma(z)$$ 代入到公式 (57) 中應(yīng)用兩次鏈?zhǔn)椒▌t,得到:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/56.png" alt="" />
將結(jié)果合并一下,簡(jiǎn)化成:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/57.png" alt="" />
根據(jù) $$\sigma(z) = 1/(1+e^{-z})$$ 的定義,和一些運(yùn)算,我們可以得到 $$\sigma'(z) = \sigma(z)(1-\sigma(z))$$。后面在練習(xí)中會(huì)要求你計(jì)算這個(gè),現(xiàn)在可以直接使用這個(gè)結(jié)果。我們看到 $$\sigma'$$ 和 $$\sigma(z)(1-\sigma(z))$$ 這兩項(xiàng)在方程中直接約去了,所以最終形式就是:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/58.png" alt="" />
這是一個(gè)優(yōu)美的公式。它告訴我們權(quán)重學(xué)習(xí)的速度受到 $$\sigma(z)-y$$,也就是輸出中的誤差的控制。更大的誤差,更快的學(xué)習(xí)速度。這是我們直覺上期待的結(jié)果。特別地,這個(gè)代價(jià)函數(shù)還避免了像在二次代價(jià)函數(shù)中類似公式中 $$\sigma'(z)$$ 導(dǎo)致的學(xué)習(xí)緩慢,見公式(55)。當(dāng)我們使用交叉熵的時(shí)候,$$\sigma'(z)$$ 被約掉了,所以我們不再需要關(guān)心它是不是變得很小。這種約除就是交叉熵帶來的特效。實(shí)際上,這也并不是非常奇跡的事情。我們?cè)诤竺婵梢钥吹?,交叉熵其?shí)只是滿足這種特性的一種選擇罷了。
根據(jù)類似的方法,我們可以計(jì)算出關(guān)于偏差的偏導(dǎo)數(shù)。我這里不再給出詳細(xì)的過程,你可以輕易驗(yàn)證得到
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/59.png" alt="" />
讓我們重回最原初的例子,來看看換成了交叉熵之后的學(xué)習(xí)過程?,F(xiàn)在仍然按照前面的參數(shù)配置來初始化網(wǎng)絡(luò),開始權(quán)重為 $$0.6$$,而偏差為 $$0.9$$。點(diǎn)擊“Run”按鈕看看在換成交叉熵之后網(wǎng)絡(luò)的學(xué)習(xí)情況:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/60.png" alt="1" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/61.png" alt="2" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/62.png" alt="3" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/63.png" alt="4" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/64.png" alt="5" />
毫不奇怪,在這個(gè)例子中,神經(jīng)元學(xué)習(xí)得相當(dāng)出色,跟之前差不多。現(xiàn)在我們?cè)倏纯粗俺鰡栴}的那個(gè)例子,權(quán)重和偏差都初始化為 $$2.0$$:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/65.png" alt="1" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/66.png" alt="2" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/67.png" alt="3" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/68.png" alt="4" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/69.png" alt="5" />
成功了!這次神經(jīng)元的學(xué)習(xí)速度相當(dāng)快,跟我們預(yù)期的那樣。如果你觀測(cè)的足夠仔細(xì),你可以發(fā)現(xiàn)代價(jià)函數(shù)曲線要比二次代價(jià)函數(shù)訓(xùn)練前面部分要陡很多。正是交叉熵帶來的快速下降的坡度讓神經(jīng)元在處于誤差很大的情況下能夠逃脫出學(xué)習(xí)緩慢的困境,這才是我們直覺上所期待的效果。
我們還沒有提及關(guān)于學(xué)習(xí)率的討論。剛開始使用二次代價(jià)函數(shù)的時(shí)候,我們使用了 $$\eta=0.15$$。在新例子中,我們還應(yīng)該使用同樣的學(xué)習(xí)率么?實(shí)際上,根據(jù)不同的代價(jià)函數(shù),我們不能夠直接去套用同樣的學(xué)習(xí)率。這好比蘋果和橙子的比較。對(duì)于這兩種代價(jià)函數(shù),我只是通過簡(jiǎn)單的實(shí)驗(yàn)來找到一個(gè)能夠讓我們看清楚變化過程的學(xué)習(xí)率的值。盡管我不愿意提及,但如果你仍然好奇,這個(gè)例子中我使用了 $$\eta=0.005$$。
你可能會(huì)反對(duì)說,上面學(xué)習(xí)率的改變使得上面的圖失去了意義。誰(shuí)會(huì)在意當(dāng)學(xué)習(xí)率的選擇是任意挑選的時(shí)候神經(jīng)元學(xué)習(xí)的速度?!這樣的反對(duì)其實(shí)沒有抓住重點(diǎn)。上面的圖例不是想討論學(xué)習(xí)的絕對(duì)速度。而是想研究學(xué)習(xí)速度的變化情況。特別地,當(dāng)我們使用二次代價(jià)函數(shù)時(shí),學(xué)習(xí)在神經(jīng)元犯了明顯的錯(cuò)誤的時(shí)候卻比學(xué)習(xí)快接近真實(shí)值的時(shí)候緩慢;而使用交叉熵學(xué)習(xí)正是在神經(jīng)元犯了明顯錯(cuò)誤的時(shí)候速度更快。這些現(xiàn)象并不是因?yàn)閷W(xué)習(xí)率的改變?cè)斐傻摹?/p>
我們已經(jīng)研究了一個(gè)神經(jīng)元的交叉熵。不過,將其推廣到多個(gè)神經(jīng)元的多層神經(jīng)網(wǎng)絡(luò)上也是很簡(jiǎn)單的。特別地,假設(shè) $$y=y_1,y_2,...$$ 是輸出神經(jīng)元上的目標(biāo)值,而 $$a_1^L,a_2^L,...$$是實(shí)際輸出值。那么我們定義交叉熵如下
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/70.png" alt="" />
除了這里需要對(duì)所有輸出神經(jīng)元進(jìn)行求和外,這個(gè)其實(shí)和我們?cè)缜暗墓?57)一樣的。這里不會(huì)給出一個(gè)推算的過程,但需要說明的時(shí)使用公式(63)確實(shí)會(huì)在很多的神經(jīng)網(wǎng)絡(luò)中避免學(xué)習(xí)的緩慢。如果你感興趣,你可以嘗試一下下面問題的推導(dǎo)。
那么我們應(yīng)該在什么時(shí)候用交叉熵來替換二次代價(jià)函數(shù)?實(shí)際上,如果在輸出神經(jīng)元使用 sigmoid 激活函數(shù)時(shí),交叉熵一般都是更好的選擇。為什么?考慮一下我們初始化網(wǎng)絡(luò)的時(shí)候通常使用某種隨機(jī)方法??赡軙?huì)發(fā)生這樣的情況,這些初始選擇會(huì)對(duì)某些訓(xùn)練輸入誤差相當(dāng)明顯——比如說,目標(biāo)輸出是 $$1$$,而實(shí)際值是 $$0$$,或者完全反過來。如果我們使用二次代價(jià)函數(shù),那么這就會(huì)導(dǎo)致學(xué)習(xí)速度的下降。它并不會(huì)完全終止學(xué)習(xí)的過程,因?yàn)檫@些權(quán)重會(huì)持續(xù)從其他的樣本中進(jìn)行學(xué)習(xí),但是顯然這不是我們想要的效果。
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/71.png" alt="" />
而其中 $$?[y\ln y+(1?y)\ln (1?y)]$$ 有時(shí)候被稱為 二元熵
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/72.png" alt="" />
項(xiàng) $$\sigma'(z_j^L)$$ 會(huì)在一個(gè)輸出神經(jīng)元困在錯(cuò)誤值時(shí)導(dǎo)致學(xué)習(xí)速度的下降。證明對(duì)于交叉熵代價(jià)函數(shù),針對(duì)一個(gè)訓(xùn)練樣本 $$x$$ 的輸出誤差 $$\delta^L$$為
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/73.png" alt="" />
使用這個(gè)表達(dá)式來證明關(guān)于輸出層的權(quán)重的偏導(dǎo)數(shù)為
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/74.png" alt="" />
這里 $$\sigma'(z_j^L)$$ 就消失了,所以交叉熵避免了學(xué)習(xí)緩慢的問題,不僅僅是在一個(gè)神經(jīng)元上,而且在多層多元網(wǎng)絡(luò)上都起作用。這個(gè)分析過程稍作變化對(duì)偏差也是一樣的。如果你對(duì)這個(gè)還不確定,那么請(qǐng)仔細(xì)研讀一下前面的分析。
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/75.png" alt="" />
類似于前一個(gè)問題,使用這個(gè)表達(dá)式來證明關(guān)于輸出層的權(quán)重和偏差的偏導(dǎo)數(shù)為
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/76.png" alt="" />
這表明如果輸出神經(jīng)元是線性的那么二次代價(jià)函數(shù)不再會(huì)導(dǎo)致學(xué)習(xí)速度下降的問題。在此情形下,二次代價(jià)函數(shù)就是一種合適的選擇。
交叉熵很容易作為使用梯度下降和反向傳播方式進(jìn)行模型學(xué)習(xí)的一部分來實(shí)現(xiàn)。我們將會(huì)在下一章進(jìn)行對(duì)前面的程序 network.py 的改進(jìn)。新的程序?qū)懺?network2.py 中,不僅使用了交叉熵,還有本章中介紹的其他的技術(shù)?,F(xiàn)在我們看看新的程序在進(jìn)行 MNIST 數(shù)字分類問題上的表現(xiàn)。如在第一章中那樣,我們會(huì)使用一個(gè)包含 $$30$$ 個(gè)隱藏元的網(wǎng)絡(luò),而 minibatch 的大小也設(shè)置為 $$10$$。我們將學(xué)習(xí)率設(shè)置為 $$\eta=0.5$$ 然后訓(xùn)練 $$30$$ 回合。network2.py 的接口和 network.py 稍微不同,但是過程還是很清楚的。你可以使用如 help(network2.Network.SGD) 這樣的命令來檢查對(duì)應(yīng)的文檔。
>>> 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() 命令使用和第一章介紹的同樣的方式來進(jìn)行權(quán)重和偏差的初始化。運(yùn)行上面的代碼我們得到了一個(gè) 95.49% 準(zhǔn)確度的網(wǎng)絡(luò)。這跟我們?cè)诘谝徽轮惺褂枚未鷥r(jià)函數(shù)得到的結(jié)果相當(dāng)接近了,95.42%。
同樣也來試試使用 $$100$$ 個(gè)隱藏元的交叉熵及其他參數(shù)保持不變的情況。在這個(gè)情形下,我們獲得了 96.82% 的準(zhǔn)確度。相比第一章使用二次代價(jià)函數(shù)的結(jié)果 96.59%,這有一定的提升。這看起來是一個(gè)小小的變化,但是考慮到誤差率已經(jīng)從 3.41% 下降到 3.18%了。我們已經(jīng)消除了原誤差的 $$1/14$$。這其實(shí)是可觀的改進(jìn)。
令人振奮的是交叉熵代價(jià)函數(shù)給了我們類似的或者更好的結(jié)果。然而,這些結(jié)果并沒有能夠確定性地證明交叉熵是更好的選擇。原因在于我已經(jīng)在選擇諸如學(xué)習(xí)率,minibatch 大小等等這樣的超參數(shù)上做出了一些努力。為了讓這些提升更具說服力,我們需要進(jìn)行對(duì)超參數(shù)進(jìn)行深度的優(yōu)化。當(dāng)然,這些結(jié)果都挺好的,強(qiáng)化了我們?cè)缦汝P(guān)于交叉熵優(yōu)于二次代價(jià)的理論論斷。
這只是本章后面的內(nèi)容和整本書剩余內(nèi)容中的更為一般的模式的一部分。我們將給出一個(gè)新的技術(shù),然后進(jìn)行嘗試,隨后獲得“提升的”結(jié)果。當(dāng)然,看到這些進(jìn)步是很好的。但是這些提升的解釋一般來說都困難重重。在進(jìn)行了大量工作來優(yōu)化所有其他的超參數(shù),使得提升真的具有說服力。工作量很大,需要大量的計(jì)算能力,我們也不會(huì)進(jìn)行這樣耗費(fèi)的調(diào)查。相反,我采用上面進(jìn)行的那些不正式的測(cè)試來達(dá)成目標(biāo)。所以你要記住這樣的測(cè)試缺少確定性的證明,需要注意那些使得論斷失效的信號(hào)。
至此,我們已經(jīng)花了大量篇幅介紹交叉熵。為何對(duì)一個(gè)只能給出一點(diǎn)點(diǎn)性能提升的技術(shù)上花費(fèi)這么多的精力?后面,我們會(huì)看到其他的技術(shù)——規(guī)范化,會(huì)帶來更大的提升效果。所以為何要這么細(xì)致地討論交叉熵?部分原因在于交叉熵是一種廣泛使用的代價(jià)函數(shù),值得深入理解。但是更加重要的原因是神經(jīng)元的飽和是神經(jīng)網(wǎng)絡(luò)中一個(gè)關(guān)鍵的問題,整本書都會(huì)不斷回歸到這個(gè)問題上。因此我現(xiàn)在深入討論交叉熵就是因?yàn)檫@是一種開始理解神經(jīng)元飽和和如何解決這個(gè)問題的很好的實(shí)驗(yàn)。
我們對(duì)于交叉熵的討論聚焦在代數(shù)分析和代碼實(shí)現(xiàn)。這雖然很有用,但是也留下了一個(gè)未能回答的更加寬泛的概念上的問題,如:交叉熵究竟表示什么?存在一些直覺上的思考交叉熵的方法么?我們?nèi)绾蜗氲竭@個(gè)概念?
讓我們從最后一個(gè)問題開始回答:什么能夠激發(fā)我們想到交叉熵?假設(shè)我們發(fā)現(xiàn)學(xué)習(xí)速度下降了,并理解其原因是因?yàn)樵诠?55)(56)中的 $$\sigma'(z)$$ 那一項(xiàng)。在研究了這些公式后,我們可能就會(huì)想到選擇一個(gè)不包含 $$\sigma'(z)$$ 的代價(jià)函數(shù)。所以,這時(shí)候?qū)σ粋€(gè)訓(xùn)練樣本 $$x$$,代價(jià)函數(shù)是 $$C=C_x$$ 就滿足:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/77.png" alt="" />
如果我們選擇的代價(jià)函數(shù)滿足這些條件,那么同樣他們會(huì)擁有遇到明顯誤差時(shí)的學(xué)習(xí)速度越快這樣的特性。這也能夠解決學(xué)習(xí)速度下降的問題。實(shí)際上,從這些公式開始,現(xiàn)在就給你們看看若是跟隨自身的數(shù)學(xué)嗅覺推導(dǎo)出交叉熵的形式是可能的。我們來推一下,由鏈?zhǔn)椒▌t,我們有
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/78.png" alt="" />
使用 $$\sigma'(z)=\sigma(z)(1-\sigma(z))=a(1-a)$$,上個(gè)等式就變成
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/79.png" alt="" />
對(duì)比等式(72),我們有
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/80.png" alt="" />
對(duì)此方程關(guān)于 $$a$$ 進(jìn)行積分,得到
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/81.png" alt="" />
其中 $$constant$$ 是積分常量。這是一個(gè)單獨(dú)的訓(xùn)練樣本 $$x$$ 對(duì)代價(jià)函數(shù)的貢獻(xiàn)。為了得到整個(gè)的代價(jià)函數(shù),我們需要對(duì)所有的訓(xùn)練樣本進(jìn)行平均,得到了
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/82.png" alt="" />
而這里的常量就是所有單獨(dú)的常量的平均。所以我們看到方程(71)和(72)唯一確定了交叉熵的形式,并加上了一個(gè)常量的項(xiàng)。這個(gè)交叉熵并不是憑空產(chǎn)生的。而是一種我們以自然和簡(jiǎn)單的方法獲得的結(jié)果。
那么交叉熵直覺含義又是什么?我們?nèi)绾慰创??深入解釋這一點(diǎn)會(huì)將我們帶到一個(gè)不大愿意討論的領(lǐng)域。然而,還是值得提一下,有一種源自信息論的解釋交叉熵的標(biāo)準(zhǔn)方式。粗略地說,交叉熵是驚奇的度量(measure of surprise)。特別地,我們的神經(jīng)元想要要計(jì)算函數(shù) $$x\rightarrow y=y(x)$$。但是,它用函數(shù)$$x\rightarrow a=a(x)$$ 進(jìn)行了替換。假設(shè)我們將 $$a$$ 想象成我們神經(jīng)元估計(jì) $$y = 1$$ 概率,而 $$1-a$$ 則是 $$y=0$$ 的概率。如果輸出我們期望的結(jié)果,驚奇就會(huì)小一點(diǎn);反之,驚奇就大一些。當(dāng)然,我這里沒有嚴(yán)格地給出“驚奇”到底意味著什么,所以看起來像在夸夸奇談。但是實(shí)際上,在信息論中有一種準(zhǔn)確的方式來定義驚奇究竟是什么。不過,我也不清楚在網(wǎng)絡(luò)上,哪里有好的,短小的自包含對(duì)這個(gè)內(nèi)容的討論。但如果你要深入了解的話,Wikipedia 包含一個(gè)簡(jiǎn)短的總結(jié),這會(huì)指引你正確地探索這個(gè)領(lǐng)域。而更加細(xì)節(jié)的內(nèi)容,你們可以閱讀Cover and Thomas的第五章涉及 Kraft 不等式的有關(guān)信息論的內(nèi)容。
本章,我們大多數(shù)情況會(huì)使用交叉熵來解決學(xué)習(xí)緩慢的問題。但是,我希望簡(jiǎn)要介紹一下基于 softmax 神經(jīng)元層的解決這個(gè)問題的另一種觀點(diǎn)。我們不會(huì)實(shí)際在剩下的章節(jié)中使用 softmax 層,所以你如果趕時(shí)間,就可以跳到下一個(gè)小節(jié)了。不過,softmax 仍然有其重要價(jià)值,一方面它本身很有趣,另一方面,因?yàn)槲覀儠?huì)在第六章在對(duì)深度神經(jīng)網(wǎng)絡(luò)的討論中使用 softmax 層。
softmax 的想法其實(shí)就是為神經(jīng)網(wǎng)絡(luò)定義一種新式的輸出層。開始時(shí)和 sigmoid 層一樣的,首先計(jì)算帶權(quán)輸入 $$z_j^L = \sumk w{jk}^La_k^{L-1}+b_j^L$$。不過,這里我們不會(huì)使用 sigmoid 函數(shù)來獲得輸出。而是,會(huì)應(yīng)用一種叫做 softmax 函數(shù)在 $$z_j^L$$ 上。根據(jù)這個(gè)函數(shù),激活值 $$a_j^L$$ 就是
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/83.png" alt="" />
其中,分母是對(duì)所有的輸出神經(jīng)元進(jìn)行求和。
如果你不習(xí)慣這個(gè)函數(shù),方程(78)可能看起來會(huì)比較難理解。因?yàn)閷?duì)于使用這個(gè)函數(shù)的原因你不清楚。為了更好地理解這個(gè)公式,假設(shè)我們有一個(gè)包含四個(gè)輸出神經(jīng)元的神經(jīng)網(wǎng)絡(luò),對(duì)應(yīng)四個(gè)帶權(quán)輸入,表示為 $$z_1^L, z_2^L, z_3^L, z_4^L$$。下面的例子可以進(jìn)行對(duì)應(yīng)權(quán)值的調(diào)整,并給出對(duì)應(yīng)的激活值的圖像??梢酝ㄟ^固定其他值,來看看改變 $$z_4^L$$ 的值會(huì)產(chǎn)生什么樣的影響:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/84.png" alt="1" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/85.png" alt="2" />
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/86.png" alt="3" />
這里給出了三個(gè)選擇的圖像,建議去原網(wǎng)站體驗(yàn)
在我們?cè)黾?$$z_4^L$$ 的時(shí)候,你可以看到對(duì)應(yīng)激活值 $$a_4^L$$ 的增加,而其他的激活值就在下降。類似地,如果你降低 $$z_4^L$$ 那么 $$a_4^L$$ 就隨之下降。實(shí)際上,如果你仔細(xì)看,你會(huì)發(fā)現(xiàn)在兩種情形下,其他激活值的整個(gè)改變恰好填補(bǔ)了 $$a_4^L$$ 的變化的空白。原因很簡(jiǎn)單,根據(jù)定義,輸出的激活值加起來正好為 $$1$$,使用公式(78)我們可以證明:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/87.png" alt="" />
所以,如果 $$a_4^L$$ 增加,那么其他輸出激活值肯定會(huì)總共下降相同的量,來保證和式為 $$1$$。當(dāng)然,類似的結(jié)論對(duì)其他的激活函數(shù)也需要滿足。
方程(78)同樣保證輸出激活值都是正數(shù),因?yàn)橹笖?shù)函數(shù)是正的。將這兩點(diǎn)結(jié)合起來,我們看到 softmax 層的輸出是一些相加為 $$1$$ 正數(shù)的集合。換言之,softmax 層的輸出可以被看做是一個(gè)概率分布。
這樣的效果很令人滿意。在很多問題中,將這些激活值作為網(wǎng)絡(luò)對(duì)于某個(gè)輸出正確的概率的估計(jì)非常方便。所以,比如在 MNIST 分類問題中,我們可以將 $$a_j^L$$ 解釋成網(wǎng)絡(luò)估計(jì)正確數(shù)字分類為 $$j$$ 的概率。
對(duì)比一下,如果輸出層是 sigmoid 層,那么我們肯定不能假設(shè)激活值形成了一個(gè)概率分布。我不會(huì)證明這一點(diǎn),但是源自 sigmoid 層的激活值是不能夠形成一種概率分布的一般形式的。所以使用 sigmoid 輸出層,我們沒有關(guān)于輸出的激活值的簡(jiǎn)單的解釋。
我們現(xiàn)在開始體會(huì)到 softmax 函數(shù)的形式和行為特征了。來回顧一下:在公式(78)中的指數(shù)函數(shù)確保了所有的輸出激活值是正數(shù)。然后分母的求和又保證了 softmax 的輸出和為 $$1$$。所以這個(gè)特定的形式不再像之前那樣難以理解了:反而是一種確保輸出激活值形成一個(gè)概率分布的自然的方式。你可以將其想象成一種重新調(diào)節(jié) $$z_j^L$$ 的方法,然后將這個(gè)結(jié)果整合起來構(gòu)成一個(gè)概率分布。
學(xué)習(xí)緩慢問題:我們現(xiàn)在已經(jīng)對(duì) softmax 神經(jīng)元有了一定的認(rèn)識(shí)。但是我們還沒有看到 softmax 會(huì)怎么樣解決學(xué)習(xí)緩慢問題。為了理解這點(diǎn),先定義一個(gè) log-likelihood 代價(jià)函數(shù)。我們使用 $$x$$ 表示訓(xùn)練輸入,$$y$$ 表示對(duì)應(yīng)的目標(biāo)輸出。然后關(guān)聯(lián)這個(gè)訓(xùn)練輸入樣本的 log-likelihood 代價(jià)函數(shù)就是
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/88.png" alt="" />
所以,如果我們訓(xùn)練的是 MNIST 圖像,輸入為 $$7$$ 的圖像,那么對(duì)應(yīng)的 log-likelihood 代價(jià)就是 $$-\ln a_7^L$$。看看這個(gè)直覺上的含義,想想當(dāng)網(wǎng)絡(luò)表現(xiàn)很好的時(shí)候,也就是確認(rèn)輸入為 $$7$$ 的時(shí)候。這時(shí),他會(huì)估計(jì)一個(gè)對(duì)應(yīng)的概率 $$a_7^L$$ 跟 $$1$$ 非常接近,所以代價(jià) $$-\ln a_7^L$$ 就會(huì)很小。反之,如果網(wǎng)絡(luò)的表現(xiàn)糟糕時(shí),概率 $$a_7^L$$ 就變得很小,代價(jià) $$-\ln a_7^L$$ 隨之增大。所以 log-likelihood 代價(jià)函數(shù)也是滿足我們期待的代價(jià)函數(shù)的條件的。
那關(guān)于學(xué)習(xí)緩慢問題呢?為了分析它,回想一下學(xué)習(xí)緩慢的關(guān)鍵就是量 $$\partial C/\partial w_{jk}^L$$ 和 $$\partial C/\partial b_j^L$$ 的變化情況。我不會(huì)顯式地給出詳細(xì)的推導(dǎo)——請(qǐng)你們自己去完成這個(gè)過程——但是會(huì)給出一些關(guān)鍵的步驟:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/89.png" alt="" />
請(qǐng)注意這里的表示上的差異,這里的 $$y$$ 和之前的目標(biāo)輸出值不同,是離散的向量表示,對(duì)應(yīng)位的值為 $$1$$,而其他為 $$0$$。 這些方程其實(shí)和我們前面對(duì)交叉熵得到的類似。就拿方程(82) 和 (67) 比較。盡管后者我對(duì)整個(gè)訓(xùn)練樣本進(jìn)行了平均,不過形式還是一致的。而且,正如前面的分析,這些表達(dá)式確保我們不會(huì)遇到學(xué)習(xí)緩慢的問題。實(shí)際上,將 softmax 輸出層和 log-likelihood 組合對(duì)照 sigmoid 輸出層和交叉熵的組合類比著看是非常有用的。
有了這樣的相似性,你會(huì)使用哪一種呢?實(shí)際上,在很多應(yīng)用場(chǎng)景中,這兩種方式的效果都不錯(cuò)。本章剩下的內(nèi)容,我們會(huì)使用 sigmoid 輸出層和交叉熵的組合。后面,在第六章中,我們有時(shí)候會(huì)使用 softmax 輸出層和 log-likelihood 的則和。切換的原因就是為了讓我們的網(wǎng)絡(luò)和某些在具有影響力的學(xué)術(shù)論文中的形式更為相似。作為一種更加通用的視角,softmax 加上 log-likelihood 的組合更加適用于那些需要將輸出激活值解釋為概率的場(chǎng)景。當(dāng)然這不總是合理的,但是在諸如 MNIST 這種有著不重疊的分類問題上確實(shí)很有用。
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/90.png" alt="" />
其中 $$c$$ 是正的常量。注意 $$c=1$$ 對(duì)應(yīng)標(biāo)準(zhǔn)的 softmax 函數(shù)。但是如果我們使用不同的 $$c$$ 得到不同的函數(shù),其實(shí)最終的量的結(jié)果卻和原來的 softmax 差不多。特別地,證明輸出激活值也會(huì)形成一個(gè)概率分布。假設(shè)我們?cè)试S $$c$$ 足夠大,比如說 $$c\rightarrow \infty$$。那么輸出激活值 $$a_j^L$$ 的極限值是什么?在解決了這個(gè)問題后,你應(yīng)該能夠理解 $$c=1$$ 對(duì)應(yīng)的函數(shù)是一個(gè)最大化函數(shù)的 softened 版本。這就是 softmax 的來源。
這讓我聯(lián)想到 EM 算法,對(duì) k-Means 算法的一種推廣。
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/91.png" alt="" />
使用這個(gè)表達(dá)式,我們可以應(yīng)用反向傳播在采用了 softmax 輸出層和 log-likelihood 的網(wǎng)絡(luò)上。
諾貝爾獎(jiǎng)得主美籍意大利裔物理學(xué)家恩里科·費(fèi)米曾被問到他對(duì)一個(gè)同僚提出的嘗試解決一個(gè)重要的未解決物理難題的數(shù)學(xué)模型。模型和實(shí)驗(yàn)非常匹配,但是費(fèi)米卻對(duì)其產(chǎn)生了懷疑。他問模型中需要設(shè)置的自由參數(shù)有多少個(gè)。答案是“4”。費(fèi)米回答道:“我記得我的朋友約翰·馮·諾依曼過去常說,有四個(gè)參數(shù),我可以模擬一頭大象,而有五個(gè)參數(shù),我還能讓他卷鼻子?!?/p>
這里,其實(shí)是說擁有大量的自由參數(shù)的模型能夠描述特別神奇的現(xiàn)象。即使這樣的模型能夠很好的擬合已有的數(shù)據(jù),但并不表示是一個(gè)好模型。因?yàn)檫@可能只是因?yàn)槟P椭凶銐虻淖杂啥仁沟盟梢悦枋鰩缀跛薪o定大小的數(shù)據(jù)集,不需要對(duì)現(xiàn)象的本質(zhì)有創(chuàng)新的認(rèn)知。所以發(fā)生這種情形時(shí),模型對(duì)已有的數(shù)據(jù)會(huì)表現(xiàn)的很好,但是對(duì)新的數(shù)據(jù)很難泛化。對(duì)一個(gè)模型真正的測(cè)驗(yàn)就是它對(duì)沒有見過的場(chǎng)景的預(yù)測(cè)能力。
費(fèi)米和馮·諾依曼對(duì)有四個(gè)參數(shù)的模型就開始懷疑了。我們用來對(duì) MNIST 數(shù)字分類的 $$30$$ 個(gè)隱藏神經(jīng)元神經(jīng)網(wǎng)絡(luò)擁有將近 $$24,000$$ 個(gè)參數(shù)!當(dāng)然很多。我們有 $$100$$ 個(gè)隱藏元的網(wǎng)絡(luò)擁有將近 $$80,000$$ 個(gè)參數(shù),而目前最先進(jìn)的深度神經(jīng)網(wǎng)絡(luò)包含百萬(wàn)級(jí)或者十億級(jí)的參數(shù)。我們應(yīng)當(dāng)信賴這些結(jié)果么?
讓我們將問題暴露出來,通過構(gòu)造一個(gè)網(wǎng)絡(luò)泛化能力很差的例子。我們的網(wǎng)絡(luò)有 $$30$$ 個(gè)隱藏神經(jīng)元,共 $$23,860$$ 個(gè)參數(shù)。但是我們不會(huì)使用所有 $$50,000$$ 幅訓(xùn)練圖像。相反,我們只使用前 $$1000$$ 幅圖像。使用這個(gè)受限的集合,會(huì)讓泛化的問題突顯。按照同樣的方式,使用交叉熵代價(jià)函數(shù),學(xué)習(xí)率設(shè)置為 $$\eta=0.5$$ 而 minibatch 大小設(shè)置為 $$10$$。不過這里我們訓(xùn)練回合設(shè)置為 $$400$$,比前面的要多很多,因?yàn)槲覀冎挥昧松倭康挠?xùn)練樣本。我們現(xiàn)在使用 network2 來研究代價(jià)函數(shù)改變的情況:
>>> 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[:1000], 400, 10, 0.5, evaluation_data=test_data,
... monitor_evaluation_accuracy=True, monitor_training_cost=True)
使用上面的結(jié)果,我們可以畫出代價(jià)函數(shù)變化的情況:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/92.png" alt="" />
這看起來令人振奮,因?yàn)榇鷥r(jià)函數(shù)有一個(gè)光滑的下降,跟我們預(yù)期一致。注意,我只是展示了 $$200$$ 到 $$399$$ 回合的情況。這給出了很好的近距離理解訓(xùn)練后期的情況,這也是出現(xiàn)有趣現(xiàn)象的地方。
讓我們看看分類準(zhǔn)確度在測(cè)試集上的表現(xiàn):
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/93.png" alt="" />
這里我還是聚焦到了后面的過程。 在前 $$200$$ 回合(圖中沒有顯示)準(zhǔn)確度提升到了 82%。然后學(xué)習(xí)逐漸變緩。最終,在 $$280$$ 回合左右分類準(zhǔn)確度就停止了增長(zhǎng)。后面的回合,僅僅看到了在 $$280$$ 回合準(zhǔn)確度周圍隨機(jī)的震蕩。將這幅圖和前面的圖進(jìn)行對(duì)比,和訓(xùn)練數(shù)據(jù)相關(guān)的代價(jià)函數(shù)持續(xù)平滑下降。如果我們只看哪個(gè)代價(jià),我們會(huì)發(fā)現(xiàn)模型的表現(xiàn)變得“更好”。但是測(cè)試準(zhǔn)確度展示了提升只是一種假象。就像費(fèi)米不大喜歡的那個(gè)模型一樣,我們的網(wǎng)絡(luò)在 $$280$$ 回合后就不在能夠繁華到測(cè)試數(shù)據(jù)上。所以這種學(xué)習(xí)不大有用。也可以說網(wǎng)絡(luò)在 $$280$$ 后就過匹配(或者過度訓(xùn)練)了。
你可能想知道這里的問題是不是由于我們看的是訓(xùn)練數(shù)據(jù)的代價(jià),而對(duì)比的卻是測(cè)試數(shù)據(jù)上的分類準(zhǔn)確度導(dǎo)致的。換言之,可能我們這里在進(jìn)行蘋果和橙子的對(duì)比。如果我們比較訓(xùn)練數(shù)據(jù)上的代價(jià)和測(cè)試數(shù)據(jù)上的代價(jià),會(huì)發(fā)生什么,我們是在比較類似的度量么?或者可能我們可以比較在兩個(gè)數(shù)據(jù)集上的分類準(zhǔn)確度???實(shí)際上,不管我們使用什么度量的方式盡管,細(xì)節(jié)會(huì)變化,但本質(zhì)上都是一樣的。 讓我們來看看測(cè)試數(shù)據(jù)集上的代價(jià)變化情況:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/94.png" alt="" />
我們可以看到測(cè)試集上的代價(jià)在 $$15$$ 回合前一直在提升,隨后越來越差,盡管訓(xùn)練數(shù)據(jù)機(jī)上的代價(jià)表現(xiàn)是越來越好的。這其實(shí)是另一種模型過匹配的標(biāo)志。盡管,這里帶來了關(guān)于我們應(yīng)當(dāng)將 $$15$$ 還是 $$280$$ 回合當(dāng)作是過匹配占主導(dǎo)的時(shí)間點(diǎn)的困擾。從一個(gè)實(shí)踐角度,我們真的關(guān)心的是提升測(cè)試數(shù)據(jù)集上的分類準(zhǔn)確度,而測(cè)試集合上的代價(jià)不過是分類準(zhǔn)確度的一個(gè)反應(yīng)。所以更加合理的選擇就是將 $$280$$ 看成是過匹配開始占統(tǒng)治地位的時(shí)間點(diǎn)。
另一個(gè)過匹配的信號(hào)在訓(xùn)練數(shù)據(jù)上的分類準(zhǔn)確度上也能看出來:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/95.png" alt="" />
準(zhǔn)確度一直在提升接近 100%。也就是說,我們的網(wǎng)絡(luò)能夠正確地對(duì)所有 $$1000$$ 幅圖像進(jìn)行分類!而在同時(shí),我們的測(cè)試準(zhǔn)確度僅僅能夠達(dá)到 82.27%。所以我們的網(wǎng)絡(luò)實(shí)際上在學(xué)習(xí)訓(xùn)練數(shù)據(jù)集的特例,而不是能夠一般地進(jìn)行識(shí)別。我們的網(wǎng)絡(luò)幾乎是在單純記憶訓(xùn)練集合,而沒有對(duì)數(shù)字本質(zhì)進(jìn)行理解能夠泛化到測(cè)試數(shù)據(jù)集上。
過匹配是神經(jīng)網(wǎng)絡(luò)的一個(gè)主要問題。這在現(xiàn)代網(wǎng)絡(luò)中特別正常,因?yàn)榫W(wǎng)絡(luò)權(quán)重和偏差數(shù)量巨大。為了高效地訓(xùn)練,我們需要一種檢測(cè)過匹配是不是發(fā)生的技術(shù),這樣我們不會(huì)過度訓(xùn)練。并且我們也想要找到一些技術(shù)來降低過匹配的影響。
檢測(cè)過匹配的明顯方法是使用上面的方法——跟蹤測(cè)試數(shù)據(jù)集合上的準(zhǔn)確度隨訓(xùn)練變化情況。如果我們看到測(cè)試數(shù)據(jù)上的準(zhǔn)確度不再提升,那么我們就停止訓(xùn)練。當(dāng)然,嚴(yán)格地說,這其實(shí)并非是過匹配的一個(gè)必要現(xiàn)象,因?yàn)闇y(cè)試集和訓(xùn)練集上的準(zhǔn)確度可能會(huì)同時(shí)停止提升。當(dāng)然,采用這樣的方式是可以阻止過匹配的。
實(shí)際上,我們會(huì)使用這種方式變形來試驗(yàn)。記得之前我們載入 MNIST 數(shù)據(jù)的時(shí)候有:
>>> import mnist_loader
>>> training_data, validation_data, test_data = \
... mnist_loader.load_data_wrapper()
到現(xiàn)在我們一直在使用 training_data 和 test_data,沒有用過 validation_data。validation_data 中包含了 $$10,000$$ 幅數(shù)字圖像,這些圖像和訓(xùn)練數(shù)據(jù)集中的 $$50,000$$ 幅圖像以及測(cè)試數(shù)據(jù)集中的 $$10,000$$ 幅都不相同。我們會(huì)使用 validation_data 來防止過匹配。我們會(huì)使用和上面應(yīng)用在 test_data 的策略。我們每個(gè)回合都計(jì)算在 validation_data 上的分類準(zhǔn)確度。一旦分類準(zhǔn)確度已經(jīng)飽和,就停止訓(xùn)練。這個(gè)策略被稱為 提前停止(Early stopping)。當(dāng)然,實(shí)際應(yīng)用中,我們不會(huì)立即知道什么時(shí)候準(zhǔn)確度會(huì)飽和。相反,我們會(huì)一直訓(xùn)練知道我們確信準(zhǔn)確度已經(jīng)飽和。
這里需要一些判定標(biāo)準(zhǔn)來確定什么時(shí)候停止。在我前面的圖中,將 $$280$$ 回合看成是飽和的地方??赡苓@有點(diǎn)太悲觀了。因?yàn)樯窠?jīng)網(wǎng)絡(luò)有時(shí)候會(huì)訓(xùn)練過程中處在一個(gè)平原期,然后又開始提升。如果在 $$400$$ 回合后,性能又開始提升(也許只是一些少量提升),那我也不會(huì)詫異。所以,在提前停止中采取一點(diǎn)激進(jìn)的策略也是可以的。
為何要使用 validation_data 來替代 test_data 防止過匹配問題?實(shí)際上,這是一個(gè)更為一般的策略的一部分,這個(gè)一般的策略就是使用 validation_data 來衡量不同的超參數(shù)(如訓(xùn)練回合,學(xué)習(xí)率,最好的網(wǎng)絡(luò)架構(gòu)等等)的選擇的效果。我們使用這樣方法來找到超參數(shù)的合適值。因此,盡管到現(xiàn)在我并沒有提及這點(diǎn),但其實(shí)本書前面已經(jīng)稍微介紹了一些超參數(shù)選擇的方法。
當(dāng)然,這對(duì)于我們前面關(guān)于 validation_data 取代 test_data 來防止過匹配的原因仍舊沒有回答。實(shí)際上,有一個(gè)更加一般的問題,就是為何用validation_data 取代 test_data 來設(shè)置更好的超參數(shù)?為了理解這點(diǎn),想想當(dāng)設(shè)置超參數(shù)時(shí),我們想要嘗試許多不同的超參數(shù)選擇。如果我們?cè)O(shè)置超參數(shù)是基于 test_data 的話,可能最終我們就會(huì)得到過匹配于 test_data 的超參數(shù)。也就是說,我們可能會(huì)找到那些 符合 test_data 特點(diǎn)的超參數(shù),但是網(wǎng)絡(luò)的性能并不能夠泛化到其他數(shù)據(jù)集合上。我們借助 validation_data 來克服這個(gè)問題。然后一旦獲得了想要的超參數(shù),最終我們就使用 test_data 進(jìn)行準(zhǔn)確度測(cè)量。這給了我們?cè)?test_data 上結(jié)果是一個(gè)網(wǎng)絡(luò)泛化能力真正的度量方式的信心。換言之,你可以將驗(yàn)證集看成是一種特殊的訓(xùn)練數(shù)據(jù)集能夠幫助我們學(xué)習(xí)好的超參數(shù)。這種尋找好的超參數(shù)的觀點(diǎn)有時(shí)候被稱為 hold out 方法,因?yàn)?validation_data 是從訓(xùn)練集中保留出來的一部分。
在實(shí)際應(yīng)用中,甚至在衡量了測(cè)試集上的性能后,我們可能也會(huì)改變想法并去嘗試另外的方法——也許是一種不同的網(wǎng)絡(luò)架構(gòu)——這將會(huì)引入尋找新的超參數(shù)的的過程。如果我們這樣做,難道不會(huì)產(chǎn)生過匹配于 test_data 的困境么?我們是不是需要一種潛在無(wú)限大的數(shù)據(jù)集的回歸,這樣才能夠確信模型能夠泛化?去除這樣的疑惑其實(shí)是一個(gè)深刻而困難的問題。但是對(duì)實(shí)際應(yīng)用的目標(biāo),我們不會(huì)擔(dān)心太多。相反,我們會(huì)繼續(xù)采用基于 training_data, validation_data, and test_data 的基本 hold out 方法。
我們已經(jīng)研究了在使用 $$1,000$$ 幅訓(xùn)練圖像時(shí)的過匹配問題。那么如果我們使用所有的訓(xùn)練數(shù)據(jù)會(huì)發(fā)生什么?我們會(huì)保留所有其他的參數(shù)都一樣($$30$$ 個(gè)隱藏元,學(xué)習(xí)率 $$0.5$$,mini-batch 規(guī)模為 $$10$$),但是訓(xùn)練回合為 $$30$$ 次。下圖展示了分類準(zhǔn)確度在訓(xùn)練和測(cè)試集上的變化情況。注意我們使用的測(cè)試數(shù)據(jù),而不是驗(yàn)證集合,為了讓結(jié)果看起來和前面的圖更方便比較。
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/96.png" alt="" />
如你所見,測(cè)試集和訓(xùn)練集上的準(zhǔn)確度相比我們使用 $$1,000$$ 個(gè)訓(xùn)練數(shù)據(jù)時(shí)相差更小。特別地,在訓(xùn)練數(shù)據(jù)上的最佳的分類準(zhǔn)確度 97.86% 只比測(cè)試集上的 95.33% 準(zhǔn)確度高一點(diǎn)點(diǎn)。而之前的例子中,這個(gè)差距是 17.73%!過匹配仍然發(fā)生了,但是已經(jīng)減輕了不少。我們的網(wǎng)絡(luò)從訓(xùn)練數(shù)據(jù)上更好地泛化到了測(cè)試數(shù)據(jù)上。一般來說,最好的降低過匹配的方式之一就是增加訓(xùn)練樣本的量。有了足夠的訓(xùn)練數(shù)據(jù),就算是一個(gè)規(guī)模非常大的網(wǎng)絡(luò)也不大容易過匹配。不幸的是,訓(xùn)練數(shù)據(jù)其實(shí)是很難或者很昂貴的資源,所以這不是一種太切實(shí)際的選擇。
增加訓(xùn)練樣本的數(shù)量是一種減輕過匹配的方法。還有其他的一下方法能夠減輕過匹配的程度么?一種可行的方式就是降低網(wǎng)絡(luò)的規(guī)模。然而,大的網(wǎng)絡(luò)擁有一種比小網(wǎng)絡(luò)更強(qiáng)的潛力,所以這里存在一種應(yīng)用冗余性的選項(xiàng)。
幸運(yùn)的是,還有其他的技術(shù)能夠緩解過匹配,即使我們只有一個(gè)固定的網(wǎng)絡(luò)和固定的訓(xùn)練集合。這種技術(shù)就是規(guī)范化。本節(jié),我會(huì)給出一種最為常用的規(guī)范化手段——有時(shí)候被稱為權(quán)重下降(weight decay)或者 L2 規(guī)范化。L2 規(guī)范化的想法是增加一個(gè)額外的項(xiàng)到代價(jià)函數(shù)上,這個(gè)項(xiàng)叫做 規(guī)范化 項(xiàng)。下面是規(guī)范化交叉熵:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/97.png" alt="" />
其中第一個(gè)項(xiàng)就是常規(guī)的交叉熵的表達(dá)式。第二個(gè)現(xiàn)在加入到就是所有權(quán)重的平方的和。然后使用一個(gè)因子 $$\lambda/2n$$ 進(jìn)行量化調(diào)整,其中 $$\lambda > 0$$ 可以成為 規(guī)范化參數(shù),而 $$n$$ 就是訓(xùn)練集合的大小。我們會(huì)在后面討論 $$\lambda$$ 的選擇策略。需要注意的是,規(guī)范化項(xiàng)里面并不包含偏差。這點(diǎn)我們后面也會(huì)在講述。
當(dāng)然,對(duì)其他的代價(jià)函數(shù)也可以進(jìn)行規(guī)范化,例如二次代價(jià)函數(shù)。類似的規(guī)范化的形式如下:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/98.png" alt="" />
兩者都可以寫成這樣:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/99.png" alt="" />
其中 $$C_0$$ 是原始的代價(jià)函數(shù)。
直覺地看,規(guī)范化的效果是讓網(wǎng)絡(luò)傾向于學(xué)習(xí)小一點(diǎn)的權(quán)重,其他的東西都一樣的。大的權(quán)重只有能夠給出代價(jià)函數(shù)第一項(xiàng)足夠的提升時(shí)才被允許。換言之,規(guī)范化可以當(dāng)做一種尋找小的權(quán)重和最小化原始的代價(jià)函數(shù)之間的折中。這兩部分之前相對(duì)的重要性就由 $$\lambda$$ 的值來控制了:$$\lambda$$ 越小,就偏向于最小化原始代價(jià)函數(shù),反之,傾向于小的權(quán)重。
現(xiàn)在,對(duì)于這樣的折中為何能夠減輕過匹配還不是很清楚!但是,實(shí)際表現(xiàn)表明了這點(diǎn)。我們會(huì)在下一節(jié)來回答這個(gè)問題。但現(xiàn)在,我們來看看一個(gè)規(guī)范化的確減輕過匹配的例子。
為了構(gòu)造這個(gè)例子,我們首先需要弄清楚如何將隨機(jī)梯度下降算法應(yīng)用在一個(gè)規(guī)范化的神經(jīng)網(wǎng)絡(luò)上。特別地,我們需要知道如何計(jì)算偏導(dǎo)數(shù) $$\partial C/\partial w$$ 和 $$\partial C/\partial b$$。對(duì)公式(87)進(jìn)行求偏導(dǎo)數(shù)得:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/100.png" alt="" />
$$\partial C_0/\partial w$$ 和 $$\partial C_0/\partial b$$ 可以通過反向傳播進(jìn)行計(jì)算,和上一章中的那樣。所以我們看到其實(shí)計(jì)算規(guī)范化的代價(jià)函數(shù)的梯度是很簡(jiǎn)單的:僅僅需要反向傳播,然后加上 $$\frac{\lambda}{n} w$$ 得到所有權(quán)重的偏導(dǎo)數(shù)。而偏差的偏導(dǎo)數(shù)就不要變化,所以梯度下降學(xué)習(xí)規(guī)則不會(huì)發(fā)生變化:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/101.png" alt="" />
權(quán)重的學(xué)習(xí)規(guī)則就變成:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/102.png" alt="" />
這其實(shí)和通常的梯度下降學(xué)習(xí)規(guī)則相同歐諾個(gè),除了乘了 $$1-\frac{\eta\lambda}{n}$$ 因子。這里就是權(quán)重下降的來源。粗看,這樣會(huì)導(dǎo)致權(quán)重會(huì)不斷下降到 $$0$$。但是實(shí)際不是這樣的,因?yàn)槿绻谠即鷥r(jià)函數(shù)中造成下降的話其他的項(xiàng)可能會(huì)讓權(quán)重增加。
好的,這就是梯度下降工作的原理。那么隨機(jī)梯度下降呢?正如在沒有規(guī)范化的隨機(jī)梯度下降中,我們可以通過平均 minibatch 中 $$m$$ 個(gè)訓(xùn)練樣本來估計(jì) $$\partial C_0/\partial w$$。因此,為了隨機(jī)梯度下降的規(guī)范化學(xué)習(xí)規(guī)則就變成(參考 方程(20))
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/103.png" alt="" />
其中后面一項(xiàng)是對(duì) minibatch 中的訓(xùn)練樣本 $$x$$ 進(jìn)行求和,而 $$C_x$$ 是對(duì)每個(gè)訓(xùn)練樣本的(無(wú)規(guī)范化的)代價(jià)。這其實(shí)和之前通常的隨機(jī)梯度下降的規(guī)則是一樣的,除了有一個(gè)權(quán)重下降的因子 $$1-\frac{\eta\lambda}{n}$$。最后,為了完備性,我給出偏差的規(guī)范化的學(xué)習(xí)規(guī)則。這當(dāng)然是和我們之前的非規(guī)范化的情形一致了(參考公式(32))
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/104.png" alt="" />
這里也是對(duì)minibatch 中的訓(xùn)練樣本 $$x$$ 進(jìn)行求和的。
讓我們看看規(guī)范化給網(wǎng)絡(luò)帶來的性能提升吧。這里還會(huì)使用有 $$30$$ 個(gè)隱藏神經(jīng)元、minibatch 為 $$10$$,學(xué)習(xí)率為 $$0.5$$,使用交叉熵的神經(jīng)網(wǎng)絡(luò)。然而,這次我們會(huì)使用規(guī)范化參數(shù)為 $$\lambda = 0.1$$。注意在代碼中,我們使用的變量名字為 lmbda,這是因?yàn)樵?Python 中 lambda 是關(guān)鍵字,尤其特定的作用。我也會(huì)使用 test_data,而不是 validation_data。不過嚴(yán)格地講,我們應(yīng)當(dāng)使用 validation_data的,因?yàn)榍懊嬉呀?jīng)講過了。這里我這樣做,是因?yàn)檫@會(huì)讓結(jié)果和非規(guī)范化的結(jié)果對(duì)比起來效果更加直接。你可以輕松地調(diào)整為 validation_data,你會(huì)發(fā)現(xiàn)有相似的結(jié)果。
>>> 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[:1000], 400, 10, 0.5,
... evaluation_data=test_data, lmbda = 0.1,
... monitor_evaluation_cost=True, monitor_evaluation_accuracy=True,
... monitor_training_cost=True, monitor_training_accuracy=True)
訓(xùn)練集上的代價(jià)函數(shù)持續(xù)下降,和前面無(wú)規(guī)范化的情況一樣的規(guī)律:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/105.png" alt="" />
但是這里測(cè)試集上的準(zhǔn)確度是隨著回合次數(shù)持續(xù)增加的:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/106.png" alt="" />
顯然,規(guī)范化的使用能夠解決過匹配的問題。而且,準(zhǔn)確度相當(dāng)搞了,最高處達(dá)到了 87.1%,相較于之前的 82.27%。因此,我們幾乎可以確信持續(xù)訓(xùn)練會(huì)有更加好的結(jié)果。實(shí)驗(yàn)起來,規(guī)范化讓網(wǎng)絡(luò)具有更好的泛化能力,顯著地減輕了過匹配的效果。
如果我們換成全部的訓(xùn)練數(shù)據(jù)進(jìn)行訓(xùn)練呢?當(dāng)然,我們之前已經(jīng)看到過匹配在大規(guī)模的數(shù)據(jù)上其實(shí)不是那么明顯了。那規(guī)范化能不能起到相應(yīng)的作用呢?保持超參數(shù)和之前一樣。不過我們這里需要改變規(guī)范化參數(shù)。原因在于訓(xùn)練數(shù)據(jù)的大小已經(jīng)從 $$n=1,000$$ 改成了 $$n=50,000$$,這個(gè)會(huì)改變權(quán)重下降因子 $$1-\frac{\eta\lambda}{n}$$。如果我們持續(xù)使用 $$\lambda = 0.1$$ 就會(huì)產(chǎn)生很小的權(quán)重下降,因此就將規(guī)范化的效果降低很多。我們通過將 $$\lambda = 5.0$$ 來補(bǔ)償這種下降。
好了,來訓(xùn)練網(wǎng)絡(luò),重新初始化權(quán)重:
>>> net.large_weight_initializer()
>>> net.SGD(training_data, 30, 10, 0.5,
... evaluation_data=test_data, lmbda = 5.0,
... monitor_evaluation_accuracy=True, monitor_training_accuracy=True)
我們得到:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/107.png" alt="" />
這個(gè)結(jié)果很不錯(cuò)。第一,我們?cè)跍y(cè)試集上的分類準(zhǔn)確度在使用規(guī)范化后有了提升,從 95.49% 到 96.49%。這是個(gè)很大的進(jìn)步。第二,我們可以看到在訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)上的結(jié)果之間的差距也更小了。這仍然是一個(gè)大的差距,不過我們已經(jīng)顯著得到了本質(zhì)上的降低過匹配的進(jìn)步。
最后,我們看看在使用 $$100$$ 個(gè)隱藏元和規(guī)范化參數(shù)為 $$\lambda = 5.0$$ 相應(yīng)的測(cè)試分類準(zhǔn)確度。我不會(huì)給出詳細(xì)分析,就為了有趣,來看看我們使用一些技巧(交叉熵函數(shù)和 $$L2$$ 規(guī)范化)能夠達(dá)到多高的準(zhǔn)確度。
>>> net = network2.Network([784, 100, 10], cost=network2.CrossEntropyCost)
>>> net.large_weight_initializer()
>>> net.SGD(training_data, 30, 10, 0.5, lmbda=5.0,
... evaluation_data=validation_data,
... monitor_evaluation_accuracy=True)
最終在驗(yàn)證集上的準(zhǔn)確度達(dá)到了 97.92%。這是比 $$30$$ 個(gè)隱藏元的較大飛躍。實(shí)際上,稍微改變一點(diǎn),$$60$$ 回合 $$\eta=0.1$$ 和 $$\lambda = 5.0$$。我們就突破了 98%,達(dá)到了 98.04% 的分類準(zhǔn)確度。對(duì)于 $$152$$ 行代碼這個(gè)效果還真不錯(cuò)!
我們討論了作為一種減輕過匹配和提高分類準(zhǔn)確度的方式的規(guī)范化技術(shù)。實(shí)際上,這不是僅有的好處。實(shí)踐表明,在使用不同的(隨機(jī))權(quán)重初始化進(jìn)行多次 MNIST 網(wǎng)絡(luò)訓(xùn)練的時(shí)候,我發(fā)現(xiàn)無(wú)規(guī)范化的網(wǎng)絡(luò)會(huì)偶然被限制住,明顯困在了代價(jià)函數(shù)的局部最優(yōu)值處。結(jié)果就是不同的運(yùn)行會(huì)給出相差很大的結(jié)果。對(duì)比看來,規(guī)范化的網(wǎng)絡(luò)能夠提供更容易復(fù)制的結(jié)果。
為何會(huì)這樣子?從經(jīng)驗(yàn)上看,如果代價(jià)函數(shù)是無(wú)規(guī)范化的,那么權(quán)重向量的長(zhǎng)度可能會(huì)增長(zhǎng),而其他的東西都保持一樣。隨著時(shí)間的推移,這個(gè)會(huì)導(dǎo)致權(quán)重向量變得非常大。所以會(huì)使得權(quán)重向困在差不多方向上,因?yàn)橛捎谔荻认陆档母淖儺?dāng)長(zhǎng)度很大的時(shí)候僅僅會(huì)在那個(gè)方向發(fā)生微小的變化。我相信這個(gè)現(xiàn)象讓學(xué)習(xí)算法更難有效地探索權(quán)重空間,最終導(dǎo)致很難找到代價(jià)函數(shù)的最優(yōu)值。
我們已經(jīng)看到了規(guī)范化在實(shí)踐中能夠減少過匹配了。這是令人振奮的,不過,這背后的原因還不得而知!通常的說法是:小的權(quán)重在某種程度上,意味著更低的復(fù)雜性,也就給出了一種更簡(jiǎn)單卻更強(qiáng)大的數(shù)據(jù)解釋,因此應(yīng)該優(yōu)先選擇。這雖然很簡(jiǎn)短,不過暗藏了一些可能看起來會(huì)令人困惑的因素。讓我們將這個(gè)解釋細(xì)化,認(rèn)真地研究一下。現(xiàn)在給一個(gè)簡(jiǎn)單的數(shù)據(jù)集,我們?yōu)槠浣⒛P停?/p>
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/108.png" alt="" />
這里我們其實(shí)在研究某種真實(shí)的現(xiàn)象,$$x$$ 和 $$y$$ 表示真實(shí)的數(shù)據(jù)。我們的目標(biāo)是訓(xùn)練一個(gè)模型來預(yù)測(cè) $$y$$ 關(guān)于 $$x$$ 的函數(shù)。我們可以使用神經(jīng)網(wǎng)絡(luò)來構(gòu)建這個(gè)模型,但是我們先來個(gè)簡(jiǎn)單的:用一個(gè)多項(xiàng)式來擬合數(shù)據(jù)。這樣做的原因其實(shí)是多項(xiàng)式相比神經(jīng)網(wǎng)絡(luò)能夠讓事情變得更加清楚。一旦我們理解了多項(xiàng)式的場(chǎng)景,對(duì)于神經(jīng)網(wǎng)絡(luò)可以如法炮制。現(xiàn)在,圖中有十個(gè)點(diǎn),我們就可以找到唯一的 $$9$$ 階多項(xiàng)式 $$y=a_0x^9 + a_1x^8 + ... + a_9$$ 來完全擬合數(shù)據(jù)。下面是多項(xiàng)式的圖像:
I won't show the coefficients explicitly, although they are easy to find using a routine such as Numpy's polyfit. You can view the exact form of the polynomial in the source code for the graph if you're curious. It's the function p(x) defined starting on line 14 of the program which produces the graph.
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/109.png" alt="" />
這給出了一個(gè)完美的擬合。但是我們同樣也能夠使用線性模型 $$y=2x$$ 得到一個(gè)好的擬合效果:
http://wiki.jikexueyuan.com/project/neural-networks-and-deep-learning-zh-cn/images/110.png" alt="" />
哪個(gè)是更好的模型?哪個(gè)更可能是真的?還有哪個(gè)模型更可能泛化到其他的擁有同樣現(xiàn)象的樣本上?
這些都是很難回答的問題。實(shí)際上,我們?nèi)绻麤]有關(guān)于現(xiàn)象背后的信息的話,并不能確定給出上面任何一個(gè)問題的答案。但是讓我們考慮兩種可能的情況:(1)$$9$$ 階多項(xiàng)式實(shí)際上是完全描述了真實(shí)情況的模型,最終它能夠很好地泛化;(2)正確的模型是 $$y=2x$$,但是存在著由于測(cè)量誤差導(dǎo)致的額外的噪聲,使得模型不能夠準(zhǔn)確擬合。
先驗(yàn)假設(shè)無(wú)法說出哪個(gè)是正確的(或者,如果還有其他的情況出現(xiàn))。邏輯上講,這些都可能出現(xiàn)。并且這不是易見的差異。在給出的數(shù)據(jù)上,兩個(gè)模型的表現(xiàn)其實(shí)是差不多的。但是假設(shè)我們想要預(yù)測(cè)對(duì)應(yīng)于某個(gè)超過了圖中所有的 $$x$$ 的 $$y$$ 的值,在兩個(gè)模型給出的結(jié)果之間肯定有一個(gè)極大的差距,因?yàn)?$$9$$ 階多項(xiàng)式模型肯定會(huì)被 $$x^9$$ 主導(dǎo),而線性模型只是線性的增長(zhǎng)。
在科學(xué)中,一種觀點(diǎn)是我們除非不得已應(yīng)該追隨更簡(jiǎn)單的解釋。當(dāng)我們找到一個(gè)簡(jiǎn)單模型似乎能夠解釋很多數(shù)據(jù)樣本的時(shí)候,我們都會(huì)激動(dòng)地認(rèn)為發(fā)現(xiàn)了規(guī)律!總之,這看起來簡(jiǎn)單的解決僅僅會(huì)是偶然出現(xiàn)的不大可能。我們懷疑模型必須表達(dá)出某些關(guān)于現(xiàn)象的內(nèi)在的真理。如上面的例子,線性模型加噪聲肯定比多項(xiàng)式更加可能。所以如果簡(jiǎn)單性是偶然出現(xiàn)的話就很令人詫異。因此我們會(huì)認(rèn)為線性模型加噪聲表達(dá)除了一些潛在的真理。從這個(gè)角度看,多項(xiàng)式模型僅僅是學(xué)習(xí)到了局部噪聲的影響效果。所以盡管多是對(duì)于這些特定的數(shù)據(jù)點(diǎn)表現(xiàn)得很好。模型最終會(huì)在未知數(shù)據(jù)上的泛化上出現(xiàn)問題,所以噪聲線性模型具有更強(qiáng)大的預(yù)測(cè)能力。
讓我們從這個(gè)觀點(diǎn)來看神經(jīng)網(wǎng)絡(luò)。假設(shè)神經(jīng)網(wǎng)絡(luò)