寫在前面
ShuffleNet是曠視提出的兩個輕量級網絡,是目前最快的幾個輕量級網絡之一。這裏主要對兩個版本的論文進行閱讀整理。不足之處還請路過的大神指點。
ShuffleNet V1
Group Convolution
這算是整個ShuffleNet的優化核心,Group Convolution操作早在AlexNet的時候就被拿來進行速度的優化了,其運算的過程可以參考這裏,簡單的說就是對一個輸入通道爲N的特徵圖進行的卷積操作拆分爲對g個通道爲N/g的特徵圖進行卷積,這樣的方法在速度和參數上都會有大幅的提升。下表以卷積核爲,特徵圖大小爲,輸入通道數爲N,輸出通道數爲M簡單的說明一下速度和參數的提升:
No Group | With Group | |
---|---|---|
Parameter | ||
Computation |
可以看到兩個參數均縮小的g倍,也就是說當group number越大,優化的越好(但是在ShuffleNetV2中作者論證出group number對於網絡的速度來講並不是越大越好,g=1是對速度最友好的)。
Channel Shuffle
對於上述的Group Convolution,很容易想到一個問題就是在卷積的時候,僅僅是將這一個Group的特徵圖進行了融合,但是不同的組別之間缺沒有充分的連接,長此以往,不同的特徵圖對於對方的瞭解就越來越少,雖然網絡的全連接層會幫助不同特徵圖相互連接,但是可以預想的是這樣的連接融合的次數較少,不如不分組的情況。
基於上述的情況,作者提出把每個組的特徵圖分爲一定組在每一層都進行一定程度的亂序結合,以這樣的方式增加特徵圖的連接融合次數,過程如下圖所示:
ShuffleNet unit
整個單元其實比較好理解,直接上圖如下:
圖(a)是使用DWconv的bottleneck操作;圖(b)是使用添加了Channel Shuffle之後的單元模型(該單元模型並不進行圖像大小的調整),Channel Shuffle操作在1×1的卷積操作之後,也就是先對通道進行了收縮,隨後進行通道調整,最後卷積在調整回原來的通道數;圖(c)是使用該單元進行池化的操作,值得注意的是經過該單元之後,通道數爲原先的2倍。
作者也說道,對於ResNet的bottleneck操作,一共需要的操作爲,其中hw爲圖像的寬度和高度,cm爲輸入通道數和收縮到的通道數,卷積核默認爲3×3,而本文的shuffleNet單元的整體操作花費爲,其中得益於採用了DWConv,而GConv的貢獻主要在於兩端的1×1卷積操作。
ShuffleNet Architecture
ShuffleNet的網絡結構如下圖所示:
可以看到,隨着分組的增加,最終的複雜度(論文中以FLOPS作爲衡量標準)相應的減少,這和我們對於Group Convolution操作的期望相同;隨之而來的一個問題是,採用了這樣的方式會對準確率有影響嗎?出人意料的,該改進也比傳統的網絡優秀一些。
除了標準網絡,作者也按照MobileNetV1的思路,對於網絡設置了一些超參數s,表示通道數的多少,例如s=1,即標準的網絡結構,通道數如上圖所示;s=0.5表明每個stage的輸出和輸入通道數都爲上圖中通道數的一半,其他的類似。通過通道縮放s倍,整個計算複雜度和參數均下降倍。下表是作者的一些實驗數據。
上表中有一個很有意思的現象,就是在s=0.5的時候,較大的group參數居然導致準確率的下降,而s=0.25的時候,較大的group參數使得準確率提高;這裏作者也僅僅是一筆帶過,只是說當每一組的特徵圖數變少,可能影響網絡的表徵能力。
Shuffle操作有無的對比
作者也對比了網絡添加shuffle和不添加shuffle的區別,如下圖
可以看到,網絡添加了shuffle操作之後準確率確實有了一部分的提升。
與MobileNet的對比
下圖是ShuffleNet與MobileNet的對比,可以看到精確度上提高不少。
ShuffleNet V2
如MobileNetV2一樣,ShuffleNetV2也是對深度神經網絡的深層探討,但是不一樣的地方在於,ShuffleNetV2的優化點更精細一些,完全瞄準輕量化這個目標而設計。
對於網絡複雜度的考慮
作者上來就提出了一個被大家廣泛忽略的一個問題:我們廣泛使用的FLOPs真的可以很好的反應我們網絡的複雜度嗎?顯然答案是否定的,作者舉出的例子是MobileNetV2的FLOPs和NASNET-A是相當的,但是速度卻快出了後者很多。下圖是更多的作證。
所以作者這裏提出,僅僅使用FLOPs作爲衡量標準是不全面的,其中一個忽略的因素就是MAC(memory access cost),實際上,很多網絡的操作都跟該因素息息相關,而另一個被忽略的因素就是網絡設計的平行度(parallelism),作者研究說在相同的FLOPs下,平行度高的模型比平行度低的模型速度要快很多。
同時,除了上面的因素,速度還和運行的硬件平臺息息相關,比如使用了加速庫cudnn的話,3×3的卷積操作會被加快,而在ARM平臺上,這樣的好處顯然是沒有的。
所以針對以上的發現,作者提出直接的對網絡速度測量應該代替FLOPs,並針對網絡的速度提出了四點指導建議。
4個guide lines
由於這幾個建議描述也比較多,但是原理都不難,這裏就用結論一筆帶過。
1. 相同維度的通道數將最小化MAC
作者爲了驗證卷積層兩端的通道數對於速度的影響,自己搭建了一個驗證網絡,參數如上表所示,可以看到當兩端的通道數之比爲1:1的時候,模型的速度是最快的(不同比例的通道數不一致主要是爲了保證FLOPs是相同的)。
2. 過多的分組卷積會加大MAC
從上表可以看到,越多的分組會導致速度急速下降,特別是在GPU上,下降的十分嚴重,一個顯卡跑的話,8個Group Convolution會使得速度下降4倍!(這一這裏作者依舊是在不同的條件下使用不同的通道數保證FLOPs是一樣的)
3. 碎片操作將減小網絡的平行度
這裏的碎片操作指的是將一個大的卷積操作分爲多個小的卷積操作進行。
作者這裏使用自己搭建了一些網絡進行驗證,網絡的結構如下(這裏作者似乎並沒有保證FLOPs是一樣的):
最終的結果如下所示:
這裏有一個比較有趣的結果,就是我們認爲可能增加平行度的平行結構,最後居然減低了速度,不過這裏由於還有下一個guide line的實驗說到了元素級的操作也會對速度有一定的影響,因此這裏還不能下定論到底是因爲平行還是因爲最後的相加拉低了時間。
4. 不要忽略元素級操作
這裏元素級操作指的就是Relu,TensorAdd,BiasAdd等等的矩陣元素級操作,可以推測到這些操作其實基本沒有被算到FLOPs中,但是對於MAC這個參數的影響確實比較大的。
作者爲了驗證這個想法,對bottleneck這個層級進行了相應的修改,測試了是否含有Relu和short-cut兩種操作的情況,對比如下:
結論一目瞭然,沒有兩種操作的時候,更快一些。而且一個有意思的現象是,去掉short-cut對於速度的提升比Relu快一些,可以想到的是Relu只是對一個tensor進行操作,而short-cut是對兩個tensor進行的操作。
結論(這裏的結論很好,有必要重申一下)
作者首先簡要總結了一下4個guideline
1). 使用“平衡的”的卷積層(輸入輸出通道相同);
2). 小心使用分組卷積;
3). 減少使用碎片化的操作;
4). 減少元素級的操作;
隨後作者分析道最近的一些比較火的網絡結構:
ShuffleNetV1違反了G2,bottleneck的結構違反了G1,而MobileNetV2使用的inverse bottleneck的結構違反了G1,其中夾雜的DWconv和Relu都違反了G4,自動生成結構(auto-generated structures)高度碎片化違反了G3。
ShuffleNetV2結構
作者首先覆盤了ShuffleNetV1,認爲目前比較關鍵的問題是如何在全卷積或者分組卷積中維護大多數的卷積是平衡的。針對這個目標,作者提出了Channel Split的操作,同時構建了ShuffleNetV2。
Channel Split操作
上圖中(a)(b)是ShuffleNetV1的層結構,而後面的(c)(d)是ShuffleNetV2的層結構。下面稍微講一下筆者結合論文的理解。
Channel Split操作將整個特徵圖分爲c’組(假設爲A組)和c-c’(假設爲B組)兩個部分,主要有三個好處:
- 把整個特徵圖分爲兩個組了,但是這樣的分組又不像分組卷積一樣,增加了卷積時的組數,符合G2;
- 這樣分開之後,將A組認爲是通過short-cut通道的,而B組經過的bottleneck層的輸入輸出的通道數就可以保持一致,符合G1;
- 同時由於最後使用的concat操作,沒有用TensorAdd操作,符合G4;
可以看到,這樣一個簡單的通道分離的操作帶來了諸多好處;但是從理論上來說,這樣的結構是否還符合short-cut的初衷(即bottleneck學到的是殘差Residual部分)?這裏筆者也不好妄加揣測,但是可以想到的是經過後面的Channel Shuffle的亂序之後,每個通道應該都會經過一次bottleneck結構。
上述的結構是不改變輸入輸出通道數和特徵圖大小的情況,而池化操作使用圖(d)代替了,跟ShuffleNetV1類似,經過這樣的結構之後,圖像通道數擴張爲原先的2倍。
ShuffleNetV2網絡結構
相似於ShuffleNetV1,網絡也使用了4個不同的stage,結構如下圖:
值得特別注意的是!channel數都異常的小!這裏作者並沒有特別的解釋這個現象(按照MobileNetV2中對於Relu的分析,這個地方似乎有點兒激進?)。
ShuffleNetV2的分析
作者得到的結果是ShuffleNetV2既高效而且準確,主要分析有兩點原因:
- 1). 每個結構層(building block)的高效率使得能夠使用更多的特徵通道和更大的網絡容量(這個地方並沒有很理解);
- 2). 在每個結構層,都有一部分的通道直接通道下一個結構層,提高了特徵的重用度;
論文有對比了DenseNet和ShuffleNetV2重用度的區別,如下圖:
可以看到,在特徵重用方面,ShuffleNetV2在不同層之間保持了連接,但是不像DenseNet,過遠的層之間也會有很大的連接。
ShuffleNetV2的結果對比
這部分就是很枯燥的對比,這裏直接放圖,有趣的地方會說一下:
上述結果中有一個現象是MobileNetV1的速度在GPU上是最快的,作者說明這個現象是因爲MobileNetV1比於之後的幾個輕量級網絡,具有更貼近的4個guide line的設計,因此在GPU的速度更快,但是我們看到,在CPU上,ShuffleNet又扳回一城,而且快了許多。
這個圖中帶*號的模型是作者從Xception中得到了一些啓發,表明更大的感受野對於detection的任務更友好,因此作者在每個結構的1×1卷積之前添加了一個3×3的DWconv卷積層增大感受野,結果確實有所提升。
總結
不得不承認,ShuffleNet系列確實是很不錯的工作,V2更是對網絡的速度進行了深入的思考,秉着一切服務於速度的思路而提出了該結構,從準確度上來說,也絲毫不遜色於其他網絡。