Neil Zhu,簡(jiǎn)書(shū)ID Not_GOD,University AI 創(chuàng)始人 & Chief Scientist,致力于推進(jìn)世界人工智能化進(jìn)程。制定并實(shí)施 UAI 中長(zhǎng)期增長(zhǎng)戰(zhàn)略和目標(biāo),帶領(lǐng)團(tuán)隊(duì)快速成長(zhǎng)為人工智能領(lǐng)域最專業(yè)的力量。
作為行業(yè)領(lǐng)導(dǎo)者,他和UAI一起在2014年創(chuàng)建了TASA(中國(guó)最早的人工智能社團(tuán)), DL Center(深度學(xué)習(xí)知識(shí)中心全球價(jià)值網(wǎng)絡(luò)),AI growth(行業(yè)智庫(kù)培訓(xùn))等,為中國(guó)的人工智能人才建設(shè)輸送了大量的血液和養(yǎng)分。此外,他還參與或者舉辦過(guò)各類國(guó)際性的人工智能峰會(huì)和活動(dòng),產(chǎn)生了巨大的影響力,書(shū)寫了60萬(wàn)字的人工智能精品技術(shù)內(nèi)容,生產(chǎn)翻譯了全球第一本深度學(xué)習(xí)入門書(shū)《神經(jīng)網(wǎng)絡(luò)與深度學(xué)習(xí)》,生產(chǎn)的內(nèi)容被大量的專業(yè)垂直公眾號(hào)和媒體轉(zhuǎn)載與連載。曾經(jīng)受邀為國(guó)內(nèi)頂尖大學(xué)制定人工智能學(xué)習(xí)規(guī)劃和教授人工智能前沿課程,均受學(xué)生和老師好評(píng)。
當(dāng)一個(gè)高爾夫球員剛開(kāi)始學(xué)習(xí)打高爾夫時(shí),他們通常會(huì)在揮桿的練習(xí)上花費(fèi)大多數(shù)時(shí)間。慢慢地他們才會(huì)在基本的揮桿上通過(guò)變化發(fā)展其他的擊球方式,學(xué)習(xí)?低飛球、左曲球和右曲球。類似的,我們現(xiàn)在仍然聚焦在反向傳播算法的理解上。這就是我們的“基本揮桿”——神經(jīng)網(wǎng)絡(luò)中大部分工作學(xué)習(xí)和研究的基礎(chǔ)。本章,我會(huì)解釋若干技術(shù)能夠用來(lái)提升我們關(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ù),使用他們來(lái)提高在第一章中的分類問(wèn)題上的性能。
當(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ì)遇到哪些問(wèn)題的理解。這會(huì)讓你們做好在需要時(shí)快速掌握其他技術(shù)的充分準(zhǔn)備。
交叉熵代價(jià)函數(shù)
我們大多數(shù)人覺(jué)得錯(cuò)了就很不爽。在開(kāi)始學(xué)習(xí)彈奏鋼琴不久后,我在一個(gè)聽(tīng)眾前做了處女秀。我很緊張,開(kāi)始時(shí)將八度音階的曲段演奏得很低。我很困惑,因?yàn)椴荒芾^續(xù)演奏下去了,直到有個(gè)人指出了其中的錯(cuò)誤。當(dāng)時(shí),我非常尷尬。不過(guò),盡管不開(kāi)心,我們卻能夠因?yàn)槊黠@的犯錯(cuò)快速地學(xué)習(xí)到正確的東西。你應(yīng)該相信下次我再演奏肯定會(huì)是正確的!相反,在我們的錯(cuò)誤不是很好的定義的時(shí)候,學(xué)習(xí)的過(guò)程會(huì)變得更加緩慢。
理想地,我們希望和期待神經(jīng)網(wǎng)絡(luò)可以從錯(cuò)誤中快速地學(xué)習(xí)。在實(shí)踐中,這種情況經(jīng)常出現(xiàn)么?為了回答這個(gè)問(wèn)題,讓我們看看一個(gè)小例子。這個(gè)例子包含一個(gè)只有一個(gè)輸入的神經(jīng)元:
我們會(huì)訓(xùn)練這個(gè)神經(jīng)元來(lái)做一件非常簡(jiǎn)單的事:讓輸入 $$1$$ 轉(zhuǎn)化為 $$0$$。當(dāng)然,這很簡(jiǎn)單了,手工找到合適的權(quán)重和偏差就可以了,不需要什么學(xué)習(xí)算法。然而,看起來(lái)使用梯度下降的方式來(lái)學(xué)習(xí)權(quán)重和偏差是很有啟發(fā)的。所以,我們來(lái)看看神經(jīng)元如何學(xué)習(xí)。
為了讓事情確定化,我會(huì)首先將權(quán)重和偏差初始化為 $$0.6$$ 和 $$0.9$$。這些就是一般的開(kāi)始學(xué)習(xí)的選擇,并沒(méi)有任何刻意的想法。一開(kāi)始的神經(jīng)元的輸出是 $$0.82$$,所以這離我們的目標(biāo)輸出 $$0.0$$ 還差得很遠(yuǎn)。點(diǎn)擊右下角的“運(yùn)行”按鈕來(lái)看看神經(jīng)元如何學(xué)習(xí)到讓輸出接近 $$0.0$$ 的。注意到,這并不是一個(gè)已經(jīng)錄好的動(dòng)畫,你的瀏覽器實(shí)際上是正在進(jìn)行梯度的計(jì)算,然后使用梯度更新來(lái)對(duì)權(quán)重和偏差進(jìn)行更新,并且展示結(jié)果。設(shè)置學(xué)習(xí)率 $$\eta=0.15$$ 進(jìn)行學(xué)習(xí)一方面足夠慢的讓我們跟隨學(xué)習(xí)的過(guò)程,另一方面也保證了學(xué)習(xí)的時(shí)間不會(huì)太久,幾秒鐘應(yīng)該就足夠了。代價(jià)函數(shù)是我們前面用到的二次函數(shù),$$C$$。這里我也會(huì)給出準(zhǔn)確的形式,所以不需要翻到前面查看定義了。注意,你可以通過(guò)點(diǎn)擊 “Run” 按鈕執(zhí)行訓(xùn)練若干次。
我們這里是靜態(tài)的例子,在原書(shū)中,使用的動(dòng)態(tài)示例,所以為了更好的效果,請(qǐng)參考原書(shū)的此處動(dòng)態(tài)示例。
正如你所見(jiàn),神經(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)大的。現(xiàn)在看看神經(jīng)元學(xué)習(xí)的過(guò)程。點(diǎn)擊“Run” 按鈕:
雖然這個(gè)例子使用的了同樣的學(xué)習(xí)率($$\eta=0.15$$),我們可以看到剛開(kāi)始的學(xué)習(xí)速度是比較緩慢的。對(duì)前 $$150$$ 左右的學(xué)習(xí)次數(shù),權(quán)重和偏差并沒(méi)有發(fā)生太大的變化。隨后學(xué)習(xí)速度加快,與上一個(gè)例子中類似了,神經(jīng)網(wǎng)絡(luò)的輸出也迅速接近 $$0.0$$。
強(qiáng)烈建議參考原書(shū)的此處動(dòng)態(tài)示例感受學(xué)習(xí)過(guò)程的差異。
這種行為看起來(lái)和人類學(xué)習(xí)行為差異很大。正如我在此節(jié)開(kāi)頭所說(shuō),我們通常是在犯錯(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è)問(wèn)題的源頭,想想神經(jīng)元是按照偏導(dǎo)數(shù)($$\partial C/\partial w$$ 和 $$\partial C/\partial b$$)和學(xué)習(xí)率($$\eta$$)的乘積來(lái)改變權(quán)重和偏差的。所以,我們?cè)谡f(shuō)“學(xué)習(xí)緩慢”時(shí),實(shí)際上就是說(shuō)這些偏導(dǎo)數(shù)很小。理解他們?yōu)楹芜@么小就是我們面臨的挑戰(zhàn)。為了理解這些,讓我們計(jì)算偏導(dǎo)數(shù)看看。我們一直在用的是二次代價(jià)函數(shù),定義如下
其中 $$a$$ 是神經(jīng)元的輸出,其中訓(xùn)練輸入為 $$x=1$$,$$y=0$$ 則是目標(biāo)輸出。顯式地使用權(quán)重和偏差來(lái)表達(dá)這個(gè),我們有 $$a=\sigma(z)$$,其中 $$z=wx+b$$。使用鏈?zhǔn)椒▌t來(lái)求偏導(dǎo)數(shù)就有:
其中我已經(jīng)將 $$x=1$$ 和 $$y=0$$ 代入了。為了理解這些表達(dá)式的行為,讓我們仔細(xì)看 $$\sigma'(z)$$ 這一項(xiàng)。首先回憶一下 $$\sigma$$ 函數(shù)圖像:
我們可以從這幅圖看出,當(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è)特例中特有的。
引入交叉熵代價(jià)函數(shù)
那么我們?nèi)绾谓鉀Q這個(gè)問(wèn)題呢?研究表明,我們可以通過(guò)使用交叉熵代價(jià)函數(shù)來(lái)替換二次代價(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$$:
神經(jīng)元的輸出就是 $$a=\sigma(z)$$,其中 $$z=\sum_jw_jx_j+b$$ 是輸入的帶權(quán)和。我們?nèi)缦露x交叉熵代價(jià)函數(shù):
其中 $$n$$ 是訓(xùn)練數(shù)據(jù)的總數(shù),對(duì)所有的訓(xùn)練數(shù)據(jù) $$x$$ 和 對(duì)應(yīng)的目標(biāo)輸出 $$y$$ 進(jìn)行求和。
公式(57)是否解決學(xué)習(xí)緩慢的問(wèn)題并不明顯。實(shí)際上,甚至將這個(gè)定義看做是代價(jià)函數(shù)也不是顯而易見(jiàn)的!在解決學(xué)習(xí)緩慢前,我們來(lái)看看交叉熵為何能夠解釋成一個(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í)速度下降的問(wèn)題。為了弄清楚這個(gè)情況,我們來(lái)算算交叉熵函數(shù)關(guān)于權(quán)重的偏導(dǎo)數(shù)。我們將 $$a=\sigma(z)$$ 代入到公式 (57) 中應(yīng)用兩次鏈?zhǔn)椒▌t,得到:
將結(jié)果合并一下,簡(jiǎn)化成:
根據(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)在方程中直接約去了,所以最終形式就是:
這是一個(gè)優(yōu)美的公式。它告訴我們權(quán)重學(xué)習(xí)的速度受到 $$\sigma(z)-y$$,也就是輸出中的誤差的控制。更大的誤差,更快的學(xué)習(xí)速度。這是我們直覺(jué)上期待的結(jié)果。特別地,這個(gè)代價(jià)函數(shù)還避免了像在二次代價(jià)函數(shù)中類似公式中 $$\sigma'(z)$$ 導(dǎo)致的學(xué)習(xí)緩慢,見(jiàn)公式(55)。當(dāng)我們使用交叉熵的時(shí)候,$$\sigma'(z)$$ 被約掉了,所以我們不再需要關(guān)心它是不是變得很小。這種約除就是交叉熵帶來(lái)的?特效。實(shí)際上,這也并不是非常奇跡的事情。我們?cè)诤竺婵梢钥吹剑徊骒仄鋵?shí)只是滿足這種特性的一種選擇罷了。
根據(jù)類似的方法,我們可以計(jì)算出關(guān)于偏差的偏導(dǎo)數(shù)。我這里不再給出詳細(xì)的過(guò)程,你可以輕易驗(yàn)證得到
練習(xí)
- 驗(yàn)證 \sigma'(z) = \sigma(z)(1-\sigma(z))。
讓我們重回最原初的例子,來(lái)看看換成了交叉熵之后的學(xué)習(xí)過(guò)程。現(xiàn)在仍然按照前面的參數(shù)配置來(lái)初始化網(wǎng)絡(luò),開(kāi)始權(quán)重為 $$0.6$$,而偏差為 $$0.9$$。點(diǎn)擊“Run”按鈕看看在換成交叉熵之后網(wǎng)絡(luò)的學(xué)習(xí)情況:
毫不奇怪,在這個(gè)例子中,神經(jīng)元學(xué)習(xí)得相當(dāng)出色,跟之前差不多。現(xiàn)在我們?cè)倏纯粗俺鰡?wèn)題的那個(gè)例子,權(quán)重和偏差都初始化為 $$2.0$$:
成功了!這次神經(jīng)元的學(xué)習(xí)速度相當(dāng)快,跟我們預(yù)期的那樣。如果你觀測(cè)的足夠仔細(xì),你可以發(fā)現(xiàn)代價(jià)函數(shù)曲線要比二次代價(jià)函數(shù)訓(xùn)練前面部分要陡很多。正是交叉熵帶來(lái)的快速下降的坡度讓神經(jīng)元在處于誤差很大的情況下能夠逃脫出學(xué)習(xí)緩慢的困境,這才是我們直覺(jué)上所期待的效果。
我們還沒(méi)有提及關(guān)于學(xué)習(xí)率的討論。剛開(kāi)始使用二次代價(jià)函數(shù)的時(shí)候,我們使用了 $$\eta=0.15$$。在新例子中,我們還應(yīng)該使用同樣的學(xué)習(xí)率么?實(shí)際上,根據(jù)不同的代價(jià)函數(shù),我們不能夠直接去套用同樣的學(xué)習(xí)率。這好比蘋果和橙子的比較。對(duì)于這兩種代價(jià)函數(shù),我只是通過(guò)簡(jiǎn)單的實(shí)驗(yàn)來(lái)找到一個(gè)能夠讓我們看清楚變化過(guò)程的學(xué)習(xí)率的值。盡管我不愿意提及,但如果你仍然好奇,這個(gè)例子中我使用了 $$\eta=0.005$$。
你可能會(huì)反對(duì)說(shuō),上面學(xué)習(xí)率的改變使得上面的圖失去了意義。誰(shuí)會(huì)在意當(dāng)學(xué)習(xí)率的選擇是任意挑選的時(shí)候神經(jīng)元學(xué)習(xí)的速度?!這樣的反對(duì)其實(shí)沒(méi)有抓住重點(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)元的交叉熵。不過(guò),將其推廣到多個(gè)神經(jīng)元的多層神經(jīng)網(wǎng)絡(luò)上也是很簡(jiǎn)單的。特別地,假設(shè) $$y=y_1,y_2,...$$ 是輸出神經(jīng)元上的目標(biāo)值,而 $$a_1L,a_2L,...$$是實(shí)際輸出值。那么我們定義交叉熵如下
除了這里需要對(duì)所有輸出神經(jīng)元進(jìn)行求和外,這個(gè)其實(shí)和我們?cè)缜暗墓?57)一樣的。這里不會(huì)給出一個(gè)推算的過(guò)程,但需要說(shuō)明的時(shí)使用公式(63)確實(shí)會(huì)在很多的神經(jīng)網(wǎng)絡(luò)中避免學(xué)習(xí)的緩慢。如果你感興趣,你可以嘗試一下下面問(wèn)題的推導(dǎo)。
那么我們應(yīng)該在什么時(shí)候用交叉熵來(lái)替換二次代價(jià)函數(shù)?實(shí)際上,如果在輸出神經(jīng)元使用 sigmoid 激活函數(shù)時(shí),交叉熵一般都是更好的選擇。為什么?考慮一下我們初始化網(wǎng)絡(luò)的時(shí)候通常使用某種隨機(jī)方法。可能會(huì)發(fā)生這樣的情況,這些初始選擇會(huì)對(duì)某些訓(xùn)練輸入誤差相當(dāng)明顯——比如說(shuō),目標(biāo)輸出是 $$1$$,而實(shí)際值是 $$0$$,或者完全反過(guò)來(lái)。如果我們使用二次代價(jià)函數(shù),那么這就會(huì)導(dǎo)致學(xué)習(xí)速度的下降。它并不會(huì)完全終止學(xué)習(xí)的過(guò)程,因?yàn)檫@些權(quán)重會(huì)持續(xù)從其他的樣本中進(jìn)行學(xué)習(xí),但是顯然這不是我們想要的效果。
練習(xí)
- 一個(gè)小問(wèn)題就是剛接觸交叉熵時(shí),很難一下子記住那些表達(dá)式對(duì)應(yīng)的角色。又比如說(shuō),表達(dá)式的正確形式是 $$?[ylna+(1?y)ln(1?a)]$$
或者 $$?[alny+(1?a)ln(1?y)]$$。在 $$y=0$$ 或者 $$1$$ 的時(shí)候第二個(gè)表達(dá)式的結(jié)果怎樣?這個(gè)問(wèn)題會(huì)影響第一個(gè)表達(dá)式么?為什么? - 在對(duì)單個(gè)神經(jīng)元討論中,我們指出如果對(duì)所有的訓(xùn)練數(shù)據(jù)有 $$\sigma(z)\approx y$$,交叉熵會(huì)很小。這個(gè)論斷其實(shí)是和 $$y$$ 只是等于 $$1$$ 或者 $$0$$ 有關(guān)。這在分類問(wèn)題一般是可行的,但是對(duì)其他的問(wèn)題(如回歸問(wèn)題)$$y$$ 可以取 $$0$$ 和 $$1$$ 之間的中間值的。證明,交叉熵在 $$\sigma(z)=y$$ 時(shí)仍然是最小化的。此時(shí)交叉熵的表示是:
而其中 $$?[y\ln y+(1?y)\ln(1?y)]$$ 有時(shí)候被稱為 ?二元熵
問(wèn)題
- 多層多神經(jīng)元網(wǎng)絡(luò) 用上一章的定義符號(hào),證明對(duì)二次代價(jià)函數(shù),關(guān)于輸出層的權(quán)重的偏導(dǎo)數(shù)為
項(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$$為
使用這個(gè)表達(dá)式來(lái)證明關(guān)于輸出層的權(quán)重的偏導(dǎo)數(shù)為
這里 $$\sigma'(z_j^L)$$ 就消失了,所以交叉熵避免了學(xué)習(xí)緩慢的問(wèn)題,不僅僅是在一個(gè)神經(jīng)元上,而且在多層多元網(wǎng)絡(luò)上都起作用。這個(gè)分析過(guò)程稍作變化對(duì)偏差也是一樣的。如果你對(duì)這個(gè)還不確定,那么請(qǐng)仔細(xì)研讀一下前面的分析。
- 在輸出層使用線性神經(jīng)元時(shí)使用二次代價(jià)函數(shù) 假設(shè)我們有一個(gè)多層多神經(jīng)元網(wǎng)絡(luò),最終輸出層的神經(jīng)元都是線性的,輸出不再是 sigmoid 函數(shù)作用的結(jié)果,而是 $$a_j^L = z_j^L$$。證明如果我們使用二次代價(jià)函數(shù),那么對(duì)單個(gè)訓(xùn)練樣本 $$x$$ 的輸出誤差就是
類似于前一個(gè)問(wèn)題,使用這個(gè)表達(dá)式來(lái)證明關(guān)于輸出層的權(quán)重和偏差的偏導(dǎo)數(shù)為
這表明如果輸出神經(jīng)元是線性的那么二次代價(jià)函數(shù)不再會(huì)導(dǎo)致學(xué)習(xí)速度下降的問(wèn)題。在此情形下,二次代價(jià)函數(shù)就是一種合適的選擇。
使用交叉熵來(lái)對(duì) MNIST 數(shù)字進(jìn)行分類
交叉熵很容易作為使用梯度下降和反向傳播方式進(jìn)行模型學(xué)習(xí)的一部分來(lái)實(shí)現(xiàn)。我們將會(huì)在下一章進(jìn)行對(duì)前面的程序 network.py
的改進(jìn)。新的程序?qū)懺?network2.py
中,不僅使用了交叉熵,還有本章中介紹的其他的技術(shù)。現(xiàn)在我們看看新的程序在進(jìn)行 MNIST 數(shù)字分類問(wèn)題上的表現(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
稍微不同,但是過(guò)程還是很清楚的。你可以使用如 help(network2.Network.SGD)
這樣的命令來(lái)檢查對(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()
命令使用和第一章介紹的同樣的方式來(lái)進(jìn)行權(quán)重和偏差的初始化。運(yùn)行上面的代碼我們得到了一個(gè) 95.49% 準(zhǔn)確度的網(wǎng)絡(luò)。這跟我們?cè)诘谝徽轮惺褂枚未鷥r(jià)函數(shù)得到的結(jié)果相當(dāng)接近了,95.42%。
同樣也來(lái)試試使用 $$100$$ 個(gè)隱藏元的交叉熵及其他參數(shù)保持不變的情況。在這個(gè)情形下,我們獲得了 96.82% 的準(zhǔn)確度。相比第一章使用二次代價(jià)函數(shù)的結(jié)果 96.59%,這有一定的提升。這看起來(lái)是一個(gè)小小的變化,但是考慮到誤差率已經(jīng)從 3.41% 下降到 3.18%了。我們已經(jīng)消除了原誤差的 $$1/14$$。這其實(shí)是可觀的改進(jìn)。
令人振奮的是交叉熵代價(jià)函數(shù)給了我們類似的或者更好的結(jié)果。然而,這些結(jié)果并沒(méi)有能夠確定性地證明交叉熵是更好的選擇。原因在于我已經(jīng)在選擇諸如學(xué)習(xí)率,minibatch 大小等等這樣的超參數(shù)上做出了一些努力。為了讓這些提升更具說(shuō)服力,我們需要進(jìn)行對(duì)超參數(shù)進(jìn)行深度的優(yōu)化。當(dāng)然,這些結(jié)果都挺好的,強(qiáng)化了我們?cè)缦汝P(guān)于交叉熵優(yōu)于二次代價(jià)的理論論斷。
這只是本章后面的內(nèi)容和整本書(shū)剩余內(nèi)容中的更為一般的模式的一部分。我們將給出一個(gè)新的技術(shù),然后進(jìn)行嘗試,隨后獲得“提升的”結(jié)果。當(dāng)然,看到這些進(jìn)步是很好的。但是這些提升的解釋一般來(lái)說(shuō)都困難重重。在進(jìn)行了大量工作來(lái)優(yōu)化所有其他的超參數(shù),使得提升真的具有說(shuō)服力。工作量很大,需要大量的計(jì)算能力,我們也不會(huì)進(jìn)行這樣耗費(fèi)的調(diào)查。相反,我采用上面進(jìn)行的那些不正式的測(cè)試來(lái)達(dá)成目標(biāo)。所以你要記住這樣的測(cè)試缺少確定性的證明,需要注意那些使得論斷失效的信號(hào)。
至此,我們已經(jīng)花了大量篇幅介紹交叉熵。為何對(duì)一個(gè)只能給出一點(diǎn)點(diǎn)性能提升的技術(shù)上花費(fèi)這么多的精力?后面,我們會(huì)看到其他的技術(shù)——規(guī)范化,會(huì)帶來(lái)更大的提升效果。所以為何要這么細(xì)致地討論交叉熵?部分原因在于交叉熵是一種廣泛使用的代價(jià)函數(shù),值得深入理解。但是更加重要的原因是神經(jīng)元的飽和是神經(jīng)網(wǎng)絡(luò)中一個(gè)關(guān)鍵的問(wèn)題,整本書(shū)都會(huì)不斷回歸到這個(gè)問(wèn)題上。因此我現(xiàn)在深入討論交叉熵就是因?yàn)檫@是一種開(kāi)始理解神經(jīng)元飽和和如何解決這個(gè)問(wèn)題的很好的實(shí)驗(yàn)。
交叉熵的含義?源自哪里?
我們對(duì)于交叉熵的討論聚焦在代數(shù)分析和代碼實(shí)現(xiàn)。這雖然很有用,但是也留下了一個(gè)未能回答的更加寬泛的概念上的問(wèn)題,如:交叉熵究竟表示什么?存在一些直覺(jué)上的思考交叉熵的方法么?我們?nèi)绾蜗氲竭@個(gè)概念?
讓我們從最后一個(gè)問(wèn)題開(kāi)始回答:什么能夠激發(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$$ 就滿足:
如果我們選擇的代價(jià)函數(shù)滿足這些條件,那么同樣他們會(huì)擁有遇到明顯誤差時(shí)的學(xué)習(xí)速度越快這樣的特性。這也能夠解決學(xué)習(xí)速度下降的問(wèn)題。實(shí)際上,從這些公式開(kāi)始,現(xiàn)在就給你們看看若是跟隨自身的數(shù)學(xué)嗅覺(jué)推導(dǎo)出交叉熵的形式是可能的。我們來(lái)推一下,由鏈?zhǔn)椒▌t,我們有
使用 $$\sigma'(z)=\sigma(z)(1-\sigma(z))=a(1-a)$$,上個(gè)等式就變成
對(duì)比等式(72),我們有
對(duì)此方程關(guān)于 $$a$$ 進(jìn)行積分,得到
其中 $$constant$$ 是積分常量。這是一個(gè)單獨(dú)的訓(xùn)練樣本 $$x$$ 對(duì)代價(jià)函數(shù)的貢獻(xiàn)。為了得到整個(gè)的代價(jià)函數(shù),我們需要對(duì)所有的訓(xùn)練樣本進(jìn)行平均,得到了
而這里的常量就是所有單獨(dú)的常量的平均。所以我們看到方程(71)和(72)唯一確定了交叉熵的形式,并加上了一個(gè)常量的項(xiàng)。這個(gè)交叉熵并不是憑空產(chǎn)生的。而是一種我們以自然和簡(jiǎn)單的方法獲得的結(jié)果。
那么交叉熵直覺(jué)含義又是什么?我們?nèi)绾慰创可钊虢忉屵@一點(diǎn)會(huì)將我們帶到一個(gè)不大愿意討論的領(lǐng)域。然而,還是值得提一下,有一種源自信息論的解釋交叉熵的標(biāo)準(zhǔn)方式。粗略地說(shuō),交叉熵是驚奇的度量(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)然,我這里沒(méi)有嚴(yán)格地給出“驚奇”到底意味著什么,所以看起來(lái)像在夸夸奇談。但是實(shí)際上,在信息論中有一種準(zhǔn)確的方式來(lái)定義驚奇究竟是什么。不過(guò),我也不清楚在網(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)容。
問(wèn)題
- 我們已經(jīng)深入討論了使用二次代價(jià)函數(shù)的網(wǎng)絡(luò)中在輸出神經(jīng)元飽和時(shí)候?qū)W習(xí)緩慢的問(wèn)題,另一個(gè)可能會(huì)影響學(xué)習(xí)的因素就是在方程(61)中的 $$x_j$$ 項(xiàng)。由于此項(xiàng),當(dāng)輸入 $$x_j$$ 接近 $$0$$ 時(shí),對(duì)應(yīng)的權(quán)重 $$x_j$$ 會(huì)學(xué)習(xí)得相當(dāng)緩慢。解釋為何不可以通過(guò)改變代價(jià)函數(shù)來(lái)消除 $$x_j$$ 項(xiàng)的影響。
Softmax
本章,我們大多數(shù)情況會(huì)使用交叉熵來(lái)解決學(xué)習(xí)緩慢的問(wèn)題。但是,我希望簡(jiǎn)要介紹一下基于 softmax 神經(jīng)元層的解決這個(gè)問(wèn)題的另一種觀點(diǎn)。我們不會(huì)實(shí)際在剩下的章節(jié)中使用 softmax 層,所以你如果趕時(shí)間,就可以跳到下一個(gè)小節(jié)了。不過(guò),softmax 仍然有其重要價(jià)值,一方面它本身很有趣,另一方面,因?yàn)槲覀儠?huì)在第六章在對(duì)深度神經(jīng)網(wǎng)絡(luò)的討論中使用 softmax 層。
softmax 的想法其實(shí)就是為神經(jīng)網(wǎng)絡(luò)定義一種新式的輸出層。開(kāi)始時(shí)和 sigmoid 層一樣的,首先計(jì)算帶權(quán)輸入 $$z_j^L = \sum_k w_{jk}La_k{L-1}+b_j^L$$。不過(guò),這里我們不會(huì)使用 sigmoid 函數(shù)來(lái)獲得輸出。而是,會(huì)應(yīng)用一種叫做 softmax 函數(shù)在 $$z_j^L$$ 上。根據(jù)這個(gè)函數(shù),激活值 $$a_j^L$$ 就是
其中,分母是對(duì)所有的輸出神經(jīng)元進(jìn)行求和。
如果你不習(xí)慣這個(gè)函數(shù),方程(78)可能看起來(lái)會(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)的激活值的圖像。可以通過(guò)固定其他值,來(lái)看看改變 $$z_4^L$$ 的值會(huì)產(chǎn)生什么樣的影響:
這里給出了三個(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ù)定義,輸出的激活值加起來(lái)正好為 $$1$$,使用公式(78)我們可以證明:
所以,如果 $$a_4^L$$ 增加,那么其他輸出激活值肯定會(huì)總共下降相同的量,來(lái)保證和式為 $$1$$。當(dāng)然,類似的結(jié)論對(duì)其他的激活函數(shù)也需要滿足。
方程(78)同樣保證輸出激活值都是正數(shù),因?yàn)橹笖?shù)函數(shù)是正的。將這兩點(diǎn)結(jié)合起來(lái),我們看到 softmax 層的輸出是一些相加為 $$1$$ 正數(shù)的集合。換言之,softmax 層的輸出可以被看做是一個(gè)概率分布。
這樣的效果很令人滿意。在很多問(wèn)題中,將這些激活值作為網(wǎng)絡(luò)對(duì)于某個(gè)輸出正確的概率的估計(jì)非常方便。所以,比如在 MNIST 分類問(wèn)題中,我們可以將 $$a_j^L$$ 解釋成網(wǎng)絡(luò)估計(jì)正確數(shù)字分類為 $$j$$ 的概率。
對(duì)比一下,如果輸出層是 sigmoid 層,那么我們肯定不能假設(shè)激活值形成了一個(gè)概率分布。我不會(huì)證明這一點(diǎn),但是源自 sigmoid 層的激活值是不能夠形成一種概率分布的一般形式的。所以使用 sigmoid 輸出層,我們沒(méi)有關(guān)于輸出的激活值的簡(jiǎn)單的解釋。
練習(xí)
- 構(gòu)造例子表明在使用 sigmoid 輸出層的網(wǎng)絡(luò)中輸出激活值 $$a_j^L$$ 的和并不會(huì)確保為 $$1$$。
我們現(xiàn)在開(kāi)始體會(huì)到 softmax 函數(shù)的形式和行為特征了。來(lái)回顧一下:在公式(78)中的指數(shù)函數(shù)確保了所有的輸出激活值是正數(shù)。然后分母的求和又保證了 softmax 的輸出和為 $$1$$。所以這個(gè)特定的形式不再像之前那樣難以理解了:反而是一種確保輸出激活值形成一個(gè)概率分布的自然的方式。你可以將其想象成一種重新調(diào)節(jié) $$z_j^L$$ 的方法,然后將這個(gè)結(jié)果整合起來(lái)構(gòu)成一個(gè)概率分布。
練習(xí)
- softmax 的單調(diào)性 證明如果 $$j=k$$ 則 $$\partial a_j^L/\partial z_k^L$$ 為正,否則為負(fù)。結(jié)果是,增加 $$z_^L$$ 會(huì)提高對(duì)應(yīng)的輸出激活值 $$a_k^L$$ 并降低其他所有輸出激活值。我們已經(jīng)在滑條示例中實(shí)驗(yàn)性地看到了這一點(diǎn),這里需要你給出一個(gè)嚴(yán)格證明。
- softmax 的非局部性 sigmoid 層的一個(gè)好處是輸出 $$a_j^L$$ 是對(duì)應(yīng)帶權(quán)輸入 $$a_j^L = \sigma(z_j^L)$$ 的函數(shù)。解釋為何對(duì)于 softmax 來(lái)說(shuō),并不是這樣的情況:仍和特定的輸出激活值 $$a_j^L$$ 依賴所有的帶權(quán)輸入。
問(wèn)題
- 逆轉(zhuǎn) softmax 層 假設(shè)我們有一個(gè)使用 softmax 輸出層的神經(jīng)網(wǎng)絡(luò),然后激活值 $$a_j^L$$ 已知。證明對(duì)應(yīng)帶權(quán)輸入的形式為 $$z_j^L = \ln a_j^L + C$$,其中 $$C$$ 是獨(dú)立于 $$j$$ 的。
學(xué)習(xí)緩慢問(wèn)題:我們現(xiàn)在已經(jīng)對(duì) softmax 神經(jīng)元有了一定的認(rèn)識(shí)。但是我們還沒(méi)有看到 softmax 會(huì)怎么樣解決學(xué)習(xí)緩慢問(wèn)題。為了理解這點(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ù)就是
所以,如果我們訓(xùn)練的是 MNIST 圖像,輸入為 $$7$$ 的圖像,那么對(duì)應(yīng)的 log-likelihood 代價(jià)就是 $$-\ln a_7^L$$。看看這個(gè)直覺(jué)上的含義,想想當(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í)緩慢問(wèn)題呢?為了分析它,回想一下學(xué)習(xí)緩慢的關(guān)鍵就是量 $$\partial C/\partial w_{jk}^L$$ 和 $$\partial C/\partial b_j^L$$ 的變化情況。我不會(huì)顯式地給出詳細(xì)的推導(dǎo)——請(qǐng)你們自己去完成這個(gè)過(guò)程——但是會(huì)給出一些關(guān)鍵的步驟:
請(qǐng)注意這里的表示上的差異,這里的 $$y$$ 和之前的目標(biāo)輸出值不同,是離散的向量表示,對(duì)應(yīng)位的值為 $$1$$,而其他為 $$0$$。
這些方程其實(shí)和我們前面對(duì)交叉熵得到的類似。就拿方程(82) 和 (67) 比較。盡管后者我對(duì)整個(gè)訓(xùn)練樣本進(jìn)行了平均,不過(guò)形式還是一致的。而且,正如前面的分析,這些表達(dá)式確保我們不會(huì)遇到學(xué)習(xí)緩慢的問(wèn)題。實(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 這種有著不重疊的分類問(wèn)題上確實(shí)很有用。
問(wèn)題
- 推導(dǎo)方程(81) 和 (82)
- softmax 這個(gè)名稱從何處來(lái)? 假設(shè)我們改變一下 softmax 函數(shù),使得輸出激活值定義如下
其中 $$c$$ 是正的常量。注意 $$c=1$$ 對(duì)應(yīng)標(biāo)準(zhǔn)的 softmax 函數(shù)。但是如果我們使用不同的 $$c$$ 得到不同的函數(shù),其實(shí)最終的量的結(jié)果卻和原來(lái)的 softmax 差不多。特別地,證明輸出激活值也會(huì)形成一個(gè)概率分布。假設(shè)我們?cè)试S $$c$$ 足夠大,比如說(shuō) $$c\rightarrow \inf$$。那么輸出激活值 $$a_j^L$$ 的極限值是什么?在解決了這個(gè)問(wèn)題后,你應(yīng)該能夠理解 c=1 對(duì)應(yīng)的函數(shù)是一個(gè)最大化函數(shù)的 softened 版本。這就是 softmax 的來(lái)源。
這讓我聯(lián)想到 EM 算法,對(duì) k-Means 算法的一種推廣。
- softmax 和 log-likelihood 的反向傳播 上一章,我們推到了使用 sigmoid 層的反向傳播算法。為了應(yīng)用在 softmax 層的網(wǎng)絡(luò)上,我們需要搞清楚最后一層上誤差的表示 $$\delta_j^L \equiv \partial C/\partial z_j^L$$。證明形式如下:
使用這個(gè)表達(dá)式,我們可以應(yīng)用反向傳播在采用了 softmax 輸出層和 log-likelihood 的網(wǎng)絡(luò)上。