SENet(Squeeze-and-Excitation Networks)算法筆記---通過學習的方式來自動獲取到每個特征通道的重要程度,然后依照這個重要程度去提升有用的特征並抑制對當前任務用處不大的特征


Momenta詳解ImageNet 2017奪冠架構SENet

轉自機器之心專欄

作者:胡傑

本屆 CVPR 2017大會上出現了很多值得關注的精彩論文,國內自動駕駛創業公司 Momenta 聯合機器之心推出 CVPR 2017 精彩論文解讀專欄。除此之外,Momenta 還受邀在 CVPR 2017 的 ImageNet Workshop 中發表演講,介紹 Momenta 在ImageNet 2017 挑戰賽中奪冠的網絡架構SENet。本文作者為 Momenta 高級研發工程師胡傑。

我是 Momenta 的高級研發工程師胡傑,很高興可以和大家分享我們的 SENet。借助我們提出的 SENet,我們團隊(WMW)以極大的優勢獲得了最后一屆 ImageNet 2017 競賽 Image Classification 任務的冠軍,並被邀請在 CVPR 2017 的 workshop(Beyond ImageNet)中給出算法介紹。下面我將介紹我們提出的 SENet,論文和代碼會在近期公布在 arXiv 上,歡迎大家 follow 我們的工作,並給出寶貴的建議和意見。

我們從最基本的卷積操作開始說起。近些年來,卷積神經網絡在很多領域上都取得了巨大的突破。而卷積核作為卷積神經網絡的核心,通常被看做是在局部感受野上,將空間上(spatial)的信息和特征維度上(channel-wise)的信息進行聚合的信息聚合體。卷積神經網絡由一系列卷積層、非線性層和下采樣層構成,這樣它們能夠從全局感受野上去捕獲圖像的特征來進行圖像的描述。

然而去學到一個性能非常強勁的網絡是相當困難的,其難點來自於很多方面。最近很多工作被提出來從空間維度層面來提升網絡的性能,如 Inception 結構中嵌入了多尺度信息,聚合多種不同感受野上的特征來獲得性能增益;在 Inside-Outside 網絡中考慮了空間中的上下文信息;還有將 Attention 機制引入到空間維度上,等等。這些工作都獲得了相當不錯的成果。

我們可以看到,已經有很多工作在空間維度上來提升網絡的性能。那么很自然想到,網絡是否可以從其他層面來考慮去提升性能,比如考慮特征通道之間的關系?我們的工作就是基於這一點並提出了 Squeeze-and-Excitation Networks(簡稱 SENet)。在我們提出的結構中,Squeeze 和 Excitation 是兩個非常關鍵的操作,所以我們以此來命名。我們的動機是希望顯式地建模特征通道之間的相互依賴關系。另外,我們並不打算引入一個新的空間維度來進行特征通道間的融合,而是采用了一種全新的「特征重標定」策略。具體來說,就是通過學習的方式來自動獲取到每個特征通道的重要程度,然后依照這個重要程度去提升有用的特征並抑制對當前任務用處不大的特征

上圖是我們提出的 SE 模塊的示意圖。給定一個輸入 x,其特征通道數為 c_1,通過一系列卷積等一般變換后得到一個特征通道數為 c_2 的特征。與傳統的 CNN 不一樣的是,接下來我們通過三個操作來重標定前面得到的特征。

首先是 Squeeze 操作,我們順着空間維度來進行特征壓縮,將每個二維的特征通道變成一個實數,這個實數某種程度上具有全局的感受野,並且輸出的維度和輸入的特征通道數相匹配。它表征着在特征通道上響應的全局分布,而且使得靠近輸入的層也可以獲得全局的感受野,這一點在很多任務中都是非常有用的。

其次是 Excitation 操作,它是一個類似於循環神經網絡中門的機制。通過參數 w 來為每個特征通道生成權重,其中參數 w 被學習用來顯式地建模特征通道間的相關性。

最后是一個 Reweight 的操作,我們將 Excitation 的輸出的權重看做是進過特征選擇后的每個特征通道的重要性,然后通過乘法逐通道加權到先前的特征上,完成在通道維度上的對原始特征的重標定。

上左圖是將 SE 模塊嵌入到 Inception 結構的一個示例。方框旁邊的維度信息代表該層的輸出。

這里我們使用 global average pooling 作為 Squeeze 操作。緊接着兩個 Fully Connected 層組成一個 Bottleneck 結構去建模通道間的相關性,並輸出和輸入特征同樣數目的權重。我們首先將特征維度降低到輸入的 1/16,然后經過 ReLu 激活后再通過一個 Fully Connected 層升回到原來的維度。這樣做比直接用一個 Fully Connected 層的好處在於:1)具有更多的非線性,可以更好地擬合通道間復雜的相關性;2)極大地減少了參數量和計算量。然后通過一個 Sigmoid 的門獲得 0~1 之間歸一化的權重,最后通過一個 Scale 的操作來將歸一化后的權重加權到每個通道的特征上。

除此之外,SE 模塊還可以嵌入到含有 skip-connections 的模塊中。上右圖是將 SE 嵌入到 ResNet 模塊中的一個例子,操作過程基本和 SE-Inception 一樣,只不過是在 Addition 前對分支上 Residual 的特征進行了特征重標定。如果對 Addition 后主支上的特征進行重標定,由於在主干上存在 0~1 的 scale 操作,在網絡較深 BP 優化時就會在靠近輸入層容易出現梯度消散的情況,導致模型難以優化。

目前大多數的主流網絡都是基於這兩種類似的單元通過 repeat 方式疊加來構造的。由此可見,SE 模塊可以嵌入到現在幾乎所有的網絡結構中。通過在原始網絡結構的 building block 單元中嵌入 SE 模塊,我們可以獲得不同種類的 SENet。如 SE-BN-Inception、SE-ResNet、SE-ReNeXt、SE-Inception-ResNet-v2 等等。

從上面的介紹中可以發現,SENet 構造非常簡單,而且很容易被部署,不需要引入新的函數或者層。除此之外,它還在模型和計算復雜度上具有良好的特性。拿 ResNet-50 和 SE-ResNet-50 對比舉例來說,SE-ResNet-50 相對於 ResNet-50 有着 10% 模型參數的增長。額外的模型參數都存在於 Bottleneck 設計的兩個 Fully Connected 中,由於 ResNet 結構中最后一個 stage 的特征通道數目為 2048,導致模型參數有着較大的增長,實驗發現移除掉最后一個 stage 中 3 個 build block 上的 SE 設定,可以將 10% 參數量的增長減少到 2%。此時模型的精度幾乎無損失。

另外,由於在現有的 GPU 實現中,都沒有對 global pooling 和較小計算量的 Fully Connected 進行優化,這導致了在 GPU 上的運行時間 SE-ResNet-50 相對於 ResNet-50 有着約 10% 的增長。盡管如此,其理論增長的額外計算量僅僅不到 1%,這與其在 CPU 運行時間上的增長相匹配(~2%)。可以看出,在現有網絡架構中嵌入 SE 模塊而導致額外的參數和計算量的增長微乎其微。

在訓練中,我們使用了一些常見的數據增強方法和 Li Shen 提出的均衡數據策略。為了提高訓練效率,我們使用了我們自己優化的分布式訓練系統 ROCS, 並采用了更大的 batch-size 和初始學習率。所有的模型都是從頭開始訓練的。

接下來,為了驗證 SENets 的有效性,我們將在 ImageNet 數據集上進行實驗,並從兩個方面來進行論證。一個是性能的增益 vs. 網絡的深度; 另一個是將 SE 嵌入到現有的不同網絡中進行結果對比。另外,我們也會展示在 ImageNet 競賽中的結果。

首先我們來看一下網絡的深度對 SE 的影響。上表分別展示了 ResNet-50、ResNet-101、ResNet-152 和嵌入 SE 模型的結果。第一欄 Original 是原作者實現的結果,為了進行公平的比較,我們在 ROCS 上重新進行了實驗得到 Our re-implementation 的結果(ps. 我們重實現的精度往往比原 paper 中要高一些)。最后一欄 SE-module 是指嵌入了 SE 模塊的結果,它的訓練參數和第二欄 Our re-implementation 一致。括號中的紅色數值是指相對於 Our re-implementation 的精度提升的幅值。

從上表可以看出,SE-ResNets 在各種深度上都遠遠超過了其對應的沒有 SE 的結構版本的精度,這說明無論網絡的深度如何,SE 模塊都能夠給網絡帶來性能上的增益。值得一提的是,SE-ResNet-50 可以達到和 ResNet-101 一樣的精度;更甚,SE-ResNet-101 遠遠地超過了更深的 ResNet-152。

上圖展示了 ResNet-50 和 ResNet-152 以及它們對應的嵌入 SE 模塊的網絡在 ImageNet 上的訓練過程,可以明顯地看出加入了 SE 模塊的網絡收斂到更低的錯誤率上。

另外,為了驗證 SE 模塊的泛化能力,我們也在除 ResNet 以外的結構上進行了實驗。從上表可以看出,將 SE 模塊嵌入到 ResNeXt、BN-Inception、Inception-ResNet-v2 上均獲得了不菲的增益效果。由此看出,SE 的增益效果不僅僅局限於某些特殊的網絡結構,它具有很強的泛化性。

