【小白學PyTorch】13 EfficientNet詳解及PyTorch實現

參考目錄:

文章來自微信公衆號【機器學習煉丹術】。我是煉丹兄,如果有疑問或者想要和煉丹兄交流的可以加微信:cyx645016617.

efficientNet的論文原文鏈接: https://arxiv.org/pdf/1905.11946.pdf

模型擴展Model scaling一直以來都是提高卷積神經網絡效果的重要方法。
比如說,ResNet可以增加層數從ResNet18擴展到ResNet200。這次,我們要介紹的是最新的網絡結構——EfficientNet,就是一種標準化的模型擴展結果,通過下面的圖,我們可以i只管的體會到EfficientNet b0-b7在ImageNet上的效果:對於ImageNet歷史上的各種網絡而言,可以說EfficientNet在效果上實現了碾壓
在這裏插入圖片描述

1 EfficientNet

1.1 概述

一般我們在擴展網絡的時候,一般通過調成輸入圖像的大小、網絡的深度和寬度(卷積通道數,也就是channel數)。在EfficientNet之前,沒有研究工作只是針對這三個維度中的某一個維度進行調整,因爲沒錢啊!!有限的計算能力,很少有研究對這三個維度進行綜合調整的。

EfficientNet的設想就是能否設計一個標準化的卷積網絡擴展方法,既可以實現較高的準確率,又可以充分的節省算力資源。因而問題可以描述成,如何平衡分辨率、深度和寬度這三個維度,來實現拘拿及網絡在效率和準確率上的優化

EfficientNet給出的解決方案是提出了這個模型複合縮放方法 (compound scaling methed)
在這裏插入圖片描述圖a是一個基線網絡,也就是我們所說的baseline,圖b,c,d三個網絡分別對該基線網絡的寬度、深度、和輸入分辨率進行了擴展,而最右邊的e圖,就是EfficientNet的主要思想,綜合寬度、深度和分辨率對網絡進行符合擴展。

1.2 把擴展問題用數學來描述

首先,我們把整個卷積網絡稱爲N,他的第i個卷積層可以看作下面的函數映射:
在這裏插入圖片描述
Yi是輸出張量,Xi是輸入張量,假設這個Xi的維度是<Hi,Wi,Ci>(這裏省略了Batch的維度),那麼這個整個卷積網絡N,是由k個卷積層組成的,因此可以表示爲:
在這裏插入圖片描述
通常情況,一個神經網絡會有多個相同的卷積層存在,因此,我們稱多個結構相同的卷積層爲一個stage。舉個例子:ResNet可以分爲5個stage,每一個stage中的卷積層結構相同(除了第一層爲降採樣層),前四個stage都是baseblock,第五個stage是fc層。不太理解的可以看這個:【從零學習PyTorch】 如何殘差網絡resnet作爲pre-model +代碼講解+殘差網絡resnet是個啥

總之,我們以stage爲單位,將上面的卷積網絡N改成爲:
在這裏插入圖片描述
其中,下表1...s表示stage的訊號,Fi表示對第i層的卷積運算,Li的意思是Fi在第i個stage中有Li個一樣結構的卷積層。<Hi, Wi, Ci>表示第i層輸入的shape。
爲了減小搜索空間,作者先固定了網絡的基本結構,而只改變上面公式中的三個縮放維度。還記得之前我們提高的分辨率,寬度,深度嗎?

  • Li就是深度,Li越大重複的卷積層越多,網絡越深;
  • Ci就是channel數目,也就是網絡的寬度
  • Hi和Wi就是圖片的分辨率
    就算如此,這也有三個參數要調整,搜索空間也是非常的大,因此EfficientNet的設想是一個卷積網絡所有的卷積層必須通過相同的比例常數進行統一擴展,這句話的意思是,三個參數乘上常熟倍率。所以個一個模型的擴展問題,就用數學語言描述爲:
    在這裏插入圖片描述
    其中,d、w和r分別表示網絡深度、寬度和分辨率的倍率。這個算式表現爲在給定計算內存和效率的約束下,如何優化參數d、w和r來實現最好的模型準確率。

1.3 實驗內容

上面問題的難點在於,三個倍率之間是由內在聯繫的,比如更高分辨率的圖片就需要更深的網絡來增大感受野的捕捉特徵。因此作者做了兩個實驗(實際應該是做了很多的實驗)來說明:
(1) 第一個實驗,對三個維度固定了兩個,只方法其中一個,得到的結果如下:
在這裏插入圖片描述
從左到右分別是隻放大了網絡寬度(width,w爲放大倍率)、網絡深度(depth,d爲放大倍率)和圖像分辨率(resolution, r爲放大倍率)。我們可以看到,單個維度的放大最高精度只有80左右,本次實驗,作者得出一個管帶你:三個維度中任一維度的放大都可以帶來精度的提升,但是隨着倍率的越來越大,提升越來越小。
(2)於是作者做了第二個實驗,嘗試在不同的d,r組合下變動w,得到下圖:
在這裏插入圖片描述
從實驗結果來看,最高精度相比之前已經有所提升,突破了80大關。而且組合不同,效果不同。作者又得到了一個觀點:得到了更高的精度以及效率的關鍵是平衡網絡的寬度,網絡深度,網絡分辨率三個維度的縮放倍率

1.4 compound scaling method

這時候作者提出了這個方法
EfficientNet的規範化複合調參方法使用了一個複合係數\(\phi\),來對三個參數進行符合調整:
在這裏插入圖片描述
其中的\(\alpha, \beta, \gamma\)都是常數,可以通過網格搜索獲得。複合係數通過人工調節。考慮到如果網絡深度翻番那麼對應的計算量翻番,網絡寬度和圖像分辨率翻番對應的計算量會翻4番,卷積操作的計算量與\(d,w^2 ,r^2\)成正比,。在這個約束下,網絡的計算量大約是之前的\(2^\phi\)


以上就是EfficientNet的複合擴展的方式,但是這僅僅是一種模型擴展方式,我們還沒有講到EfficientNet到底是一個什麼樣的網絡。

1.5 EfficientNet的基線模型

EfficientNet使用了MobileNet V2中的MBCConv作爲模型的主幹網絡,同時也是用了SENet中的squeeze and excitation方法對網絡結構進行了優化。 MBCConv是mobileNet中的基本結構,關於什麼是MBCconv在百度上很少有解釋,通過閱讀論文和Google這裏有一個比較好的解釋:

The MBConv block is nothing fancy but an Inverted Residual Block (used in MobileNetV2) with a Squeeze and Excite block injected sometimes.

MBCconv就是一個MobileNet的倒殘差模塊,但是這個模塊中還封裝了Squeeze and Excite的方法。

總之呢,綜合了MBConv和squeeze and excitation方法的EfficientNet-B0的網絡結構如下表所示:
在這裏插入圖片描述
對於EfficientNet-B0這樣的一個基線網絡,如何使用複合擴展發對該網絡進行擴展呢?這裏主要是分兩步走:還記得這個規劃問題嗎?
在這裏插入圖片描述
(1)第一步,先將複合係數\(\phi\)固定爲1,先假設有兩倍以上的計算資源可以用,然後對\(\alpha, \beta, \gamma\)進行網絡搜索。對於EfficientNet-B0網絡,在約束條件爲

\[\alpha \times \beta^2 \times \gamma^2 \approx 2 \]

時,\(\alpha, \beta, \gamma\)分別取1.2,1.1和1.15時效果最佳。第二步是固定\(\alpha, \beta, \gamma\),通過複合調整公式對基線網絡進行擴展,得到B1到B7網絡。於是就有了開頭的這一張圖片,EfficientNet在ImageNet上的效果碾壓,而且模型規模比此前的GPipe小了8.4倍。
在這裏插入圖片描述

普通人來訓練和擴展EfficientNet實在過於昂貴,所以對於我們來說,最好的方法就是遷移學習,下面我們來看如何用PyTorch來做遷移學習。

2 PyTorch實現

之前也提到了,在torchvision中並沒有加入efficientNet所以這裏我們使用某一位大佬貢獻的API。有一個這樣的文件Efficient_PyTorch,裏面存放了b0到b8的預訓練模型存儲文件,我們將會調用這個API。因爲這裏我們沒有直接使用pip進行安裝,所以需要將這個庫函數設置成系統路徑。Pycharm中很多朋友會踩着個坑,不知道如何設置成系統路徑:


點擊Sources Root之後,就可以直接import了。

整個代碼非常少,因爲都寫成API接口了嘛:

from efficientnet_pytorch import EfficientNet
model = EfficientNet.from_name('efficientnet-b0')
print(model)

打印的模型可以看,我加了詳細的註解(快誇我):

整個b0的結構和論文中的結構相同:
在這裏插入圖片描述
從上圖中可以知道,總共有16個MBConv模塊;在第16個時候的輸出通道爲320個通道;

從運行結果來看,結構相同。總之這就是EfficientNet的結構,原理和調用方式。

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