第五章 深度神经网络为何很难训练
原文
假設你是一名工程師,接到一項從頭開始設計計算機的任務。某天,你在工作室工作,設計邏輯電路,構建 AND 門,OR 門等等時,老板帶著壞消息進來:客戶剛剛添加了一個奇特的設計需求:整個計算機的線路的深度必須只有兩層:
兩層線路
你驚呆了,跟老板說道:“這貨瘋掉了吧!”
老板說:“他們確實瘋了,但是客戶的需求比天大,我們要滿足它?!?br /> 實際上,在某種程度上看,他們的客戶并沒有太瘋狂。假設你可以使用貴重特殊的邏輯門可以 AND 起來你想要的那么多的輸入。同樣也能使用多值輸入的 NAND 門——可以AND 多個輸入然后求否定的門。有了這類特殊的門,構建出來的兩層的深度的網絡便可以計算任何函數。
但是僅僅因為某件事是理論上可能的,就代表這是一個好的想法。在實踐中,在解決線路設計問題(或者大多數的其他算法問題)時,我們通常考慮如何解決子問題,然后逐步地集成這些子問題的解。換句話說,我們通過多層的抽象來獲得最終的解答。
例如,我們來設計一個邏輯線路來做兩個數的乘法。我們希望在已經有了計算兩個數加法的子線路基礎上創建這個邏輯線路。計算兩個數和的子線路也是構建在用語兩個比特相加的子子線路上的。最終的線路就長成這個樣子:
加法線路
最終的線路包含至少三層線路的單元。實際上,這個線路很可能會超過三層,因為我們可以將子任務分解成比上述更小的單元。但是基本思想就是這樣。
因此深度線路讓這樣的設計過程變得更加簡單。但是這對于設計本身幫助并不大。其實,數學證明對于某些函數設計的非常淺的線路可能需要指數級的線路單元來計算。例如,在1980年代早期的一系列著名的論文已經給出了計算比特的集合的奇偶性通過淺的線路來計算需要指數級的門。另一當面,如果你使用更深的線路,那么可以使用規模很小的線路來計算奇偶性:僅僅需要計算比特的對的奇偶性,然后使用這些結果來計算比特對的對的奇偶性,以此類推,構建出總共的奇偶性。深度線路這樣就能從本質上獲得超過淺線路的更強的能力。
到現在為止,本書講神經網絡看作是瘋狂的客戶。幾乎我們遇到的所有的網絡就只包括一層隱含神經元(另外還有輸入輸出層):
淺層神經網絡
這些簡單的網絡已經非常有用了:在前面的章節中,我們使用這樣的網絡可以進行準確率高達 98% 的手寫數字的識別!而且,直覺上看,我們期望擁有更多隱含層的神經網絡能夠變的更加強大:
深度神經網絡
這樣的網絡可以使用中間層構建出多層的抽象,正如我們在布爾線路中做的那樣。例如,如果我們在進行視覺模式識別,那么在第一層的神經元可能學會識別邊,在第二層的神經元可以在邊的基礎上學會識別出更加復雜的形狀,例如三角形或者矩形。第三層將能夠識別更加復雜的形狀。依此類推。這些多層的抽象看起來能夠賦予深度網絡一種學習解決復雜模式識別問題的能力。然后,正如線路的示例中看到的那樣,存在著理論上的研究結果告訴我們深度網絡在本質上比淺層網絡更加強大。
對某些問題和網絡結構,Razvan Pascanu, Guido Montúfar, and Yoshua Bengio 在2014年的這篇文章 On the number of response regions of deep feed forward networks with piece-wise linear activations給出了證明。更加詳細的討論在Yoshua Bengio 2009年的著作 Learning deep architectures for AI 的第二部分。
那我們如何訓練這樣的深度神經網絡呢?在本章中,我們嘗試使用基于 BP 的隨機梯度下降的方法來訓練。但是這會產生問題,因為我們的深度神經網絡并不能比淺層網絡性能好太多。
這個失敗的結果好像與上面的討論相悖。這就能讓我們退縮么,不,我們要深入進去試著理解使得深度網絡訓練困難的原因。仔細研究一下,就會發現,在深度網絡中,不同的層學習的速度差異很大。尤其是,在網絡中后面的層學習的情況很好的時候,先前的層次常常會在訓練時停滯不變,基本上學不到東西。這種停滯并不是因為運氣不好。而是,有著更加根本的原因是的學習的速度下降了,這些原因和基于梯度的學習技術相關。
當我們更加深入地理解這個問題時,發現相反的情形同樣會出現:先前的層可能學習的比較好,但是后面的層卻停滯不變。實際上,我們發現在深度神經網絡中使用基于梯度下降的學習方法本身存在著內在不穩定性。這種不穩定性使得先前或者后面的層的學習過程阻滯。
這個的確是壞消息。但是真正理解了這些難點后,我們就能夠獲得高效訓練深度網絡的更深洞察力。而且這些發現也是下一章的準備知識,我們到時會介紹如何使用深度學習解決圖像識別問題。
(消失的戀人,哦不)消失的梯度問題
那么,在我們訓練深度網絡時究竟哪里出了問題?
為了回答這個問題,讓我們重新看看使用單一隱藏層的神經網絡示例。這里我們也是用 MNIST 數字分類問題作為研究和實驗的對象。
MNIST 問題和數據在這里(here )和這里( here).
這里你也可以在自己的電腦上訓練神經網絡。或者就直接讀下去。如果希望實際跟隨這些步驟,那就需要在電腦上安裝 python 2.7,numpy和代碼,可以通過下面的命令復制所需要的代碼
git clone https://github.com/mnielsen/neural-networks-and-deep-learning.git如果你不使用 git,那么就直接從這里(here)下載數據和代碼。然后需要轉入 src 子目錄。
接著從 python 的 shell 就可以載入 MNIST 數據:
然后設置我們的網絡:
>>> import network2 >>> net = network2.Network([784, 30, 10])這個網絡擁有 784 個輸入層神經元,對應于輸入圖片的 28 * 28 = 784 個像素點。我們設置隱藏層神經元為 30 個,輸出層為 10 個神經元,對應于 MNIST 數字 ('0', '1', ..., '9')。
讓我們訓練 30 輪,使用 mini batch 大小為 10, 學習率 \eta = 0.1,正規化參數 \lambda = 5.0。在訓練時,我們也會在驗證集上監控分類的準確度:
最終我們得到了分類的準確率為 96.48%(也可能不同,每次運行實際上會有一點點的偏差)這和我們前面的結果相似。
現在,我們增加另外一層隱藏層,同樣地是 30 個神經元,試著使用相同的超參數進行訓練:
最終的結果分類準確度提升了一點,96.90%。這點令人興奮:一點點的深度帶來了效果。那么就再增加一層同樣的隱藏層:
>>> 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)哦,這里并沒有什么提升,反而下降到了 96.57%,這與最初的淺層網絡相差無幾。再增加一層:
>>> 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)分類準確度又下降了,96.53%。這可能不是一個統計顯著地下降,但是會讓人們覺得沮喪。
這里表現出來的現象看起非常奇怪。直覺地,額外的隱藏層應當讓網絡能夠學到更加復雜的分類函數,然后可以在分類時表現得更好吧。可以肯定的是,事情并沒有變差,至少新的層次增加上,在最壞的情形下也就是沒有影響。事情并不是這樣子的。
那么,應該是怎樣的呢?假設額外的隱藏層的確能夠在原理上起到作用,問題是我們的學習算法沒有發現正確地權值和偏差。那么現在就要好好看看學習算法本身有哪里出了問題,并搞清楚如何改進了。
為了獲得一些關于這個問題直覺上的洞察,我們可以將網絡學到的東西進行可視化。下面,我畫出了一部分 [784, 30, 30, 10] 的網絡,也就是包含兩層各有 30 個隱藏神經元的隱藏層。圖中的每個神經元有一個條形統計圖,表示這個神經元在網絡進行學習時改變的速度。更大的條意味著更快的速度,而小的條則表示變化緩慢。更加準確地說,這些條表示了 每個神經元上的dC/db,也就是代價函數關于神經元的偏差更變的速率?;仡櫟诙?#xff08;Chapter 2),我們看到了這個梯度的數值不僅僅是在學習過程中偏差改變的速度,而且也控制了輸入到神經元權重的變量速度。如果沒有回想起這些細節也不要擔心:目前要記住的就是這些條表示了每個神經元權重和偏差在神經網絡學習時的變化速率。
為了讓圖里簡單,我只展示出來最上方隱藏層上的 6 個神經元。這里忽略了輸入層神經元,因為他們并不包含需要學習的權重或者偏差。同樣輸出層神經元也忽略了,因為這里我們做的是層層之間的比較,所以比較相同數量的兩層更加合理啦。在網絡初始化后立即得到訓練前期的結果如下:
這個程序給出了計算梯度的方法generate_gradient.py. 也包含了其他一些在本章后面提到的計算方法。
比較隱藏層
該網絡是隨機初始化的,因此看到了神經元學習的速度差異其實很大。而且,我們可以發現,第二個隱藏層上的條基本上都要比第一個隱藏層上的條要大。所以,在第二個隱藏層的神經元將學習得更加快速。這僅僅是一個巧合么,或者第二個隱藏層的神經元一般情況下都要比第一個隱藏層的神經元學習得更快?
為了確定我們的猜測,擁有一種全局的方式來比較學習速度會比較有效。我們這里將梯度表示為
梯度
在第 l 層的第 j 個神經元的梯度。我們可以將 \delta^1 看做是一個向量其中元素表示第一層隱藏層的學習速度,\delta^2 則是第二層隱藏層的學習速度。接著使用這些向量的長度作為全局衡量這些隱藏層的學習速度的度量。因此,||\delta^1|| 就代表第一層隱藏層學習速度,而||\delta^2|| 就代表第二層隱藏層學習速度。
借助這些定義,在和上圖同樣的配置下,||\delta^1|| = 0.07而||\delta^2|| = 0.31,所以這就確認了之前的疑惑:在第二層隱藏層的神經元學習速度確實比第一層要快。
如果我們添加更多的隱藏層呢?如果我們有三個隱藏層,比如說在一個 [784, 30, 30, 10] 的網絡中,那么對應的學習速度就是 0.012, 0.060, 0.283。這里前面的隱藏層學習速度還是要低于最后的隱藏層。假設我們增加另一個包含 30 個隱藏神經元的隱藏層。那么,對應的學習速度就是:0.003, 0.017, 0.070, 0.285。還是一樣的模式:前面的層學習速度低于后面的層。
現在我們已經看到了訓練開始時的學習速度,這是剛剛初始化之后的情況。那么這個速度會隨著訓練的推移發生什么樣的變化呢?讓我們看看只有兩個隱藏層。學習速度變化如下:
學習速度變化圖1
為了產生這些結果,我在 1000 個訓練圖像上進行了 500 輪 batch 梯度下降。這和我們通常訓練方式還是不同的——我沒有使用 minibatch,僅僅使用了 1000 個訓練圖像,而不是全部的 50,000 幅圖。我并不是想做點新鮮的嘗試,或者蒙蔽你們的雙眼,但因為使用 minibatch 隨機梯度下降會在結果中帶來更多的噪聲(盡管在平均噪聲的時候結果很相似)。使用我已經確定的參數可以對結果進行平滑,這樣我們可以看清楚真正的情況是怎樣的。
如圖所示,兩層在開始時就有著不同的速度。然后兩層的學習速度在觸底前迅速下落。在最后,我們發現第一層的學習速度變得比第二層更慢了。
那么更加復雜的網絡是什么情況呢?這里是一個類似的實驗,但是這次有三個隱藏層([784, 30, 30, 30, 10]):
學習速度變化圖2
同樣,前面的隱藏層要比后面的隱藏層學習的更慢。最后一個實驗,就是增加第四個隱藏層([784, 30, 30, 30, 30, 10]),看看這里會發生什么:
學習速度變化圖3
同樣的情況出現了,前面的隱藏層的學習速度要低于后面的隱藏層。這里,第一層的學習速度和最后一層要差了兩個數量級,也就是比第四層慢了100倍。難怪我們之前在訓練這些網絡的時候遇到了大麻煩!
現在我們已經有了一項重要的觀察結果:至少在某些深度神經網絡中,在我們在隱藏層 BP 的時候梯度傾向于變小。這意味著在前面的隱藏層中的神經元學習速度要慢于后面的隱藏層。這兒我們只在一個網絡中發現了這個現象,其實在多數的神經網絡中存在著更加根本的導致這個現象出現的原因。這個現象也被稱作是 消失的梯度問題(vanishing gradient problem)。
為何消失的梯度問題會出現呢?我們可以通過什么方式避免它?還有在訓練深度神經網絡時如何處理好這個問題?實際上,這個問題是可以避免的,盡管替代方法并不是那么有效,同樣會產生問題——在前面的層中的梯度會變得非常大!這也叫做 爆炸的梯度問題(exploding gradient problem),這也沒比消失的梯度問題更好處理。更加一般地說,在深度神經網絡中的梯度是不穩定的,在前面的層中或會消失,或會爆炸。這種不穩定性才是深度神經網絡中基于梯度學習的根本問題。這就是我們需要理解的東西,如果可能的話,采取合理的步驟措施解決問題。
一種有關消失的(不穩定的)梯度的看法是確定這是否確實是一個問題。此刻我們暫時轉換到另一個話題,假設我們正要數值優化一個一元的函數 f(x)。如果其導數 f'(x) 很小,這難道不是一個好消息么?是不是意味著我們已經接近極值點了?同樣的方式,在深度神經網絡中前面隱藏層的小的梯度是不是表示我們不需要對權重和偏差做太多調整了?
當然,實際情況并不是這樣的。想想我們隨機初始網絡中的權重和偏差。在面對任意的一種任務,單單使用隨機初始的值就能夠獲得一個較好的結果是太天真了。具體講,看看 MNIST 問題的網絡中第一層的權重。隨機初始化意味著第一層丟失了輸入圖像的幾乎所有信息。即使后面的層能夠獲得充分的訓練,這些層也會因為沒有充分的信息而很難識別出輸入的圖像。因此,在第一層不進行學習的嘗試是不可能的。如果我們接著去訓練深度神經網絡,我們需要弄清楚如何解決消失的梯度問題。
什么導致了消失的梯度問題?也就是在深度神經網絡中的所謂的梯度不穩定性
為了弄清楚為何會出現消失的梯度,來看看一個極簡單的深度神經網絡:每一層都只有一個單一的神經元。下圖就是有三層隱藏層的神經網絡:
簡單的深度神經網絡
這里,w_1, w_2, ... 是權重,而 b_1, b_2, ... 是偏差,C 則是某個代價函數?;仡櫼幌?#xff0c;從第 j 個神經元的輸出 a_j = \sigma(z_j),其中 \sigma 是通常的 sigmoid 函數,而 z_j = w_j * a_j-1 + b_j是神經元的帶權輸入。我已經在最后表示出了代價函數 C 來強調代價是網絡輸出 a_4 的函數:如果實際輸出越接近目標輸出,那么代價會變低;相反則會變高。
現在我們要來研究一下關聯于第一個隱藏神經元梯度 dC/db_1。我們將會計算出dC/db_1 的表達式,通過研究表達式來理解消失的梯度發生的原因。
開始就簡單地給出 dC/db_1 的表達式。初看起來有點復雜,但是其結構是相當簡單的,我一會兒會解釋。下圖給出了具體的表達式:
dC/db_1
表達式結構如下:對每個神經元有一個 \sigma'(z_j) 項;對每個權重有一個 w_j 項;還有一個 dC/da_4項,表示最后的代價函數。注意,我已經將表達式中的每個項置于了對應的位置。所以網絡本身就是表達式的解讀。
你可以直接認可這個表達式,直接跳到該表達式如何關聯于小時的梯度問題的。這對理解沒有影響,因為實際上上面的表達式只是前面對于BP 的討論的特例。但是也包含了一個表達式正確的解釋,所以去看看那個解釋也是很有趣的(也可能更有啟發性吧)。
假設我們對偏差 b_1 進行了微小的調整 \Delta b_1。這會導致網絡中剩下的元素一系列的變化。首先會對第一個隱藏元輸出產生一個 \Delta a_1 的變化。這樣就會導致第二個神經元的帶權輸入產生 \Delta z_2 的變化。從第二個神經元輸出隨之發生 \Delta a_2 的變化。以此類推,最終會對代價函數產生 \Delta C 的變化。這里我們有:
Paste_Image.png
這表示我們可以通過仔細追蹤每一步的影響來搞清楚 dC/db_1 的表達式。
現在我們看看 \Delta b_1 如何影響第一個神經元的輸出 a_1 的。我們有 a_1 = \sigma(z_1) = \sigma(w_1 * a_0 + b1),所以有
Paste_Image.png
\sigma'(z_1) 這項看起很熟悉:其實是我們上面關于 dC/db_1 的表達式的第一項。直覺上看,這項將偏差的改變 \Delta b_1 轉化成了輸出的變化 \Delta a_1。\Delta a_1 隨之又影響了帶權輸入 z_2 = w_2 * a_1 + b_2:
Paste_Image.png
將 \Delta z_2 和 \Delta a_1 的表達式組合起來,我們可以看到偏差 b_1 中的改變如何通過網絡傳輸影響到 z_2的:
Paste_Image.png
現在,又能看到類似的結果了:我們得到了在表達式 dC/db_1 的前面兩項。以此類推下去,跟蹤傳播改變的路徑就可以完成。在每個神經元,我們都會選擇一個 \sigma'(z_j) 的項,然后在每個權重我們選擇出一個 w_j 項。最終的結果就是代價函數中變化 \Delta C 的相關于偏差 \Delta b_1 的表達式:
Paste_Image.png
除以 \Delta b_1,我們的確得到了梯度的表達式:
Paste_Image.png
為何出現梯度消失:現在把梯度的整個表達式寫下來:
Paste_Image.png
除了最后一項,該表達式是一系列形如 w_j \sigma'(z_j) 的乘積。為了理解每個項的行為,先看看下面的sigmoid 函數導數的圖像:
Paste_Image.png
該導數在 \sigma'(0)=1/4 時達到最高?,F在,如果我們使用標準方法來初始化網絡中的權重,那么會使用一個均值為 0 標準差為 1 的高斯分布。因此所有的權重通常會滿足 |w_j| < 1。有了這些信息,我們發現會有 w_j \sigma'(z_j) < 1/4。并且在我們進行了所有這些項的乘積時,最終結果肯定會指數級下降:項越多,乘積的下降的越快。**這里我們敏銳地嗅到了消失的梯度問題的合理解釋。
更明白一點,我們比較一下 dC/db_1 和一個更后面一些的偏差的梯度,不妨設為 dC/db_3。當然,我們還沒有顯式地給出這個表達式,但是計算的方式是一樣的。
比較梯度的表達式
兩個表示式有很多相同的項。但是 dC/db_1 還多包含了兩個項。由于這些項都是 < 1/4 的。所以 dC/db_1 會是 dC/db_3 的 1/16 或者更小。這其實就是消失的梯度出現的本質原因了。
當然,這里并非嚴格的關于消失的梯度微調的證明而是一個不太正式的論斷。還有一些可能的產生原因了。特別地,我們想要知道權重 w_j 在訓練中是否會增長。如果會,項 w_j \sigma'(z_j) 會不會不在滿足之前 w_j \sigma'(z_j) < 1/4 的約束。事實上,如果項變得很大——超過 1,那么我們將不再遇到消失的梯度問題。實際上,這時候梯度會在我們 BP 的時候發生指數級地增長。也就是說,我們遇到了梯度爆炸的問題。
梯度爆炸問題:現在看看梯度爆炸如何出現的把。這里的例子可能不是那么自然:固定網絡中的參數,來確保產生爆炸的梯度。但是即使是不自然,也是包含了確定會產生爆炸梯度(而非假設的可能)的特質的。
共兩個步驟:首先,我們將網絡的權重設置得很大,比如 w_1 = w_2 = w_3 = w_4 = 100。然后,我們選擇偏差使得 sigma'(z_j) 項不會太小。這是很容易實現的:方法就是選擇偏差來保證每個神經元的帶權輸入是 z_j = 0(這樣 sigma'(z_j) = 1/4)。比如說,我們希望 z_1 = w_1 * a_0 + b_1。我們只要把 b_1 = -100 * a_0 即可。我們使用同樣的方法來獲得其他的偏差。這樣我們可以發現所有的項 w_j * \sigma'(z_j)都等于 100*1/4 = 25。最終,我們就獲得了爆炸的梯度。
不穩定的梯度問題:根本的問題其實并非是消失的梯度問題或者爆炸的梯度問題,而是在前面的層上的梯度是來自后面的層上項的乘積。當存在過多的層次時,就出現了內在本質上的不穩定場景。唯一讓所有層都接近相同的學習速度的方式是所有這些項的乘積都能得到一種平衡。如果沒有某種機制或者更加本質的保證來達成平衡,那網絡就很容易不穩定了。簡而言之,真實的問題就是神經網絡受限于不穩定梯度的問題。所以,如果我們使用標準的基于梯度的學習算法,在網絡中的不同層會出現按照不同學習速度學習的情況。
練習
- 在我們對于消失的梯度問題討論中,使用了 |\sigma'(z) < 1/4| 這個結論。假設我們使用一個不同的激活函數,其導數值是非常大的。這會幫助我們避免不穩定梯度的問題么?
消失的梯度問題普遍存在:我們已經看到了在神經網絡的前面的層中梯度可能會消失也可能會爆炸。實際上,在使用 sigmoid 神經元時,梯度通常會消失。為什么?再看看表達式 |w\sigma'(z)|。為了避免消失的梯度問題,我們需要 |w\sigma'(z)| >= 1。你可能會認為如果 w 很大的時候很容易達成。但是這比看起來還是困難很多。原因在于,\sigma'(z) 項同樣依賴于 w:\sigma'(z) = \sigma'(w*a+b),其中 a 是輸入的激活函數。所以我們在讓 w 變大時,需要同時不讓 \sigma'(w*a+b) 變小。這將是很大的限制了。原因在于我們讓 w 變大,也會使得 w*a + b 變得非常大??纯?\sigma' 的圖,這會讓我們走到 \sigma' 的兩翼,這里會去到很小的值。唯一避免發生這個情況的方式是,如果輸入激活函數掉入相當狹窄的范圍內(這個量化的解釋在下面第一個問題中進行)。有時候,有可能會出現。但是一般不大會發生。所以一般情況下,會遇到消失的梯度。
問題
- 考慮乘積 |\w\sigma'(wa+b)|。假設有 |\w\sigma'(wa+b)| >= 1。(1) 這種情況只有在 |w| >= 4 的時候才會出現。(2) 假設 |w| >= 4,考慮那些滿足 |\w\sigma'(wa+b)| >= 1 的輸入激活 a 集合。證明:滿足上述條件的該集合能夠充滿一個不超過
Paste_Image.png
寬度的區間。(3) 數值上說明上述表達式在 |w| ~= 6.9 時候去的最高值約 0.45。所以即使每個條件都滿足,我們仍然有一個狹窄的輸入激活區間,這樣來避免消失的梯度問題。 - 幺神經元:考慮一個單一輸入的神經元,x,對應的權重 w_1,偏差 b,輸出上的權重 w_2。證明,通過合理選擇權重和偏差,我們可以確保 w_2 \sigma(w_1*x +b)~=x for x \in [0, 1]。這樣的神經元可用來作為幺元試用,輸出和輸入相同(成比例)。Hint:可以重寫 x = 1/2 + \Delta,可以假設 w_1 很小,和在 w_1 * \Delta使用 Taylor 級數展開。
在更加復雜網絡中的不穩定梯度
現在已經研究了簡單的網絡,每一層只包含一個神經元。那么那些每層包含很多神經元的更加復雜的深度網絡呢?
Paste_Image.png
實際上,在這樣的神經網絡中,同樣的情況也會發生。在前面關于 BP 的章節中,我們看到了在一個共 L 層的第 l 層的梯度:
Paste_Image.png
這里 \Sigma'(z^l)是一個對角矩陣,每個元素是對第 l 層的帶權輸入 \sigma'(z)。而 w^l 是對不同層的權值矩陣。\nbala_a C 是對每個輸出激活的偏導數向量。
這是更加復雜的表達式。不過,你仔細看,本質上的形式還是很相似的。主要是包含了更多的形如 (w^j)^T \Sigma' (z^j) 的對 (pair)。而且,矩陣 \Sigma'(z^j) 在對角線上的值挺小,不會超過 1/4。由于權值矩陣 w^j 不是太大,每個額外的項 (w^j)^T \sigma' (z^l) 會讓梯度向量更小,導致梯度消失。更加一般地看,在乘積中大量的項會導致不穩定的梯度,和前面的例子一樣。實踐中,一般會發現在 sigmoid 網絡中前面的層的梯度指數級地消失。所以在這些層上的學習速度就會變得很慢了。這種減速不是偶然現象:也是我們采用的訓練的方法決定的。
深度學習其他的障礙
本章我們已經聚焦在消失的梯度上,并且更加一般地,不穩定梯度——深度學習的一大障礙。實際上,不穩定梯度僅僅是深度學習的眾多障礙之一,盡管這一點是相當根本的。當前的研究集中在更好地理解在訓練深度神經網絡時遇到的挑戰。這里我不會給出一個詳盡的總結,僅僅想要給出一些論文,告訴你人們正在尋覓探究的問題。
首先,在 2010 年 Glorot 和 Bengio 發現證據表明 sigmoid 函數的選擇會導致訓練網絡的問題。特別地,他們發現 sigmoid 函數會導致最終層上的激活函數在訓練中會聚集在 0,這也導致了學習的緩慢。他們的工作中提出了一些取代 sigmoid 函數的激活函數選擇,使得不會被這種聚集性影響性能。
第二個例子,在 2013 年 Sutskever, Martens, Dahl 和 Hinton 研究了深度學習使用隨機權重初始化和基于 momentum 的 SGD 方法。兩種情形下,好的選擇可以獲得較大的差異的訓練效果。
這些例子告訴我們,“什么讓訓練深度網絡非常困難”這個問題相當復雜。本章,我們已經集中于深度神經網絡中基于梯度的學習方法的不穩定性。結果表明了激活函數的選擇,權重的初始化,甚至是學習算法的實現方式也扮演了重要的角色。當然,網絡結構和其他超參數本身也是很重要的。因此,太多因子影響了訓練神經網絡的難度,理解所有這些因子仍然是當前研究的重點。盡管這看起來有點悲觀,但是在下一章中我們會介紹一些好的消息,給出一些方法來一定程度上解決和迂回所有這些困難。
文/Not_GOD(簡書作者)
原文鏈接:http://www.jianshu.com/p/917f71b06499
著作權歸作者所有,轉載請聯系作者獲得授權,并標注“簡書作者”。
總結
以上是生活随笔為你收集整理的第五章 深度神经网络为何很难训练的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 受限Boltzmann机(Restric
- 下一篇: 第六章 深度学习(上)