01.18 從頭開始實施ResNet模型

在我正在研究的深度學習項目中實施ResNet

架構時,它是我習慣的基本的,簡單的卷積神經網絡的巨大飛躍。

ResNet的一個突出特點是它在其更大的宏體系結構中使用了微架構 殘留塊

我決定親自調查模型,以便更好地理解它,並研究為什麼它在ILSVRC如此成功。我通過Adrian Rosebrock博士[1] 在Python 的計算機視覺深度學習中實現了完全相同的ResNet模型類,該模型遵循了來自2015年ResNet學術出版物,He等人的深度殘留學習圖像識別的ResNet模型。[2]。

RESNET

當ResNet首次引入時,對於當時深度神經網絡的一個巨大問題的證明是一個新的解決方案是革命性的:消失的梯度問題。雖然神經網絡是通用函數逼近器,但在某個閾值處添加更多層會使訓練變得更慢並使準確度飽和。

資料來源:https://towardsdatascience.com/an-overview-of-resnet-and-its-variants-5281e2f56035

這是由於梯度從最終層到最早層的反向傳播 - 將0到1之間的數字相乘多次使其變得越來越小:因此當到達較早的層時,梯度開始“消失”。這意味著較早的層不僅訓練較慢,而且更容易出錯。這是一個巨大的問題,因為最早的層是整個網絡的構建塊 - 它們負責識別基本的核心功能!

為了緩解這個問題,ResNet採用了身份快捷方式連接,基本上可以跳過一個或多個層的訓練 - 創建一個殘留塊

單個殘餘塊; He等人提出的原始文件。資料來源:[1]

然後,作者提出了一個“優化的”剩餘塊,添加了一個稱為瓶頸的擴展它會降低前兩個CONV層的維數(在最終CONV層中學習的濾波器的1/4),然後在最終的CONV層期間再次增加。這裡有兩個堆疊在一起的殘餘模塊。

資料來源:使用Python深入學習計算機視覺:從業者捆綁[1]

最後,何等人。發表了關於殘餘模塊的第二篇論文,稱為深度剩餘網絡中的身份映射,它提供了更好的殘差塊版本:預激活殘差模型。這允許漸變通過快捷方式連接傳播到任何較早的層而不受阻礙。

我們不是從卷積(權重)開始,而是從一系列(BN => RELU => CONV)* N層開始(假設正在使用瓶頸)。然後,剩餘模塊輸出被饋送到網絡中的下一個殘餘模塊的加法運算 (因為殘餘模塊彼此堆疊)。

(a)原始瓶頸殘留模塊。(e)完整的預激活殘留模塊。稱為預激活,因為BN和ReLU層出現在卷積之前。資料來源:[2]

整個網絡架構看起來像這樣,我們的模型將類似於它。

讓我們開始用Python編寫實際網絡。這個具體的實施靈感來自He等人。他們的Caffe分佈和來自Wei Wu的mxnet實現。

我們將把它寫成一個類(ResNet),以便我們稍後在訓練深度學習模型時調用它。

我們從標準的CNN導入開始,然後開始構建residual_module函數。看看參數:

  • data:輸入到殘餘模塊
  • K:最終CONV層將學習的濾波器數量(前兩個CONV層將學習K / 4濾波器)
  • 步幅:控制卷積的步幅(將幫助我們減少空間維度而不使用最大池)
  • chanDim:定義將執行批量標準化的軸
  • 紅色(即減少)將控制我們是否正在減小空間尺寸(真實)或不減小(假),因為並非所有殘餘模塊都會減小我們空間體積的尺寸
  • reg:對殘差模塊中的所有CONV層應用正則化強度
  • bnEps:控制Ɛ負責在規範化輸入時避免“除以零”錯誤
  • bnMom:控制移動平均線的動量

現在讓我們看看函數的其餘部分。

首先,我們初始化(標識)快捷方式(連接),它實際上只是對輸入數據的引用。在殘差模塊的末尾,我們只需將快捷方式添加到我們的預激活/瓶頸分支(第3行)的輸出中。

在第6-9行,ResNet模塊的第一個塊遵循BN ==> RELU ==> CONV ==>模式。CONV層通過K / 4濾波器使用1x1卷積。請注意,CONV層的偏置項已關閉,因為偏差已經在以下BN層中,因此不需要第二個偏置項。

根據瓶頸,第二個CONV層學習3 x 3的K / 4濾波器。

最後一個塊將再次增加維度,應用尺寸為1 x 1的K濾鏡。

為避免應用最大池,我們需要檢查是否需要減少空間維度。

如果我們被命令減少空間尺寸,則步幅> 1的卷積層將應用於快捷方式(第2-4行)。

最後,我們將快捷方式和最終CONV層相加,創建輸出到我們的ResNet模塊(第7行)。我們終於有了“構建模塊”來開始構建我們的深度剩餘網絡。

讓我們開始構建構建方法。

看一下參數階段和過濾器(兩個都是列表)。在我們的架構中(如上所示),我們將N個剩餘模塊堆疊在一起(N =階段值)。同一階段中的每個殘餘模塊學習相同數量的過濾器。在每個階段學習其各自的過濾器之後,接著是降維。我們重複此過程,直到我們準備應用平均合併層和softmax分類器。

階段和過濾器

例如,讓我們設置階段=(3,4,6)和濾波器=(64,128,256,512)。第一個濾波器(64)應用於唯一的CONV層,而不是剩餘模塊的一部分 - 網絡中的第一個CONV層。然後,三個(階段= 3)殘差模塊堆疊在彼此之上 - 每個模塊將學習128個過濾器。空間維度將減少,然後我們將四個(階段= 4)殘差模塊堆疊在一起 - 每個學習256個過濾器。最後,我們再次減少空間維度,繼續將六個(階段= 6)殘差模塊堆疊在一起,每個模塊學習512個過濾器。

ResNet架構。帶圓圈的數字是過濾器值,而括號顯示堆棧。注意每個階段後如何減少維數。與之前的書面例子無關。

讓我們回到構建構建方法。

根據我們是使用“最後通道”還是“通道優先”排序(第3-4行)初始化inputShape和chanDim。

如上所述,ResNet使用BN作為第一層作為輸入標準化的附加級別(第2-4行)。然後,我們應用CONV =>,BN => ACT => POOL來減小空間大小(第7-13行)。現在,讓我們開始將殘留層堆疊在一起。

為了在不使用池化層的情況下減小體積大小,我們可以改變卷積的步幅。階段中的第一個條目將具有(1,1)的步幅 - 表示沒有下采樣。然後,在此之後的每個階段,我們將應用具有(2,2)步幅的殘餘模塊,這將減小體積大小。這在第5行顯示。

然後,我們在第10-13行循環遍歷當前階段的層數(將堆疊在彼此之上的剩餘模塊的數量)。我們使用[i + 1]作為過濾器的索引,因為已經使用了第一個過濾器。一旦我們將階段[i]殘餘模塊堆疊在彼此之上,我們將返回到第6-7行,在那裡我們減小體積的空間維度並重復該過程。

為避免密集的完全連接層,我們將應用平均池而不是將卷大小減小到1 x 1 x類:

最後,我們將為我們要學習的類的總數創建一個密集層,然後應用softmax激活來生成我們的最終輸出概率!

結束了我們的構建功能,現在我們擁有完全構建的ResNet模型!您可以調用此類在深度學習項目中實現ResNet體系結構。


分享到:


相關文章: