輕量化網絡:ShuffleNet V2

ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design

由Face++及清華的研究者共同發表,已被ECCV-2018收錄

論文下載地址:https://pan.baidu.com/s/1so7aD3hLKO-0PB8h4HWliw
prototxt 可從此處獲得: https://github.com/farmingyard/ShuffleNet

該論文雖然以ShuffleNet V2打頭,但ShuffleNet V2 只是該論文的副產品,最亮眼的還是該論文提出的兩個原則,四個指導方針,這爲輕量級模型的設計者提供了巨大的幫助。

創新點

兩個原則和四個指導方針

兩個原則:
1. 衡量模型運行速度,應採用如運行時間(speed\runtime)這樣的指標;
2. 應在具體的運行平臺上進行評估、衡量。
四個指導方針:
1. 卷積核數量儘量與輸入通道數相同(即輸入通道數等於輸出通道數);
2. 謹慎使用group convolutions,注意group convolutions的效率;
3. 降低網絡碎片化程度;
4. 減少元素級運算。

至於ShuffleNet V2的結構,就不提了,都在後面呢

前言:

近幾年輕量化卷積神經網絡設計都以浮點運算數flops爲指導,網絡設計時在保證精度的同時儘可能的獲得更小的flops。然而,在實際應用過程中,網絡的耗時不僅看“軟件”上的設計,還要考慮到硬件實現的效率。軟硬兼併,雙管齊下,才能獲得更好的移動端網絡模型。“軟件”上主要考慮權值參數數量(佔內存小)以及具體的運算方式(更小的flops),硬件上要考慮MAC(memory access cost ),並行度(degree of parallelis),數據的讀取方式等等,更多硬件上的討論可參考論文(SqueezeNext: Hardware-Aware Neural Network Design)第三小節。

本文作者就是在“軟件”和硬件上綜合考慮之後,得出四點指導方針,再基於shufflenet-v1進行改動,就得到了shufflenet-v2 。

正文:

近幾年,輕量級模型的設計都是朝着 light-weight 結構進行設計,在 light-weight結構中,主要得益於 Group convolution 和 depth-wise convolution。爲了衡量模型的是否是輕量級,通常都採用flops這一單一指標。但我們知道,flpos並不能等價於一個網絡的速度,flops相同的網絡模型,其運算速度也會存在差異,這種差異大多是由硬件的特性引起的。如圖1中的c,d所示,採用四種不同的網絡設計思想,在具有相同的flops時,它們的運算速度卻不同。

這就值得思考了,之前僅通過指標flops“指導”設計輕量級卷積神經網絡,是否完美?是否還需要考慮其他指標? 答案不言而喻。請接着往下看,到底還需要用什麼指標來衡量網絡的輕呢?
這裏寫圖片描述

經本文分析,模型的flops不能直接代表其速度的原因有二:

  1. 影響模型運行速度還有別的指標,例如,MAC(memory access ),並行度(degree of parallelism)

  2. 不同平臺有不同的加速算法,這導致flops相同的運算可能需要不同的運算時間。

基於上述發現,該文提出設計輕量級網絡時需要考慮的兩個原則(指導方針):

1. 衡量模型運行速度,應採用如運行時間(speed\runtime)這樣的指標;
2. 應在具體的運行平臺上進行評估、衡量

Guideline 1-4:

先看看兩種輕量化模型的runtime分析
這裏寫圖片描述

可以發現,模型的runtime主要由卷積主導,但不是絕對主導,模型的runtime還受到 data I/O , data shuffle, element-wise operations(AddTensor, ReLU,etc)的影響,因此可知道要設計一個輕量模型,應該綜合考慮那些會影響runtime的因素。基於上述發現,該文從不同角度進行分析模型runtime,並提出四個設計輕量模型的guidelines

G1. Equal channel width minimizes memory access cost(MAC)

先理論分析,再試驗驗證:
基本假設與條件,假設內存足夠大一次性可存儲所有feature maps and parameters;卷積核大小爲1*1 ;輸入通道有c1個;輸出通道有c2個;feture map的分辨率爲 h*w;
則 the flops of the 1*1 convolutions is
B=hwc1c2 ;
MAC=hw(c1+c2)+c1c2

從MAC公式,以及B的公式,以及均值不等式(c1c2)20 ,

可以推出: MAC2hwB+Bhw
推到過程如下
(c1c2)20(c1+c2)24c1c2

(c1+c2)2c1c2

hw(c1+c2)2hwhwc1c2

hw(c1+c2)+c1c22hwB+c1c2

MAC2hwB+Bhw

從公式中我們可以得出MAC的一個下界,即當c1==c2 時,MAC取得最小值。
試驗驗證,這僅是理論分析,實際情況中,內存是沒辦法達到要求的,因此需要用試驗來驗證是否當c1==c2時,MAC達到下限,從而較少runtime。
該文在flops相同,並採取4種不同的c1:c2比值分別在gpu 和 arm上進行試驗,試驗結果如下表:
這裏寫圖片描述

可以發現,當c1==c2時,無論在GPU平臺還是ARM平臺,均獲得了最快的runtime
(Ps: 拋出一個疑問:從表中發現,隨着c1:c2值的增加,速度變快,那麼當c1 大於c2的情況下,是否會更快呢?
不過在實際應用中,我們輸出的feature maps數量還是會小於輸入的)
通過理論及試驗結果的分析,得出G1

G2 Excessive group convolution increases MAC
先理論分析,再試驗驗證:
同G1中一樣,假設 卷積核大小爲1*1 ;輸入通道有c1個;輸出通道有c2個;feture map的分辨率爲 h*w;group 爲g

MAC=hw(c1+c2)+c1c2g=hwc1+Bgc1+Bhw;
B=hwc1c2g

文中是這樣分析的,當fixed input shape c1*h*w and the computational cost B, MAC increases with the growth of g.

但是g的變動,B也變動了呀!如何做到固定 c1*h*w 和B ,去分析MAC 隨g的變化呢?

實在想不明白,暫且跳過~

理論分析得出,g的增加,會導致MAC的增加,那麼實際情況是不是這樣? 請看試驗結果
這裏寫圖片描述

可以發現,當g=1時,速度達到最快,隨着g的增加,速度逐漸變慢

G3 Network fragmentation reduces degree of parallelis

理論上,網絡的碎片化雖然能給網絡的accuracy帶來幫助,但是在平行計算平臺(如GPU)中,網絡的碎片化會引起並行度的降低,最終增加runtime,同樣的該文用實驗驗證,詳細可看論文中的表3

G4 Element-wise operations are non-negligible

從圖2中可以看到, element-wise operations也佔了不少runtime,尤其是GPU平臺下,高達15%。什麼是element-wise operations? 如ReLU、AddTensor及AddBias等這一類的操作就屬於element-wise operations. 這一類操作,雖然flops很低,但是MAC很大,因而也佔據相當時間。同樣地,通過實驗分析element-wise operations 越少的網絡,其速度是否越快? 答案是肯定的,詳情可查看原文表4.

綜上(G1-4),可以得出設計輕量級網絡的四個指導方針:

  1. 卷積核數量儘量與輸入通道數相同(即輸入通道數等於輸出通道數);
  2. 謹慎使用group convolutions,注意group convolutions的效率;
  3. 降低網絡碎片化程度;
  4. 減少元素級運算

簡單回顧一下,早一批的輕量級網絡都違背了哪些guideline。
ShuffleNet V1 嚴重依賴組卷積(違反 G2)和瓶頸形態的構造塊(違反 G1)。MobileNet V2 使用倒置的瓶頸結構(違反G1),並且在“厚”特徵圖上使用了深度卷積和 ReLU 激活函數(違反了 G4)。

有了以上四個指導方針,就可以開始設計新的網絡(ShuffleNet V2)啦

ShuffleNet V2

ShuffleNet V2 的結構是在ShuffleNet V1基礎上進行改進,先簡單回顧ShuffleNet V1,詳細可參見博客輕量化網絡:ShuffleNet

在ShuffleNet V1中,特色在於:
1. pointwise group convolution , 這違反了本文提出的G2; 2. channel shuffle
ShuffleNet V1還採用了 bottleneck-like 結構,在bottleneck unit中,shortcut connection中的element-wise operations——add tensor,又違反了G4;

接下來,主角登場,看看ShuffleNet V2
ShuffleNet V2主要結構是多個blocks堆疊構成,block又分爲兩種,一種是帶Channel Spilit的,一種是帶Stride=2的(爲了降分辨率)
我將分三個部分剖析 ShuffleNet V2:分別是

1. 帶Channel Spilit的block;
2. 帶Stride=2的block;
3. ShuffleNet V2 的整體結構

第一:帶Channel Spilit的block