上圖展示的是 SE 嵌入在 ResNeXt-50 和 Inception-ResNet-v2 的訓練過程對比。

在上表中我們列出了一些最新的在 ImageNet 分類上的網絡的結果。其中我們的 SENet 實質上是一個 SE-ResNeXt-152(64x4d),在 ResNeXt-152 上嵌入 SE 模塊,並做了一些其他修改和訓練優化上的小技巧,這些我們會在后續公開的論文中進行詳細介紹。可以看出 SENet 獲得了迄今為止在 single-crop 上最好的性能。

最后,在 ILSVRC 2017 競賽中,我們的融合模型在測試集上獲得了 2.251% Top-5 錯誤率。對比於去年第一名的結果 2.991%, 我們獲得了將近 25% 的精度提升。

更多技術上和實驗上的細節將會展示在即將公開的論文中。

 

from:https://blog.csdn.net/u014380165/article/details/78006626

論文:Squeeze-and-Excitation Networks
論文鏈接:https://arxiv.org/abs/1709.01507
代碼地址:https://github.com/hujie-frank/SENet
PyTorch代碼地址:https://github.com/miraclewkf/SENet-PyTorch

Sequeeze-and-Excitation(SE) block並不是一個完整的網絡結構,而是一個子結構,可以嵌到其他分類或檢測模型中,作者采用SENet block和ResNeXt結合在ILSVRC 2017的分類項目中拿到第一,在ImageNet數據集上將top-5 error降低到2.251%,原先的最好成績是2.991%。
作者在文中將SENet block插入到現有的多種分類網絡中,都取得了不錯的效果。SENet的核心思想在於通過網絡根據loss去學習特征權重,使得有效的feature map權重大,無效或效果小的feature map權重小的方式訓練模型達到更好的結果。當然,SE block嵌在原有的一些分類網絡中不可避免地增加了一些參數和計算量,但是在效果面前還是可以接受的。

也許通過給某一層特征配備權重的想法很多人都有,那為什么只有SENet成功了?個人認為主要原因在於權重具體怎么訓練得到。就像有些是直接根據feature map的數值分布來判斷;有些可能也利用了loss來指導權重的訓練,不過全局信息該怎么獲取和利用也是因人而異。

Figure1表示一個SE block。主要包含Squeeze和Excitation兩部分,接下來結合公式來講解Figure1。

這里寫圖片描述

首先Ftr這一步是轉換操作(嚴格講並不屬於SENet,而是屬於原網絡,可以看后面SENet和Inception及ResNet網絡的結合),在文中就是一個標准的卷積操作而已,輸入輸出的定義如下表示。

這里寫圖片描述

那么這個Ftr的公式就是下面的公式1(卷積操作,vc表示第c個卷積核,xs表示第s個輸入)。

這里寫圖片描述

Ftr得到的U就是Figure1中的左邊第二個三維矩陣,也叫tensor,或者叫C個大小為H*W的feature map。而uc表示U中第c個二維矩陣,下標c表示channel。

接下來就是Squeeze操作,公式非常簡單,就是一個global average pooling:

這里寫圖片描述

因此公式2就將H*W*C的輸入轉換成1*1*C的輸出,對應Figure1中的Fsq操作。為什么會有這一步呢?這一步的結果相當於表明該層C個feature map的數值分布情況,或者叫全局信息。

再接下來就是Excitation操作,如公式3。直接看最后一個等號,前面squeeze得到的結果是z,這里先用W1乘以z,就是一個全連接層操作,W1的維度是C/r * C,這個r是一個縮放參數,在文中取的是16,這個參數的目的是為了減少channel個數從而降低計算量。又因為z的維度是1*1*C,所以W1z的結果就是1*1*C/r;然后再經過一個ReLU層,輸出的維度不變;然后再和W2相乘,和W2相乘也是一個全連接層的過程,W2的維度是C*C/r,因此輸出的維度就是1*1*C;最后再經過sigmoid函數,得到s。

這里寫圖片描述

也就是說最后得到的這個s的維度是1*1*C,C表示channel數目。這個s其實是本文的核心,它是用來刻畫tensor U中C個feature map的權重。而且這個權重是通過前面這些全連接層和非線性層學習得到的,因此可以end-to-end訓練。這兩個全連接層的作用就是融合各通道的feature map信息,因為前面的squeeze都是在某個channel的feature map里面操作。

在得到s之后,就可以對原來的tensor U操作了,就是下面的公式4。也很簡單,就是channel-wise multiplication,什么意思呢?uc是一個二維矩陣,sc是一個數,也就是權重,因此相當於把uc矩陣中的每個值都乘以sc。對應Figure1中的Fscale。

