『高性能模型』輕量級網絡ShuffleNet_v1及v2


項目實現:GitHub

參考博客:CNN模型之ShuffleNet

v1論文:ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices

v2論文:ShuffleNet V2: Practical Guidelines for Ecient CNN Architecture Design

一、分組卷積

Group convolution是將輸入層的不同特征圖進行分組,然后采用不同的卷積核再對各個組進行卷積,這樣會降低卷積的計算量。因為一般的卷積都是在所有的輸入特征圖上做卷積,可以說是全通道卷積,這是一種通道密集連接方式(channel dense connection),而group convolution相比則是一種通道稀疏連接方式(channel sparse connection)。

『高性能模型』深度可分離卷積和MobileNet_v1

tensorflow和分組卷積的討論:Feature Request: Support for depthwise convolution by groups

1、分組卷積的矛盾——計算量

使用group convolution的網絡有很多,如Xception,MobileNet,ResNeXt等。其中Xception和MobileNet采用了depthwise convolution,這是一種比較特殊的group convolution,此時分組數恰好等於通道數,意味着每個組只有一個特征圖。是這些網絡存在一個很大的弊端是采用了密集的1x1 pointwise convolution(如下圖)。

這個問題可以解決:對1x1卷積采用channel sparse connection 即分組操作,那樣計算量就可以降下來了,但這就涉及到另外一個問題。

2、分組卷積的矛盾——特征通信

group convolution層另一個問題是不同組之間的特征圖需要通信,否則就好像分了幾個互不相干的路,大家各走各的,會降低網絡的特征提取能力,這也可以解釋為什么Xception,MobileNet等網絡采用密集的1x1 pointwise convolution,因為要保證group convolution之后不同組的特征圖之間的信息交流。

3、channel shuffle

為達到特征通信目的,我們不采用dense pointwise convolution,考慮其他的思路:channel shuffle。如圖b,其含義就是對group convolution之后的特征圖進行“重組”,這樣可以保證接下了采用的group convolution其輸入來自不同的組,因此信息可以在不同組之間流轉。圖c進一步的展示了這一過程並隨機,其實是“均勻地打亂”。

在程序上實現channel shuffle是非常容易的:假定將輸入層分為 g 組,總通道數為 g\times n ,首先你將通道那個維度拆分為 (g,n) 兩個維度,然后將這兩個維度轉置變成 (n,g) ,最后重新reshape成一個維度g\times n


二、ShuffleNet

ShuffleNet的核心是采用了兩種操作:pointwise group convolution和channel shuffle,這在保持精度的同時大大降低了模型的計算量。其基本單元則是在一個殘差單元的基礎上改進而成。

1、ShuffleNet基本單元

下圖a展示了基本ResNet輕量級結構,這是一個包含3層的殘差單元:首先是1x1卷積,然后是3x3的depthwise convolution(DWConv,主要是為了降低計算量),這里的3x3卷積是瓶頸層(bottleneck),緊接着是1x1卷積,最后是一個短路連接,將輸入直接加到輸出上。

下圖b展示了改進思路:將密集的1x1卷積替換成1x1的group convolution,不過在第一個1x1卷積之后增加了一個channel shuffle操作。值得注意的是3x3卷積后面沒有增加channel shuffle,按paper的意思,對於這樣一個殘差單元,一個channel shuffle操作是足夠了。還有就是3x3的depthwise convolution之后沒有使用ReLU激活函數。

下圖c展示了其他改進,對原輸入采用stride=2的3x3 avg pool,在depthwise convolution卷積處取stride=2保證兩個通路shape相同,然后將得到特征圖與輸出進行連接(concat,借鑒了DenseNet?),而不是相加。極致的降低計算量與參數大小。

2、ShuffleNet網絡結構

可以看到開始使用的普通的3x3的卷積和max pool層。然后是三個階段,每個階段都是重復堆積了幾個ShuffleNet的基本單元。對於每個階段,第一個基本單元采用的是stride=2,這樣特征圖width和height各降低一半,而通道數增加一倍。后面的基本單元都是stride=1,特征圖和通道數都保持不變。對於基本單元來說,其中瓶頸層,就是3x3卷積層的通道數為輸出通道數的1/4,這和殘差單元的設計理念是一樣的。

3、對比實驗

下表給出了不同g值(分組數)的ShuffleNet在ImageNet上的實驗結果。可以看到基本上當g越大時,效果越好,這是因為采用更多的分組后,在相同的計算約束下可以使用更多的通道數,或者說特征圖數量增加,網絡的特征提取能力增強,網絡性能得到提升。注意Shuffle 1x是基准模型,而0.5x和0.25x表示的是在基准模型上將通道數縮小為原來的0.5和0.25。

除此之外,作者還對比了不采用channle shuffle和采用之后的網絡性能對比,如下表的看到,采用channle shuffle之后,網絡性能更好,從而證明channle shuffle的有效性。

然后是ShuffleNet與MobileNet的對比,如下表ShuffleNet不僅計算復雜度更低,而且精度更好。

三、ShuffleNet_v2

我們首先來看v1版本和v2版本的基礎單元,(a)和(b)是ShuffleNet v1的兩種不同block結構,兩者的差別在於后者對特征圖尺寸做了縮小,這和ResNet中某個stage的兩種block功能類似,同理(c)和(d)是ShuffleNet v2的兩種不同block結構:

 

看點如下:

  從(a)和(c)的對比可以看出首先(c)在開始處增加了一個channel split操作,這個操作將輸入特征的通道分成c-c’和c’,c’在文章中采用c/2,這主要是和第1點發現對應

  然后(c)中取消了1*1卷積層中的group操作,這和第2點發現對應,同時前面的channel split其實已經算是變相的group操作了

  channel shuffle的操作移到了concat后面,和第3點發現對應,同時也是因為第一個1*1卷積層沒有group操作,所以在其后面跟channel shuffle也沒有太大必要

  最后是將element-wise add操作替換成concat,這個和第4點發現對應。

多個(c)結構連接在一起的話,channel split、concat和channel shuffle是可以合並在一起的。(b)和(d)的對比也是同理,只不過因為(d)的開始處沒有channel split操作,所以最后concat后特征圖通道數翻倍,可以結合后面具體網絡結構來看:


現在我們查看一個新的概念:內存訪問消耗時間(memory access cost),它正比於模型對內存的消耗(特征大小+卷積核大小),在這篇文章中作者使用該指標來衡量模型的速度而非傳統的FLOPs(float-point operations),它更多的側重卷積層的乘法操作,作者認為FLOPs並不能實質的反應模型速度。

現在我們來看一下這四點發現,分別對應了結構中的四點創新:

卷積層的輸入和輸出特征通道數相等時MAC最小,此時模型速度最快

過多的group操作會增大MAC,從而使模型速度變慢

模型中的分支數量越少,模型速度越快

element-wise操作所帶來的時間消耗遠比在FLOPs上的體現的數值要多,因此要盡可能減少element-wise操作

至於模型的具體提升,建議之間看原文的圖表。


免責聲明!

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



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