先看看Channel Split的是長什麼樣,它又是如何從ShuffleNet V1中 ,並參照G1-4之後演變而來的呢?
圖(a)爲ShuffleNet V1中的block,(c)爲ShuffleNet V2 中帶Channel Split的block
這裏寫圖片描述

我們發現,不同之處有四處,這就一一道來:
1. 增加了Channel Split ,這這這,這是爲什麼,看沒明白
2. 兩處1*1的Group Conv變成了 1*1 Conv, 這遵循了G2
3. Add 操作變成了 Concat,這遵循了G4
4. Channel Shuffle 移到了最後面,這個東西就想多說兩句了,在ShuffleNet V1當中,Channel Shuffle 是因Group Convolution 帶來的信息流通不暢而設計的,這裏取消掉了Group Conv,自然沒必要放在裏面了,這個可以參看原文,或者我之前的博客有分析到;

然後爲什麼放在這裏了呢? 我們看到,一開始Channel Split,會有一部分的Channel沒有被“動”過(即,沒有被卷積),如果在送入下一個block時,不“搞一搞”,直接送下去的話, 還是會造成信息流通不暢的問題,因此在這裏加一個 Channel Shuffle 。

正如ShuffleNet V1中 3.1標題:Channel Shuffle for Group Convolutions,那麼在ShuffleNet V2 中的這個block,是否可以理解爲:Channel Shuffle for Channel Split 呢??

第二,帶Stride=2的block;
爲什麼要帶Stride=2的block? 因爲之前都沒有降分辨率啊!
圖(b)爲ShuffleNet V1中的block,(d)爲ShuffleNet V2 中帶Channel Split的block

這裏寫圖片描述

可以看出,不同之處有:

  1. 左路3*3 AVG Pool 換成了 3*3的DWConv + 1*1 Conv 用來降低分辨率;
  2. 右路的兩個1*1 Goup Conv 變成了1*1 Conv, 遵循了G2,看來ShuffleNet V2 是徹底地摒棄了 Group Convolution啊!
  3. Concat 之後增加了一個 Channel Shuffle; 咦,爲什麼有Channel Shuffle? 哪裏引起了信息流通不暢嘛? 如果沒有,那麼Channel Shuffle的意義又是什麼呢?

第三部分:ShuffleNet V2 的整體結構
如下表:
這裏寫圖片描述

第一列,Layer中,大部分都能看得明白,這裏主要將 Stage裏邊,可以發現,每個Stage首先由一個帶Stride=2的block將feature maps 降分辨率,然後重複的使用數個帶Channel Split的block進行“搞特徵”

至此,ShuffleNet V2的結構扒拉差不多了。

以上講的都是優化速度,那麼精度如何? 不用說,肯定不賴,那麼,爲什麼還能保持高精度?原因有兩個:

  1. the high efficiency in each building block enables using more feature channels and larger network capacity. (自己感受一下吧)

  2. feature reuse !! 又看到它了,DenseNet (CVPR-2017 Best Paper)將 feature reuse用到了極致,詳情可參見博客:https://blog.csdn.net/u011995719/article/details/76687476
    ShuffleNet V2是如何有特徵重用這一特點的呢? 我們可以faxing,在帶Channel Split的block中,最後會有一部分(這裏是去二分之一,即一半)的Channel 是沒有動過的,這些Channel會流到下一個Block中,被再次利用
    原文中的圖4,沒看明白,就不瞎扯了。

由於前面講太多了,實驗部分就不講了,一句話,ShuffleNet V2 分別在ImageNet2012和COCO任務上,以及不同的平臺——GPU and ARM上,精度速度都很OK啊,都很good

疑問:

最後還是有一些疑問,總結如下:

1.G2分析中,B會受到g的影響而變化,那麼文中提到,在讓B不變的情況下,g的增加會導致MAC的增加,這應該怎麼理解呢?

2.Channel Split 具體的意義是什麼?

3.在帶Channel Split的block中,是否可以理解爲:Channel Shuffle for Channel Split ?

4.帶Stride = 2 的block中採用了Channel Shuffle,這裏採用Channel Shuffle的意義是什麼? 爲什麼要去Shuffle?

如果有朋友理解以上4個問題,麻煩在評論區留言唄~~謝謝!

PS:以上所有均是個人觀點,不代表原文作者觀點,若有不正確的地方,請大家指正,謝謝!

轉載請註明出自:https://blog.csdn.net/u011995719/article/details/81409245,謝謝!

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