這里寫圖片描述

了解完上面的公式,就可以看看在實際網絡中怎么添加SE block。Figure2是在Inception中加入SE block的情況,這里的Inception部分就對應Figure1中的Ftr操作。

這里寫圖片描述

Figure3是在ResNet中添加SE block的情況。

這里寫圖片描述

看完結構,再來看添加了SE block后,模型的參數到底增加了多少。其實從前面的介紹可以看出增加的參數主要來自兩個全連接層,兩個全連接層的維度都是C/r * C,那么這兩個全連接層的參數量就是2*C^2/r。以ResNet為例,假設ResNet一共包含S個stage,每個Stage包含N個重復的residual block,那么整個添加了SE block的ResNet增加的參數量就是下面的公式:

這里寫圖片描述

除了公式介紹,文中還舉了更詳細的例子來說明參數增加大概是多少百分比:In total, SE-ResNet-50 introduces 2.5 million additional parameters beyond the 25 million parameters required by ResNet-50, corresponding to a 10% increase in the total number of parameters。而且從公式5可以看出,增加的參數和C關系很大,而網絡越到高層,其feature map的channel個數越多,也就是C越大,因此大部分增加的參數都是在高層。同時作者通過實驗發現即便去掉最后一個stage的SE block,對模型的影響也非常小(<0.1% top-1 error),因此如果你對參數量的限制要求很高,倒是可以這么做,畢竟具體在哪些stage,哪些block中添加SE block都是自由定義的。

Table2是將SE block添加到ResNet,ResNeXt和Inception三個模型中的效果對比,數據集都是ImageNet,可以看出計算復雜度的增加並不明顯(增加的主要是全連接層,全連接層其實主要還是增加參數量,對速度影響不會太大)。

這里寫圖片描述

既然是冠軍算法,文中也介紹了當時取得冠軍時的算法大致組成:Our winning entry comprised a small ensemble of SENets that employed a standard multi-scale and multi-crop fusion strategy to obtain a 2.251% top-5 error on the test set.This result represents a 25% relative improvement on the winning entry of 2016 (2.99% top-5 error). 也就是說其實是多模型做了融合。

而在融合的多個模型之中:One of our high-performing networks is constructed by integrating SE blocks with a modified ResNeXt,也就是Table3中最后一行的SENet!具體而言是在64*4d 的ResNeXt-152網絡中引入了SE block。而這個ResNeXt-152是在ResNeXt-101的基礎上根據ResNet-152的疊加方式改造出來的,因為原來的ResNeXt文章中並沒有提到152層的ResNeXt,具體改造可以看文章的附錄,附錄的一些細節可以在以后應用中參考。從Table3可以看出即便是單模型,SENet的效果也比其他算法要好。

這里寫圖片描述

另外前面提到過在SE block中第一個全連接層的維度是C/r * C,這個r在文中取的是16,作用在於將原來輸入是1*1*C的feature map縮減為1*1*C/r的feature map,這一就降低了后面的計算量。而下面的Table5則是關於這個參數r取不同值時對結果和模型大小的影響。

這里寫圖片描述

最后,除了在ImageNet數據集上做實驗,作者還在Places365-Challenge數據集上做了對比,更多實驗結果可以參看論文。

附:看了下caffe代碼(.prototxt文件),和文章的實現還有些不一樣。下圖是在Inception中添加SENet的可視化結果:SE-BN-Inception,在Inception中是在每個Inception的后面連上一個SENet,下圖的上面一半就是一個Inception,下面一半就是一個SENet,然后這個SENet下面又連着一個新的Inception。

這里寫圖片描述

注意看這個SENet的紅色部分都是用卷機操作代替文中的全連接層操作實現的,個人理解是為了減少參數(原來一個全連接層是C*C/r個參數,現在變成了C/r個參數了),計算量應該是不影響的,都是C*C/r。具體來說,inception_3a_1*1_down是輸出channel為16的1*1卷積,其輸入channel是256,這也符合文中說的縮減因子為16(256/16=16);而inception_3a_1*1_up是輸出channel為256的1*1卷積。其它層都和文中描述一致,比如inception_3a_global_pool是average pooling,inception_3a_prob是sigmoid函數。

SE-ResNet-50的情況也類似,如下圖。在ResNet中都是在Residual block中嵌入SENet。下圖最左邊的長條連線是原來Residual block的skip connection,右下角的conv2_2_global_pool到conv2_2_prob以及左邊那條連線都是SENet。不過也是用兩個1*1卷積代替文中的兩個全連接層。

這里寫圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM