【小白學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的結構,原理和調用方式。


免責聲明!

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



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