導(dǎo)讀:本文內(nèi)容節(jié)選自《深入淺出神經(jīng)網(wǎng)絡(luò)與深度學(xué)習(xí)》一書,由Michael Nielsen所著,他是實驗媒體研究工作室的聯(lián)合創(chuàng)始人,曾是 YC Research 的 Research Fellow。。
本書深入了講解神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí)技術(shù),側(cè)重于闡釋深度學(xué)習(xí)的核心概念。作者以技術(shù)原理為導(dǎo)向,輔以貫穿全書的 MNIST 手寫數(shù)字識別項目示例,介紹神經(jīng)網(wǎng)絡(luò)架構(gòu)、反向傳播算法、過擬合解決方案、卷積神經(jīng)網(wǎng)絡(luò)等內(nèi)容,以及如何利用這些知識改進(jìn)深度學(xué)習(xí)項目。學(xué)完本書后,讀者將能夠通過編寫 Python 代碼來解決復(fù)雜的模式識別問題。
了解關(guān)于深度學(xué)習(xí)的更多干貨知識,關(guān)注AI科技大本營并評論分享你對本文的學(xué)習(xí)心得或深度學(xué)習(xí)的見解,我們將從中選出5條優(yōu)質(zhì)評論,各送出《深入淺出神經(jīng)網(wǎng)絡(luò)與深度學(xué)習(xí)》一本。活動截止時間為8月29日晚8點。
假設(shè)你是工程師,接到一項任務(wù):從頭開始設(shè)計計算機(jī)。某天,你正在工作室設(shè)計邏輯電路,例如構(gòu)建與門、或門等。這時,老板帶著壞消息進(jìn)來了:客戶剛剛提了一個奇怪的設(shè)計需求——整個計算機(jī)的電路深度限于兩層,如圖5-1所示。
你驚呆了,跟老板說道:“他們瘋了吧!”
老板說:“我也覺得他們瘋了,但是客戶至上,只能設(shè)法滿足他們。”
實際上,客戶提出的需求并不過分。假設(shè)你能使用某種特殊的邏輯對任意多的輸入執(zhí)行AND運算,還能使用多輸入的與非門對多個輸入執(zhí)行AND運算和NOT運算。由這類特殊的邏輯門構(gòu)建出來的雙層深度電路就可以計算任何函數(shù)。
理論上成立并不代表這是一個好的想法。在實際解決電路設(shè)計問題或其他大多數(shù)算法問題時,通常要考慮如何解決子問題,然后逐步集成這些子問題的解。換言之,要通過多層抽象來得到最終解。
假設(shè)設(shè)計一個邏輯電路來對兩個數(shù)做乘法,我們希望基于計算兩個數(shù)之和的子電路來構(gòu)建該邏輯電路。計算兩個數(shù)之和的子電路是構(gòu)建在用于兩位相加的子子電路上的。電路大致如圖5-2所示。
最終的電路至少包含3層。實際上,這個電路很可能超過3層,因為可以將子任務(wù)分解成更小的單元,但基本思想就是這樣。
可見深度電路讓設(shè)計過程變得更簡單,但對于設(shè)計本身幫助并不大。其實用數(shù)學(xué)可以證明,對于某些函數(shù)計算,淺層電路所需的電路單元要比深度電路多得多。例如20世紀(jì)80年代初的一些著名的論文已經(jīng)提出,通過淺層電路計算比特集合的奇偶性需要指數(shù)級的邏輯門。然而,如果使用更深的電路,那么可以使用規(guī)模很小的電路來計算奇偶性:僅僅需要計算比特對的奇偶性,然后使用這些結(jié)果來計算比特對的對的奇偶性,以此類推,從而得出整體的奇偶性。這樣一來,深度電路就能在本質(zhì)上超過淺層電路了。
前文一直將神經(jīng)網(wǎng)絡(luò)看作瘋狂的客戶,幾乎講到的所有神經(jīng)網(wǎng)絡(luò)都只包含一層隱藏神經(jīng)元(另外還有輸入層和輸出層),如圖5-3所示。
這些簡單的神經(jīng)網(wǎng)絡(luò)已經(jīng)非常有用了,前面使用這樣的神經(jīng)網(wǎng)絡(luò)識別手寫數(shù)字,準(zhǔn)確率高達(dá)98%!而且,憑直覺來看,擁有更多隱藏層的神經(jīng)網(wǎng)絡(luò)會更強(qiáng)大,如圖5-4所示。
這樣的神經(jīng)網(wǎng)絡(luò)可以使用中間層構(gòu)建出多層抽象,正如在布爾電路中所做的那樣。如果進(jìn)行視覺模式識別,那么第1層的神經(jīng)元可能學(xué)會識別邊;第2層的神經(jīng)元可以在此基礎(chǔ)上學(xué)會識別更加復(fù)雜的形狀,例如三角形或矩形;第3層將能夠識別更加復(fù)雜的形狀,以此類推。有了這些多層抽象,深度神經(jīng)網(wǎng)絡(luò)似乎可以學(xué)習(xí)解決復(fù)雜的模式識別問題。正如電路示例所體現(xiàn)的那樣,理論研究表明深度神經(jīng)網(wǎng)絡(luò)本質(zhì)上比淺層神經(jīng)網(wǎng)絡(luò)更強(qiáng)大。
如何訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)呢?本章嘗試使用我們熟悉的學(xué)習(xí)算法——基于反向傳播的隨機(jī)梯度下降,來訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)。但是,這會產(chǎn)生問題,因為我們的深度神經(jīng)網(wǎng)絡(luò)并不比淺層神經(jīng)網(wǎng)絡(luò)的性能強(qiáng)多少。
這似乎與前面的討論相悖,就此退縮嗎?當(dāng)然不,下面深入探究使得深度神經(jīng)網(wǎng)絡(luò)訓(xùn)練困難的原因。仔細(xì)研究便會發(fā)現(xiàn),在深度神經(jīng)網(wǎng)絡(luò)中,不同層的學(xué)習(xí)速度差異很大。后面的層正常學(xué)習(xí)時,前面的層常常會在訓(xùn)練中停滯不前,基本上學(xué)不到什么。這種停滯并不是因為運氣不佳,而是有著更根本的原因,并且這些原因和基于梯度的學(xué)習(xí)技術(shù)相關(guān)。
隨著更加深入地理解這個問題,也會發(fā)現(xiàn)相反的情形:前面的層可能學(xué)習(xí)得很好,但是后面的層停滯不前。實際上,我們發(fā)現(xiàn)在深度神經(jīng)網(wǎng)絡(luò)中使用基于梯度下降的學(xué)習(xí)算法本身存在不穩(wěn)定性。這種不穩(wěn)定性使得前面或后面的層的學(xué)習(xí)過程阻滯。
這的確是個壞消息,但真正理解了這些難點后,就能掌握高效訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)的關(guān)鍵所在。而且這些發(fā)現(xiàn)也是第6章的預(yù)備知識,屆時會介紹如何使用深度學(xué)習(xí)解決圖像識別問題。
01
梯度消失問題
在訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)時,究竟哪里出了問題?
為了回答這個問題,首先回顧一下使用單一隱藏層的神經(jīng)網(wǎng)絡(luò)示例。這里仍以MNIST數(shù)字分類問題作為研究和試驗的對象。
你也可以使用自己的計算機(jī)訓(xùn)練神經(jīng)網(wǎng)絡(luò)。如果想同步跟隨這些步驟,需要用到NumPy,可以使用如下命令復(fù)制所有代碼:
git clone https://github.com/mnielsen/neural-networks-and-deep-learning.git
如果你不使用Git,可以直接在隨書下載的壓縮包里找到數(shù)據(jù)和代碼。
進(jìn)入src子目錄,在Python shell中加載MNIST數(shù)據(jù):
>>> import mnist_loader
>>> training_data, validation_data, test_data = \
... mnist_loader.load_data_wrapper()
初始化神經(jīng)網(wǎng)絡(luò):
>>> import network2
>>> net = network2.Network([784, 30, 10])
該神經(jīng)網(wǎng)絡(luò)有784個輸入神經(jīng)元,對應(yīng)輸入圖片的28×28 = 784個像素點。我們設(shè)置隱藏神經(jīng)元為30個,輸出神經(jīng)元為10個,對應(yīng)10個MNIST數(shù)字(0~9)。
訓(xùn)練30輪,小批量樣本大小為10,學(xué)習(xí)率,正則化參數(shù)。訓(xùn)練時也會在validation_data上監(jiān)控分類準(zhǔn)確率:
>>> net.SGD(training_data, 30, 10, 0.1, lmbda=5.0,
... evaluation_data=validation_data, monitor_evaluation_accuracy=True)
最終的分類準(zhǔn)確率為96.48%(也可能不同,每次運行實際上都會有一點點偏差),這和前面的結(jié)果相似。
接下來增加另外一個隱藏層,它也包含30個神經(jīng)元,并使用相同的超參數(shù)進(jìn)行訓(xùn)練:
>>> net = network2.Network([784, 30, 30, 10])
>>> net.SGD(training_data, 30, 10, 0.1, lmbda=5.0,
... evaluation_data=validation_data, monitor_evaluation_accuracy=True)
分類準(zhǔn)確率稍有提升,到了96.90%,這說明增加深度有效果,那就再增加一個隱藏層,它同樣有30個神經(jīng)元:
>>> net = network2.Network([784, 30, 30, 30, 10])
>>> net.SGD(training_data, 30, 10, 0.1, lmbda=5.0,
... evaluation_data=validation_data, monitor_evaluation_accuracy=True)
結(jié)果分類準(zhǔn)確率不僅沒有提升,反而下降到了96.57%,這與最初的淺層神經(jīng)網(wǎng)絡(luò)相差無幾。嘗試再增加一層:
>>> net = network2.Network([784, 30, 30, 30, 30, 10])
>>> net.SGD(training_data, 30, 10, 0.1, lmbda=5.0,
... evaluation_data=validation_data, monitor_evaluation_accuracy=True)
分類準(zhǔn)確率繼續(xù)下降,變?yōu)?6.53%。雖然這從統(tǒng)計角度看算不上顯著下降,但釋放出了不好的信號。
這種現(xiàn)象非常奇怪。根據(jù)常理判斷,額外的隱藏層能讓神經(jīng)網(wǎng)絡(luò)學(xué)到更加復(fù)雜的分類函數(shù),然后在分類時表現(xiàn)得更好。按理說不應(yīng)該變差,有了額外的神經(jīng)元層,再糟糕也不過是沒有作用,然而情況并非如此。
這究竟是為什么呢?理論上,額外的隱藏層的確能夠起作用,然而學(xué)習(xí)算法沒有找到正確的權(quán)重和偏置。下面研究學(xué)習(xí)算法本身出了什么問題,以及如何改進(jìn)。
為了直觀理解這個問題,可以將神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)過程可視化。圖5-5展示了[784,30,30,10]神經(jīng)網(wǎng)絡(luò)的一部分——兩個隱藏層,每層各有30個神經(jīng)元。圖中每個神經(jīng)元都有一個條形統(tǒng)計圖,表示在神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)時該神經(jīng)元改變的速度,長條代表權(quán)重和偏置變化迅速,反之則代表變化緩慢。確切地說,這些條代表每個神經(jīng)元上的,即代價關(guān)于神經(jīng)元偏置的變化速率。第2章講過,這個梯度量不僅控制著學(xué)習(xí)過程中偏置改變的速度,也控制著輸入到神經(jīng)元的權(quán)重的改變速度。遺忘了這些細(xì)節(jié)也不要緊,這里只需要記住這些條表示每個神經(jīng)元權(quán)重和偏置在神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)時的變化速率。
簡單起見,圖5-5只展示了每個隱藏層最上方的6個神經(jīng)元。之所以沒有展示輸入神經(jīng)元,是因為它們沒有需要學(xué)習(xí)的權(quán)重或偏置;之所以沒有展示輸出神經(jīng)元,是因為這里進(jìn)行的是層與層的比較,而比較神經(jīng)元數(shù)量相同的兩層更為合理。神經(jīng)網(wǎng)絡(luò)初始化后立即得到了訓(xùn)練前期的結(jié)果,如圖5-5所示。
該神經(jīng)網(wǎng)絡(luò)是隨機(jī)初始化的,因此神經(jīng)元的學(xué)習(xí)速度其實相差較大,而且隱藏層2上的條基本上要比隱藏層1上的條長,所以隱藏層2的神經(jīng)元學(xué)習(xí)得更快。這僅僅是一個巧合嗎?這能否說明第2個隱藏層的神經(jīng)元一般會比第1個隱藏層的神經(jīng)元學(xué)習(xí)得更快呢?
借助以上定義,在和圖5-5相同的配置下,
,這樣就解開了之前的疑惑:第2個隱藏層的神經(jīng)元確實比第1個隱藏層的學(xué)得快。如果添加更多隱藏層,會如何呢?如果有3個隱藏層,比如一個[784,30,30,30,10]神經(jīng)網(wǎng)絡(luò),那么對應(yīng)的學(xué)習(xí)速度分別是0.012、0.060和0.283,其中前面兩個隱藏層的學(xué)習(xí)速度還是慢于最后的隱藏層。假設(shè)再增加一個包含30個神經(jīng)元的隱藏層,那么對應(yīng)的學(xué)習(xí)速度分別是0.003、0.017、0.070和0.285。還是相同的模式:前面的隱藏層比后面的隱藏層學(xué)習(xí)得更慢。
這就是訓(xùn)練開始時的學(xué)習(xí)速度,即剛剛初始化之后的情況。那么隨著訓(xùn)練的推進(jìn),學(xué)習(xí)速度會發(fā)生怎樣的變化呢?以只有兩個隱藏層的神經(jīng)網(wǎng)絡(luò)為例,其學(xué)習(xí)速度的變化如圖5-6所示。
這些結(jié)果產(chǎn)生自對1000幅訓(xùn)練圖像應(yīng)用梯度下降算法,訓(xùn)練了500輪。這與通常的訓(xùn)練方式不同,沒有使用小批量方式,僅僅使用了1000幅訓(xùn)練圖像,而不是全部的50 000幅圖像。這并不是什么新嘗試,也不是敷衍了事,而顯示了使用小批量隨機(jī)梯度下降會讓結(jié)果包含更多噪聲(盡管在平均噪聲時結(jié)果很相似)。可以使用確定好的參數(shù)對結(jié)果進(jìn)行平滑處理,以便看清楚真實情況。
如圖5-6所示,兩個隱藏層一開始速度便不同,二者的學(xué)習(xí)速度在觸底前迅速下降。此外,第1層的學(xué)習(xí)速度比第2層慢得多。
更復(fù)雜的神經(jīng)網(wǎng)絡(luò)情況如何呢?下面進(jìn)行類似的試驗,但這次神經(jīng)網(wǎng)絡(luò)有3個隱藏層([784,30,30,30,10]),如圖5-7所示。
同樣,前面的隱藏層比后面的隱藏層學(xué)習(xí)得更慢。最后一個試驗用到4個隱藏層([784,30,30,30,30,10]),看看情況如何,如圖5-8所示。
同樣的情況出現(xiàn)了,前面的隱藏層慢于后面的隱藏層。其中隱藏層1的學(xué)習(xí)速度跟隱藏層4的差了兩個數(shù)量級,即前者是后者的1/100,難怪之前訓(xùn)練這些神經(jīng)網(wǎng)絡(luò)時出現(xiàn)了問題。
這就有了重要發(fā)現(xiàn):至少在某些深度神經(jīng)網(wǎng)絡(luò)中,梯度在隱藏層反向傳播時傾向于變小。這意味著前面的隱藏層中的神經(jīng)元比后面的隱藏層中的神經(jīng)元學(xué)習(xí)得更慢。本節(jié)只研究了一個神經(jīng)網(wǎng)絡(luò),其實多數(shù)神經(jīng)網(wǎng)絡(luò)存在這個現(xiàn)象,即梯度消失問題。
為何會出現(xiàn)梯度消失問題呢?如何避免它呢?在訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)時如何處理這個問題呢?實際上,這個問題并非不可避免,然而替代方法并不完美,也會出現(xiàn)問題:前面的層中的梯度會變得非常大!這被稱為梯度爆炸問題,它不比梯度消失問題容易處理。一般而言,深度神經(jīng)網(wǎng)絡(luò)中的梯度是不穩(wěn)定的,在前面的層中可能消失,可能“爆炸”。這種不穩(wěn)定性是基于梯度學(xué)習(xí)的深度神經(jīng)網(wǎng)絡(luò)存在的根本問題,也就是需要理解的地方。如果可能,應(yīng)該采取恰當(dāng)?shù)拇胧┙鉀Q該問題。
關(guān)于梯度消失(或不穩(wěn)定),一種觀點是確定這真的成問題。暫時換一個話題,假設(shè)要最小化一元函數(shù),如果其導(dǎo)數(shù)很小,這難道不是一個好消息嗎?是否意味著已經(jīng)接近極值點了?同樣,深度神經(jīng)網(wǎng)絡(luò)中前面隱藏層的小梯度是否表示不用費力調(diào)整權(quán)重和偏置了?
當(dāng)然,實際情況并非如此。想想隨機(jī)初始化神經(jīng)網(wǎng)絡(luò)中的權(quán)重和偏置。對于任意任務(wù),單單使用隨機(jī)初始化的值難以獲得良好結(jié)果。具體而言,考慮MNIST問題中神經(jīng)網(wǎng)絡(luò)第1層的權(quán)重,隨機(jī)初始化意味著第1層丟失了輸入圖像的幾乎所有信息。即使后面的層能得到充分的訓(xùn)練,這些層也會因為沒有充足的信息而難以識別輸入圖像。因此,第1層不進(jìn)行學(xué)習(xí)是行不通的。如果繼續(xù)訓(xùn)練深度神經(jīng)網(wǎng)絡(luò),就需要弄清楚如何解決梯度消失問題。
02
梯度消失的原因
為了弄清楚梯度消失問題出現(xiàn)的原因,看一個極簡單的深度神經(jīng)網(wǎng)絡(luò):每層都只有單一神經(jīng)元。圖5-9展示了有3個隱藏層的神經(jīng)網(wǎng)絡(luò)。
表達(dá)式結(jié)構(gòu)如下:每個神經(jīng)元都有
項,每個權(quán)重都有項,此外還有一個項,它表示最終的代價函數(shù)。注意,這里將表達(dá)式中的每一項置于對應(yīng)的位置,所以神經(jīng)網(wǎng)絡(luò)本身就是對表達(dá)式的解讀。你可以不深究這個表達(dá)式,直接跳到下文討論為何出現(xiàn)梯度消失的內(nèi)容。這樣做不會影響理解,因為實際上該表達(dá)式只是反向傳播的特例。不過,對于該表達(dá)式為何正確,了解一下也很有趣(可能還會給你有益的啟示)。
假設(shè)對偏置做了微調(diào),這會導(dǎo)致神經(jīng)網(wǎng)絡(luò)中其余元素發(fā)生一系列變化。首先會使得第1個隱藏神經(jīng)元輸出產(chǎn)生的變化,進(jìn)而導(dǎo)致第2個隱藏神經(jīng)元的帶權(quán)輸入產(chǎn)生的變化,第2個隱藏神經(jīng)元輸出隨之產(chǎn)生的變化,以此類推,最終輸出的代價會產(chǎn)生的變化。這里有:
5.2.1 為何出現(xiàn)梯度消失
梯度的完整表達(dá)式如下:
除了最后一項,該表達(dá)式幾乎就是一系列
的乘積。為了理解每一項,先看看sigmoid函數(shù)的導(dǎo)數(shù)的圖像,如圖5-11所示。該導(dǎo)數(shù)在
時達(dá)到峰值。如果使用標(biāo)準(zhǔn)方法來初始化神經(jīng)網(wǎng)絡(luò)中的權(quán)重,那么會用到一個均值為0、標(biāo)準(zhǔn)差為1的高斯分布,因此所有權(quán)重通常會滿足。基于這些信息,可知有。另外,在對所有這些項計算乘積后,最終結(jié)果肯定會呈指數(shù)級下降:項越多,乘積下降得越快。梯度消失的原因初見端倪。更具體一點,比較和稍后面一個偏置的梯度,例如。當(dāng)然,還未明確給出的表達(dá)式,但計算方式是和相同的。二者的對比如圖5-12所示。
這兩個表達(dá)式有很多項相同,但多了兩項。由于這些項都小于,因此
會是的或者更小,這其實就是梯度消失的根本原因。當(dāng)然,以上并非梯度消失問題的嚴(yán)謹(jǐn)證明,而是一個不太正式的論斷,可能還有別的一些原因。我們尤其想知道權(quán)重在訓(xùn)練中是否會增長,如果會,項
是否不再滿足
這個條件。實際上,如果項變得很大——超過1——那么梯度消失問題將不會出現(xiàn)。當(dāng)然,這時梯度會在反向傳播中呈指數(shù)級增長,即出現(xiàn)了梯度爆炸問題。5.2.2 梯度爆炸問題
下面分析梯度爆炸的原因。舉的例子可能不那么自然:固定神經(jīng)網(wǎng)絡(luò)中的參數(shù),以確保發(fā)生梯度爆炸。即使不太自然,這個例子也能說明梯度爆炸確實會發(fā)生(而非假設(shè))。
5.2.3 梯度不穩(wěn)定問題
根本問題其實不是梯度消失問題或梯度爆炸問題,而是前面的層上的梯度來自后面的層上項的乘積。當(dāng)層過多時,神經(jīng)網(wǎng)絡(luò)就會變得不穩(wěn)定。讓所有層的學(xué)習(xí)速度都近乎相同的唯一方式是所有這些項的乘積達(dá)到一種平衡。如果沒有某種機(jī)制或者更加本質(zhì)的保證來達(dá)到平衡,那么神經(jīng)網(wǎng)絡(luò)就很容易不穩(wěn)定。簡而言之,根本問題是神經(jīng)網(wǎng)絡(luò)受限于梯度不穩(wěn)定問題。因此,如果使用基于梯度的標(biāo)準(zhǔn)學(xué)習(xí)算法,那么不同的層會以不同的速度學(xué)習(xí)。
練 習(xí)
在關(guān)于梯度消失問題的討論中,我們采用了這個結(jié)論。假設(shè)使用一個不同的激活函數(shù),其導(dǎo)數(shù)值更大,這有助于避免梯度不穩(wěn)定問題嗎?
5.2.4 梯度消失問題普遍存在
如前所述,在神經(jīng)網(wǎng)絡(luò)中,前面的層可能會出現(xiàn)梯度消失或梯度爆炸。實際上,在使用sigmoid神經(jīng)元時,通常發(fā)生的是梯度消失,原因見表達(dá)式
。為了避免梯度消失問題,需要滿足。也許你認(rèn)為如果很大就行了,實際上更復(fù)雜。原因在于項同樣依賴:,其中是輸入激活值,所以在讓變大時,需要保持不變小。這會是很大的限制,因為變大的話,也會使得變得非常大。看看的圖像,就會發(fā)現(xiàn)它出現(xiàn)在的兩翼外,取到很小的值。為了避免出現(xiàn)這種情況,唯一的方法是讓輸入激活值落在相當(dāng)小的范圍內(nèi)(這個量化的解釋見下面第一個問題)。這種情況偶爾會出現(xiàn),但通常不會發(fā)生,所以梯度消失問題更常見。問 題
考慮乘積。假設(shè)有,請完成如下證明。
(1) 證明這種情況只在時才會出現(xiàn)。
(2) 假設(shè),考慮滿足的輸入激活值的集合。請證明:滿足上述條件的集合跨了一個不超過如下寬度的區(qū)間。
03
04
今日話題
看完本文,你有什么學(xué)習(xí)心得?
歡迎在留言區(qū)分享哦
留言點贊數(shù)量最多的前 5 名
將各獲得《深入淺出神經(jīng)網(wǎng)絡(luò)與深度學(xué)習(xí)》紙質(zhì)書籍一本
截止時間:09 月 10 日 18:00
小編會在留言區(qū)直接公布獲獎名單哦~
聯(lián)系客服