解讀殘差網(wǎng)絡(Residual Network),殘差連接(skip-connect)
在VGG中,卷積網(wǎng)絡達到了19層,在GoogLeNet中,網(wǎng)絡史無前例的達到了22層。
那么,網(wǎng)絡的精度會隨著網(wǎng)絡的層數(shù)增多而增多嗎?
在深度學習中,網(wǎng)絡層數(shù)增多一般會伴著下面幾個問題
- 計算資源的消耗
- 模型容易過擬合
- 梯度消失/梯度爆炸問題的產生
問題1可以通過GPU集群來解決,對于一個企業(yè)資源并不是很大的問題;問題2的過擬合通過采集海量數(shù)據(jù),并配合Dropout正則化等方法也可以有效避免;問題3通過Batch Normalization也可以避免。貌似我們只要無腦的增加網(wǎng)絡的層數(shù),我們就能從此獲益,但實驗數(shù)據(jù)給了我們當頭一棒。
作者發(fā)現(xiàn),隨著網(wǎng)絡層數(shù)的增加,網(wǎng)絡發(fā)生了退化(degradation)的現(xiàn)象:隨著網(wǎng)絡層數(shù)的增多,訓練集loss逐漸下降,然后趨于飽和,當你再增加網(wǎng)絡深度的話,訓練集loss反而會增大。注意這并不是過擬合,因為在過擬合中訓練loss是一直減小的。
當網(wǎng)絡退化時,淺層網(wǎng)絡能夠達到比深層網(wǎng)絡更好的訓練效果,這時如果我們把低層的特征傳到高層,那么效果應該至少不比淺層的網(wǎng)絡效果差,或者說如果一個VGG-100網(wǎng)絡在第98層使用的是和VGG-16第14層一模一樣的特征,那么VGG-100的效果應該會和VGG-16的效果相同。所以,我們可以在VGG-100的98層和14層之間添加一條直接映射(Identity Mapping)來達到此效果。
從信息論的角度講,由于DPI(數(shù)據(jù)處理不等式)的存在,在前向傳輸?shù)倪^程中,隨著層數(shù)的加深,F(xiàn)eature Map包含的圖像信息會逐層減少,而ResNet的直接映射的加入,保證了 l+1 層的網(wǎng)絡一定比 l 層包含更多的圖像信息?;谶@種使用直接映射來連接網(wǎng)絡不同層直接的思想,殘差網(wǎng)絡應運而生。
殘差網(wǎng)絡
1.殘差塊
殘差網(wǎng)絡是由一系列殘差塊組成的(圖1)。
一個殘差塊可以用表示為:


2.殘差網(wǎng)絡
殘差網(wǎng)絡的搭建分為兩步:
使用VGG公式搭建Plain VGG網(wǎng)絡在Plain VGG的卷積網(wǎng)絡之間插入Identity Mapping,注意需要升維或者降維的時候加入 1×1 卷積。
在實現(xiàn)過程中,一般是直接stack殘差塊的方式。
3.為什么叫殘差網(wǎng)絡

一、背景
1.梯度消失問題
我們發(fā)現(xiàn)很深的網(wǎng)絡層,由于參數(shù)初始化一般更靠近0,這樣在訓練的過程中更新淺層網(wǎng)絡的參數(shù)時,很容易隨著網(wǎng)絡的深入而導致梯度消失,淺層的參數(shù)無法更新。

解釋:
可以看到,假設現(xiàn)在需要更新b1,w2,w3,w4參數(shù)因為隨機初始化偏向于0,通過鏈式求導我們會發(fā)現(xiàn),w1w2w3相乘會得到更加接近于0的數(shù),那么所求的這個b1的梯度就接近于0,也就產生了梯度消失的現(xiàn)象。
2.網(wǎng)絡退化問題
舉個例子,假設已經(jīng)有了一個最優(yōu)化的網(wǎng)絡結構,是18層。當我們設計網(wǎng)絡結構的時候,我們并不知道具體多少層次的網(wǎng)絡是最優(yōu)化的網(wǎng)絡結構,假設設計了34層網(wǎng)絡結構。
那么多出來的16層其實是冗余的,我們希望訓練網(wǎng)絡的過程中,模型能夠自己訓練這五層為恒等映射,也就是經(jīng)過這層時的輸入與輸出完全一樣。
但是往往模型很難將這16層恒等映射的參數(shù)學習正確,那么就一定會不比最優(yōu)化的18層網(wǎng)絡結構性能好,這就是隨著網(wǎng)絡深度增加,模型會產生退化現(xiàn)象。
它不是由過擬合產生的,而是由冗余的網(wǎng)絡層學習了不是恒等映射的參數(shù)造成的。
二、ResNets 殘差網(wǎng)絡
ResNet使用了一個新的思想,ResNet的思想是假設我們涉及一個網(wǎng)絡層,存在最優(yōu)化的網(wǎng)絡層次,那么往往我們設計的深層次網(wǎng)絡是有很多網(wǎng)絡層為冗余層的。
那么我們希望這些冗余層能夠完成恒等映射,保證經(jīng)過該恒等層的輸入和輸出完全相同。
具體哪些層是恒等層,這個會有網(wǎng)絡訓練的時候自己判斷出來。

殘差網(wǎng)絡有什么好處呢?
顯而易見:因為增加了 x 項,那么該網(wǎng)絡求 x 的偏導的時候,多了一項常數(shù) 1(對x的求導為1),所以反向傳播過程,梯度連乘,也不會造成梯度消失。
可以看到X是這一層殘差塊的輸入,也稱作F(x)為殘差,x為輸入值,F(xiàn)(X)是經(jīng)過第一層線性變化并激活后的輸出,該圖表示在殘差網(wǎng)絡中,第二層進行線性變化之后激活之前,F(xiàn)(x)加入了這一層輸入值X,然后再進行激活后輸出。在第二層輸出值激活前加入X,這條路徑稱作shortcut連接。
三、網(wǎng)絡架構
1.普通網(wǎng)絡(Plain Network)

2.殘差網(wǎng)絡

把它變成ResNet的方法是加上所有跳躍連接,每兩層增加一個捷徑,構成一個殘差塊。如圖所示,5個殘差塊連接在一起構成一個殘差網(wǎng)絡。
3.對比分析

如果我們使用標準優(yōu)化算法訓練一個普通網(wǎng)絡,比如說梯度下降法,或者其它熱門的優(yōu)化算法。
如果沒有殘差,沒有這些捷徑或者跳躍連接,憑經(jīng)驗你會發(fā)現(xiàn)隨著網(wǎng)絡深度的加深,訓練錯誤會先減少,然后增多。而理論上,隨著網(wǎng)絡深度的加深,應該訓練得越來越好才對。也就是說,理論上網(wǎng)絡深度越深越好。
但實際上,如果沒有殘差網(wǎng)絡,對于一個普通網(wǎng)絡來說,深度越深意味著用優(yōu)化算法越難訓練。實際上,隨著網(wǎng)絡深度的加深,訓練錯誤會越來越多。
但有了ResNets就不一樣了,即使網(wǎng)絡再深,訓練的表現(xiàn)卻不錯,比如說訓練誤差減少,就算是訓練深達100層的網(wǎng)絡也不例外。
有人甚至在1000多層的神經(jīng)網(wǎng)絡中做過實驗,這樣就讓我們在訓練更深網(wǎng)絡的同時,又能保證良好的性能。
也許從另外一個角度來看,隨著網(wǎng)絡越深,網(wǎng)絡連接會變得臃腫,但是ResNet確實在訓練深度網(wǎng)絡方面非常有效。
四、解決問題
1.為什么可以解決梯度消失?

ResNet最終更新某一個節(jié)點的參數(shù)時,由于h(x)=F(x)+x,使得鏈式求導后的結果如圖所示,不管括號內右邊部分的求導參數(shù)有多小,因為左邊的1的存在,并且將原來的鏈式求導中的連乘變成了連加狀態(tài),都能保證該節(jié)點參數(shù)更新不會發(fā)生梯度消失或梯度爆炸現(xiàn)象。
2.為什么可以解決網(wǎng)絡退化問題?
我們發(fā)現(xiàn),假設該層是冗余的,在引入ResNet之前,我們想讓該層學習到的參數(shù)能夠滿足h(x)=x,即輸入是x,經(jīng)過該冗余層后,輸出仍然為x。
但是可以看見,要想學習h(x)=x恒等映射時的這層參數(shù)時比較困難的。ResNet想到避免去學習該層恒等映射的參數(shù),使用了如上圖的結構,讓h(x)=F(x)+x;這里的F(x)我們稱作殘差項,我們發(fā)現(xiàn),要想讓該冗余層能夠恒等映射,我們只需要學習F(x)=0。
學習F(x)=0比學習h(x)=x要簡單,因為一般每層網(wǎng)絡中的參數(shù)初始化偏向于0,這樣在相比于更新該網(wǎng)絡層的參數(shù)來學習h(x)=x,該冗余層學習F(x)=0的更新參數(shù)能夠更快收斂,如圖所示:

假設該曾網(wǎng)絡只經(jīng)過線性變換,沒有bias也沒有激活函數(shù)。
我們發(fā)現(xiàn)因為隨機初始化權重一般偏向于0,那么經(jīng)過該網(wǎng)絡的輸出值為[0.6 0.6],很明顯會更接近與[0 0],而不是[2 1],相比與學習h(x)=x,模型要更快到學習F(x)=0。并且ReLU能夠將負數(shù)激活為0,過濾了負數(shù)的線性變化,也能夠更快的使得F(x)=0。
這樣當網(wǎng)絡自己決定哪些網(wǎng)絡層為冗余層時,使用ResNet的網(wǎng)絡很大程度上解決了學習恒等映射的問題,用學習殘差F(x)=0更新該冗余層的參數(shù)來代替學習h(x)=x更新冗余層的參數(shù)。
這樣當網(wǎng)絡自行決定了哪些層為冗余層后,通過學習殘差F(x)=0來讓該層網(wǎng)絡恒等映射上一層的輸入,使得有了這些冗余層的網(wǎng)絡效果與沒有這些冗余層的網(wǎng)絡效果相同,這樣很大程度上解決了網(wǎng)絡的退化問題
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
python中將\\uxxxx轉換為Unicode字符串的方法
這篇文章主要介紹了python中將\\uxxxx轉換為Unicode字符串的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09
python目標檢測yolo3詳解預測及代碼復現(xiàn)
這篇文章主要為大家介紹了python目標檢測yolo3詳解預測及代碼復現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05

