卷積神經網絡.經典神經網絡模型之ResNet

1. 提出ResNet的背景:

一般印象中,越複雜的特徵有着越強的表達特徵能力。在深度網絡中,各個特徵會不斷的經過線性非線性的綜合計算,越深的網絡輸出表示能力越強的特徵。所以網絡的深度對於學習表達能力更強的特徵至關重要,即神經網絡結構越深(複雜,參數多)越是有着更強的表達能力。這一點在VGGNet中得到很好的體現。

深度模型中,每層的輸出特徵圖的尺寸大都隨着網絡深度而變化,主要是長和寬越來越小,輸出特徵圖的深度隨着網絡層數的深度而增加。從另一方面講,長和寬的減小有助於減小計算量,而特徵圖深度的增加則使每層輸出中可用的特徵數量增多。

增加深度帶來的首個問題就是 梯度爆炸/梯度消失 的問題。這是由於隨着層數的增多,在網絡中反向傳播的梯度會隨着連乘變得不穩定,變得特別大或特別小。這其中經常出現的是梯度消失的問題。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

補充:什麼是梯度消失?

首先回顧一下反向傳播的知識

假設我們現在需要計算函數時的梯度,那麼首先可以做出如下所示的計算圖。

代入,其中,令,一步步計算,很容易就能得出

這就是前向傳播,即

前向傳播是從輸入一步步向前計算輸出,而反向傳播則是從輸出反向一點點推出輸入的梯度

注:這裏的反向傳播假設輸出端接受之前回傳的梯度爲1(也可以是輸出對輸出求導=1)

觀察上述反向傳播,不難發現,在輸出端梯度的模值,經過回傳擴大了3~4倍。

這是由於反向傳播結果的數值大小不止取決於求導的式子,很大程度上也取決於輸入的模值。當計算圖每次輸入的模值都大於1,那麼經過很多層回傳,梯度將不可避免地呈幾何倍數增長(每次都變成3~4倍,重複上萬次,想象一下310000有多大……),直到Nan。這就是梯度爆炸現象。

由於至今神經網絡都以反向傳播爲參數更新的基礎,所以梯度消失問題聽起來很有道理。然而,事實也並非如此,至少不止如此。

我們現在無論用Pytorch還是Tensorflow,都會自然而然地加上Bacth Normalization(簡稱BN),而BN的作用本質上也是控制每層輸入的模值,因此梯度的爆炸/消失現象理應在很早就被解決了(至少解決了大半)。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
恆等映射

Residual Learning的初衷,其實是讓模型的內部結構至少有恆等映射的能力。以保證在堆疊網絡的過程中,網絡至少不會因爲繼續堆疊而產生退化!

當下Resnet已經代替VGG成爲一般計算機視覺領域問題中的基礎特徵提取網絡。

2. 深度殘差學習 Deep Residual Learning

如上圖所示:

這裏有兩層神經網絡,開始於a^{[l]}a^{[l]}代表第L層中的激活函數,然後是經過一層網絡得到a^{[l+1]},兩層後是a^{[l+2]}

z^{[l+1]}a^{[l]}通過線性運算得到(通過乘一個加權矩陣,並加上一個偏置向量),之後將其應用於非線性ReLU來得到a^{[l+1]};再下一層,同樣應用這個線性步驟以及ReLU變換,得到第二層後的a^{[l+2]}。從a^{[l]}流向a^{[l+2]}的信息,它所需要經過的這些步驟,稱作主路徑main path。

在殘差網絡中,我們將a^{[l]}z^{[l+2]}之間建立一個快捷路徑shot cut(也叫跳躍連接skip connection:指a^{[l]}跳過一層或這跳過幾乎兩層把信息傳遞到更深的神經網絡中去),所以無需遵循主路徑,a^{[l]}中的信息現在可以遵循快捷路徑進入到更深層的神經網絡中。這就意味着 a^{[l+2]}=g(z^{[l+2]})轉變爲a^{[l+2]}=g(a^{[l]}+z^{[l+2]}),使a^{[l]}a^{[l+2]}的兩層神經網絡整體稱爲一個殘差塊。

使用殘差塊可以讓你訓練更深層的神經網絡,而建立一個ResNet的方法就是通過大量的這種殘差塊,然後把他們堆疊起來,形成一個深層網絡。如下所示:

上圖顯示了5個殘差塊堆積連接在一起,這就是一個殘差網絡。

事實證明,如果你使用標準的優化算法,如梯度下降法,以及很高級的優化算法之一來訓練普通網絡,沒有額外的跳躍連接、殘差塊等,一般從經驗上來說,你會發現當你增加層數時,訓練誤差會在下降一段時間後,會回升上去。在理論上,當你使神經網絡更深時,它在訓練數據上的性能應該只會更好,一個更深層次的網絡只會有幫助。但是實際上,有一個普通網絡,沒有ResNet,有一個很深的純網絡意味着你的優化算法訓練起來會更困難,訓練誤差會更糟糕。

