解讀殘差網絡(Residual Network),殘差連接(skip-connect)
在VGG中,卷積網絡達到了19層,在GoogLeNet中,網絡史無前例的達到了22層。
那么,網絡的精度會隨著網絡的層數增多而增多嗎?
在深度學習中,網絡層數增多一般會伴著下面幾個問題
- 計算資源的消耗
- 模型容易過擬合
- 梯度消失/梯度爆炸問題的產生
問題1可以通過GPU集群來解決,對于一個企業(yè)資源并不是很大的問題;問題2的過擬合通過采集海量數據,并配合Dropout正則化等方法也可以有效避免;問題3通過Batch Normalization也可以避免。貌似我們只要無腦的增加網絡的層數,我們就能從此獲益,但實驗數據給了我們當頭一棒。
作者發(fā)現(xiàn),隨著網絡層數的增加,網絡發(fā)生了退化(degradation)的現(xiàn)象:隨著網絡層數的增多,訓練集loss逐漸下降,然后趨于飽和,當你再增加網絡深度的話,訓練集loss反而會增大。注意這并不是過擬合,因為在過擬合中訓練loss是一直減小的。
當網絡退化時,淺層網絡能夠達到比深層網絡更好的訓練效果,這時如果我們把低層的特征傳到高層,那么效果應該至少不比淺層的網絡效果差,或者說如果一個VGG-100網絡在第98層使用的是和VGG-16第14層一模一樣的特征,那么VGG-100的效果應該會和VGG-16的效果相同。所以,我們可以在VGG-100的98層和14層之間添加一條直接映射(Identity Mapping)來達到此效果。
從信息論的角度講,由于DPI(數據處理不等式)的存在,在前向傳輸的過程中,隨著層數的加深,F(xiàn)eature Map包含的圖像信息會逐層減少,而ResNet的直接映射的加入,保證了 l+1 層的網絡一定比 l 層包含更多的圖像信息?;谶@種使用直接映射來連接網絡不同層直接的思想,殘差網絡應運而生。
殘差網絡
1.殘差塊
殘差網絡是由一系列殘差塊組成的(圖1)。
一個殘差塊可以用表示為:
2.殘差網絡
殘差網絡的搭建分為兩步:
使用VGG公式搭建Plain VGG網絡在Plain VGG的卷積網絡之間插入Identity Mapping,注意需要升維或者降維的時候加入 1×1 卷積。
在實現(xiàn)過程中,一般是直接stack殘差塊的方式。
3.為什么叫殘差網絡
一、背景
1.梯度消失問題
我們發(fā)現(xiàn)很深的網絡層,由于參數初始化一般更靠近0,這樣在訓練的過程中更新淺層網絡的參數時,很容易隨著網絡的深入而導致梯度消失,淺層的參數無法更新。
解釋:
可以看到,假設現(xiàn)在需要更新b1,w2,w3,w4參數因為隨機初始化偏向于0,通過鏈式求導我們會發(fā)現(xiàn),w1w2w3相乘會得到更加接近于0的數,那么所求的這個b1的梯度就接近于0,也就產生了梯度消失的現(xiàn)象。
2.網絡退化問題
舉個例子,假設已經有了一個最優(yōu)化的網絡結構,是18層。當我們設計網絡結構的時候,我們并不知道具體多少層次的網絡是最優(yōu)化的網絡結構,假設設計了34層網絡結構。
那么多出來的16層其實是冗余的,我們希望訓練網絡的過程中,模型能夠自己訓練這五層為恒等映射,也就是經過這層時的輸入與輸出完全一樣。
但是往往模型很難將這16層恒等映射的參數學習正確,那么就一定會不比最優(yōu)化的18層網絡結構性能好,這就是隨著網絡深度增加,模型會產生退化現(xiàn)象。
它不是由過擬合產生的,而是由冗余的網絡層學習了不是恒等映射的參數造成的。
二、ResNets 殘差網絡
ResNet使用了一個新的思想,ResNet的思想是假設我們涉及一個網絡層,存在最優(yōu)化的網絡層次,那么往往我們設計的深層次網絡是有很多網絡層為冗余層的。
那么我們希望這些冗余層能夠完成恒等映射,保證經過該恒等層的輸入和輸出完全相同。
具體哪些層是恒等層,這個會有網絡訓練的時候自己判斷出來。
殘差網絡有什么好處呢?
顯而易見:因為增加了 x 項,那么該網絡求 x 的偏導的時候,多了一項常數 1(對x的求導為1),所以反向傳播過程,梯度連乘,也不會造成梯度消失。
可以看到X是這一層殘差塊的輸入,也稱作F(x)為殘差,x為輸入值,F(xiàn)(X)是經過第一層線性變化并激活后的輸出,該圖表示在殘差網絡中,第二層進行線性變化之后激活之前,F(xiàn)(x)加入了這一層輸入值X,然后再進行激活后輸出。在第二層輸出值激活前加入X,這條路徑稱作shortcut連接。
三、網絡架構
1.普通網絡(Plain Network)
2.殘差網絡
把它變成ResNet的方法是加上所有跳躍連接,每兩層增加一個捷徑,構成一個殘差塊。如圖所示,5個殘差塊連接在一起構成一個殘差網絡。
3.對比分析
如果我們使用標準優(yōu)化算法訓練一個普通網絡,比如說梯度下降法,或者其它熱門的優(yōu)化算法。
如果沒有殘差,沒有這些捷徑或者跳躍連接,憑經驗你會發(fā)現(xiàn)隨著網絡深度的加深,訓練錯誤會先減少,然后增多。而理論上,隨著網絡深度的加深,應該訓練得越來越好才對。也就是說,理論上網絡深度越深越好。
但實際上,如果沒有殘差網絡,對于一個普通網絡來說,深度越深意味著用優(yōu)化算法越難訓練。實際上,隨著網絡深度的加深,訓練錯誤會越來越多。
但有了ResNets就不一樣了,即使網絡再深,訓練的表現(xiàn)卻不錯,比如說訓練誤差減少,就算是訓練深達100層的網絡也不例外。
有人甚至在1000多層的神經網絡中做過實驗,這樣就讓我們在訓練更深網絡的同時,又能保證良好的性能。
也許從另外一個角度來看,隨著網絡越深,網絡連接會變得臃腫,但是ResNet確實在訓練深度網絡方面非常有效。
四、解決問題
1.為什么可以解決梯度消失?
ResNet最終更新某一個節(jié)點的參數時,由于h(x)=F(x)+x,使得鏈式求導后的結果如圖所示,不管括號內右邊部分的求導參數有多小,因為左邊的1的存在,并且將原來的鏈式求導中的連乘變成了連加狀態(tài),都能保證該節(jié)點參數更新不會發(fā)生梯度消失或梯度爆炸現(xiàn)象。
2.為什么可以解決網絡退化問題?
我們發(fā)現(xiàn),假設該層是冗余的,在引入ResNet之前,我們想讓該層學習到的參數能夠滿足h(x)=x,即輸入是x,經過該冗余層后,輸出仍然為x。
但是可以看見,要想學習h(x)=x恒等映射時的這層參數時比較困難的。ResNet想到避免去學習該層恒等映射的參數,使用了如上圖的結構,讓h(x)=F(x)+x;這里的F(x)我們稱作殘差項,我們發(fā)現(xiàn),要想讓該冗余層能夠恒等映射,我們只需要學習F(x)=0。
學習F(x)=0比學習h(x)=x要簡單,因為一般每層網絡中的參數初始化偏向于0,這樣在相比于更新該網絡層的參數來學習h(x)=x,該冗余層學習F(x)=0的更新參數能夠更快收斂,如圖所示:
假設該曾網絡只經過線性變換,沒有bias也沒有激活函數。
我們發(fā)現(xiàn)因為隨機初始化權重一般偏向于0,那么經過該網絡的輸出值為[0.6 0.6],很明顯會更接近與[0 0],而不是[2 1],相比與學習h(x)=x,模型要更快到學習F(x)=0。并且ReLU能夠將負數激活為0,過濾了負數的線性變化,也能夠更快的使得F(x)=0。
這樣當網絡自己決定哪些網絡層為冗余層時,使用ResNet的網絡很大程度上解決了學習恒等映射的問題,用學習殘差F(x)=0更新該冗余層的參數來代替學習h(x)=x更新冗余層的參數。
這樣當網絡自行決定了哪些層為冗余層后,通過學習殘差F(x)=0來讓該層網絡恒等映射上一層的輸入,使得有了這些冗余層的網絡效果與沒有這些冗余層的網絡效果相同,這樣很大程度上解決了網絡的退化問題
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
python Django框架實現(xiàn)自定義表單提交
這篇文章主要為大家詳細介紹了Django框架實現(xiàn)自定義表單提交,針對"表單提交"和"Ajax提交"兩種方式來解決CSRF帶來的錯誤進行講解,感興趣的小伙伴們可以參考一下2016-03-03解決jupyterLab打開后出現(xiàn)Config option `template_path`not&
在JupyterLab中使用OpenCV環(huán)境時遇到模板路徑問題,經排查發(fā)現(xiàn)是nbconvert版本過高導致的,通過降級nbconvert到5.6.1版本成功解決2025-02-02Python3.5內置模塊之shelve模塊、xml模塊、configparser模塊、hashlib、hmac模塊用法
這篇文章主要介紹了Python3.5內置模塊之shelve模塊、xml模塊、configparser模塊、hashlib、hmac模塊,結合實例形式較為詳細的分析了shelve、xml、configparser、hashlib、hmac等模塊的功能及使用方法,需要的朋友可以參考下2019-04-04Python打包模塊wheel的使用方法與將python包發(fā)布到PyPI的方法詳解
這篇文章主要介紹了Python打包模塊wheel的使用方法與將python包發(fā)布到PyPI的方法詳解,需要的朋友可以參考下2020-02-02