ResNet--從理論到實踐

1、理論

理論部分參考:https://blog.csdn.net/weixin_43624538/article/details/85049699 (我下邊這篇寫得有點簡略,完整公式還是直接點擊原博鏈接吧,我不想複製了,因爲會導致格式亂八七糟的。強烈懇求CSDN能出一個一鍵轉載的功能!!!)

ResNet論文地址: https://arxiv.org/pdf/1512.03385.pdf 

添加了自己的理解,如果有理解不對的地方,還請指出!

 

ResNet主要思想恆等映射(identity mapping) 。當我們直接對網絡進行簡單的堆疊到特別長,網絡內部的特徵在其中某一層已經達到了最佳的情況,這時候剩下層應該不對改特徵做任何改變,自動學成恆等映射的形式,至少讓深度網絡實現和淺層網絡一樣的性能,即讓深度網絡後面的層至少實現恆等映射的作用。

前向傳播:

å¨è¿éæå¥å¾çæè¿°

根據上圖,copy一個淺層網絡的輸出加給深層的輸出,這樣當網絡特徵達到optimal的時候更深層恆等映射的任務就從原來堆疊的層中釋放到新建的這個恆等映射關係中,而原來層中的任務就從恆等映射轉爲全0。
F(x)=H(x)−x,x爲淺層的輸出,H(x)爲深層的輸出,F(x) 爲夾在二者中間的的兩層代表的變換,當淺層的x代表的特徵已經足夠成熟,如果任何對於特徵x 的改變都會讓loss變大的話,F(x) 會自動趨向於學習成爲0,x 則從恆等映射的路徑繼續傳遞。這樣就在不增加計算成本的情況下實現了一開始的目的:在前向過程中,當淺層的輸出已經足夠成熟(optimal),讓深層網絡後面的層能夠實現恆等映射的作用。
 

反向傳播

residual模塊將輸出分成F(x)+x 兩部分,其中F依然是x的函數,也就是說F實際上是對於x 的補充,是對於x 的fun-tuning,這樣就把任務從根據x 映射成一個新的y 轉爲了根據x 求x 和y 之間的差距,這明顯是一個相對更加簡單的任務,論文是這麼寫的,到底怎麼簡單的,我們來分析一下。

舉個例子,假設不加residual模塊的輸出爲h(x) 。x=10,h(x)=11 ,h 簡化爲線性運算Wh ,Wh 明顯爲1.1,加了redidual模塊後,F(x)=1 ,H(x)=F(x)+x=11 ,F也簡化爲線性運算,對應的WF爲0.1。當標籤中的真實值爲12,反向傳播的損失爲1,而對於F中的參數和h中參數回傳的損失實際上是一樣大的而且梯度都是x的值,但是對於F的參數就從0.1到0.2,而h的參數是從1.1到1.2,因此redidual模塊會明顯減小模塊中參數的值從而讓網絡中的參數對反向傳導的損失值有更敏感的響應能力,雖然根本上沒有解決回傳的損失小得問題,但是卻讓參數減小,相對而言增加了回傳損失的效果,也產生了一定的正則化作用。

其次,因爲前向過程中有恆等映射的支路存在,因此在反向傳播過程中梯度的傳導也多了更簡便的路徑,僅僅經過一個relu就可以把梯度傳達給上一個模塊。

所謂反向傳播就是網絡輸出一個值,然後與真實值做比較的到一個誤差損失,同時將這個損失做差改變參數,返回的損失大小取決於原來的損失和梯度,既然目的是爲了改變參數,而問題是改變參數的力度過小,則可以減小參數的值,使損失對參數改變的力度相對更大。

因此殘差模塊最重要的作用就是改變了前向和後向信息傳遞的方式從而很大程度上促進了網絡的優化。
 

圖左:basic block ,用於18/34層。    圖右:bottleneck,用於50/101/152層。

左側的通道數是64,右側的通道數是256,bottleneck殘差模塊將兩個3*3的卷積核換成了1*1+3*3+1*1的形式,第一個1*1用來降維,3*3用來在降維後的特徵上卷積,後一個1*1用來升維(下邊會介紹)。這樣操作,會使參數大大減少,

basic block參數個數

3*3*256*64+3*3*256*64=294912

bottleneck參數個數

1*1*256*64+3*3*64*64+1*1*64*256=69632

å¨è¿éæå¥å¾çæè¿°

需要注意的一點是對於block和block之間的特徵大小不同,即網絡深度不同時(如下圖34-layer residual的虛線),因爲是在F內部發生變化,x也需要隨之變化才能對應相加,論文中採用的調整方法是採用0填充來擬補深度,但是如何縮小特徵尺寸沒有說,而且官網的復現方式都是直接用一個1*1的卷積核來操作這一步(即:升維),理論上講會破壞恆等映射。

 

2、代碼

除了原博中提到的基於pytorch的實現代碼: https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py 

還有基於tensorflow實現的代碼: https://github.com/tensorpack/tensorpack/tree/master/examples/ResNet 

博客 https://blog.csdn.net/superman_xxx/article/details/65452735 中也有50/101/152源碼。

 

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