但是有了ResNet之後,即使層數越來越深,你仍可以讓訓練誤差繼續下降,即使我們訓練一個超過100層的網絡(儘管很少有這麼深的網絡結構)。將這些激活X或者這些中間層的激活輸出,連接到更後面的層去, 這確實對解決梯度消失梯度爆炸問題非常有幫助,使得我們可以訓練深得多的神經元網絡而不會看到性能倒退的現象。儘管可能在某一點會達到平緩階段,這時候在加深網絡層次也不會有幫助,但是至少不會造成誤差上升的情況。

3.ResNet如此有效的原因

一般我們如果設計了更深層的網絡,它會使得你用訓練集訓練神經網絡的能力下降,這也是爲什麼我們不太希望有肽深層的神經網絡的原因。但是當訓練ResNet的時候就不一樣了,具體看下面的例子:

假設你有X作爲輸入,輸入到某個大型神經網絡Big NN並輸出a^{[l]};如果在這裏要調整,使得神經網絡層數更深一點,相同的Big NN,然後輸出a^{[l]},我們在這後面再增加幾層,這裏增加兩層輸出a^{[l+2]},將a^{[l]}連接到間隔一個神經網絡中去,形成一個有着跳躍連接的殘差塊。

在這整個神經網絡中我們使用ReLU激活函數,那麼所有激活(a)都將會\geqslant 0.

由於添加了一個殘差塊,現在 a^{[l+2]}=g(z^{[l+2]}+a^{[l]})=g(w^{[l+2]}*a^{[l+1]}+b^{[l+2]} + a^{[l]})

這裏要注意一下,如果你這裏用遠離K的L2正則化(regularisation),這將會減小w^{[l+2]}的值,如果你應用正則化於b的話也會導致b值減小,儘管實際上並不總是需要應用於b,但是這裏w纔是最需要關注的項。如果w^{[l+2]}爲0,同時我們假設b^{[l+2]}也等於0,那麼這裏所有的項都會消失因爲它們都等於0,那麼 a^{[l+2]} = g(a^{[l]})=a^{[l]}(使用的激活函數爲ReLU且我們假設所有激活都不是負數),這意味着殘差塊比較容易學習恆等函數。由於這個跳躍連接也很容易得到a^{[l+2]}=a^{[l]},這意味着將這兩層加入到你的神經網絡,與上面這個沒有這兩層的網絡相比,並不會非常影響神經網絡的能力,因爲對它來說學習恆等函數非常容易,只需要複製a^{[l]}a^{[l+2]},即便它中間有額外兩層。所以這就是爲什麼添加這額外的兩層,這個殘差塊到大型神經網絡中間或者尾部並不會影響神經網絡的表現。當然我們的目標並不只是維持原有的表現,而是幫助獲得更好的表現,可以想象,當這裏所有項都學習到有意義的數據時可能要比學習恆等函數更好。殘差塊網絡有效的主要原因是這些額外曾學習起恆等函數非常簡單,你幾乎總能保證它不會影響總體的表現,甚至很多時候幸運的話還可以提升網絡的表現,至少有個合理的底線,不會影響其表現,然後梯度下降從這裏開始可以改善最終的結果。

殘差網絡的另一個值得討論的細節是z^{[l+2]}+a^{[l]},我們是在假定z^{[l+2]}a^{[l]}在同一維度的,所以你將會看到在ResNet中許多相同卷積的應用,所以在殘差塊的兩個連接點的維度與輸出層的維度相同,這樣也會使得運算變得相對方便,然後運算這個兩個相同維度矢量的和。如果輸入和輸出有不同的維度,那麼我們需要添加一個W_{s}使得最終的維度相同,它可以是一個包含已學習到的參數的矩陣,也可以是一個固定的矩陣,其中包含很多0的項,即除了a^{[l]}以外,由0來填滿256維。這也是一種保證維度相同的方法(增加一個W_{s}的矩陣來保證維度相同/使用same conv保證輸入輸出維度相同,這樣在跳躍連接後的z^{[l+2]}+a^{[l]}計算能夠正常進行,畢竟只有同維度的矩陣纔可以做加法)

4. ResNet

ResNet使用了很多的same conv,保證輸入和輸出的維度相同,這樣在跳躍連接後,z^{[l+2]}+a^{[l]}維度相同,相加的算數得以成立。但是有時候中間神經單元經過線性計算後會經過池化層改變了維度,那麼我們可以使用W_{s}的矩陣保證維度相同。

 

參考博文如下:

Resnet到底在解決一個什麼問題呢?

深度學習網絡篇——ResNet

經典分類CNN模型系列其四:Resnet

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章