通往無限層神經網路 (1):對於殘差網路(Residual Network)的一種理解方法,與深層網路的訓練

目前我們在訓練極深層網路時,最有效的方法是使用殘差網路(Residual Network)結構。關於殘差網路,一種常見的理解方法是認為它等價於多個淺層網路的 ensemble(見 1605.06431),但這不足以解釋幾個現象,例如:

  • ReLU 和卷積的排列順序,為什麼按照 1603.05027 的方法比較好?

  • 為什麼要旁路掉 2 層網路才能得到不錯的結果?如果只旁路掉 1 層,為什麼效果並不好?

最近我在考慮其它問題時發現,其實可以用一個極其簡單的模型探討殘差結構的有效性。不知道之前有沒有人說過。如果您有什麼想法,歡迎討論。

我們都知道,用 2 層網路,配合足夠多的神經元,就可以擬合任何函數。那麼考慮這個問題:如果我們在每層只用 1 個神經元,但是用足夠深的網路,以及合理的網路架構,是否也可以擬合任何函數?答案也是肯定的,而且需要用殘差結構才能得到較好的結果(需要指出,理論能擬合,不代表實際能擬合。實際的擬合情況是這裡的關鍵)。

不妨看個具體例子,因為一般情況的證明稍後會看到是比較明顯的。只需看一個最簡單的回歸問題,使用 MSE 損失。我們的目標是在 (-3, 3) 區間擬合 sin(x):

方法 1 :

如果用直接的方法:

input => Max(0, w_1x+b_1) => Max(0, w_2x+b_2) => ... => w_nx+b_n => output

我們會發現多加幾層後就根本無法訓練,全部清零。原因很簡單,ReLU 會不斷丟失信息。當 ReLU 給出 0 之後,後面就全死了。如果網路的層數少,還可以得到這樣的結果:

如果層數一多,就肯定全部清零。

方法 2 :

那麼加上殘差結構吧,比如旁路掉 1 層:

input => x + Max(0, w_1x+b_1) => x + Max(0, w_2x+b_2) => .... => x + Max(0, w_nx+b_n) => output

這個肯定也不行。因為 x 只會變大,我們會得到類似這樣的結果:

可以用一些辦法改善,比如把最後一層的殘差和 ReLU 都去掉,但這無疑不是好的辦法。

方法 3 :

最簡單的解決方法就是旁路掉 2 層。因為如果熟悉 ReLU 就會知道,ReLU 是可以給出負值的,只需要 2 層即可。例如:-Max(0, -x) = Min(0, x)。

於是,最簡單的滿足我們要求的 2 層結構,就是 Convolution => ReLU => Convolution(這其實就是 1610.02915 PyramidNet 的結構了):

input => x + w_{1b} cdot Max(0, w_{1a}x+b_{1a}) + b_{1b} => .... => x + w_{nb} cdot Max(0, w_{na}x+b_{na}) + b_{nb} => output

可以得到類似這樣的結果:

易證這種方法可以擬合任何函數,因為它其實就是在不斷"折"一條線。不過,如果層數很多,仍然可能死掉,擬合效果卡住。

方法 4 :

把 ReLU 再換成 leaky 的,例如 PReLU。這就基本解決了死亡問題,可以保證多層訓練的效果,例如:

最後,如果我們把方法 1 中的 ReLU 換成 PReLU,是否可以解決死亡問題?遺憾的是不行。這裡涉及到數值穩定性。最好的方法仍然是方法 4 的旁路2層殘差+PReLU。

總結:

下一步自然的問題是做數值穩定性的分析。未來寫寫吧。深度網路的奧秘在於深度,因此在後文也會繼續探討訓練這種極窄極深的網路的辦法。

此外,在數學上容易看到殘差結構的必要性:假設網路的層數很多,那麼每一層就最好接近於 identity map,否則本徵值很容易發散或消亡(嚴格說,不一定如此,因為還可以用更精細的方法控制本徵值,不過這也是後話了)。

其實我真正在想的問題是如何構造和訓練無限深的網路。因此,本系列的下一篇是:通往無限層神經網路:一個小實驗 - 知乎專欄

如果本文對你有啟發,請點個贊,謝謝!~ 如果您有什麼想法,也很歡迎討論。


推薦閱讀:

XGBoost入門系列第一講
機器學習原來這麼有趣!第四章:用深度學習識別人臉
BP演算法的矩陣操作問題?
BLAS簡介

TAG:深度学习DeepLearning | 人工智能 | 机器学习 |