引言
深度神經網絡模型被廣泛應用在圖像分類、物體檢測等機器視覺任務中,並取得了巨大成功。然而,由於存儲空間和功耗的限制,神經網絡模型在嵌入式設備上的存儲與計算仍然是一個巨大的挑戰。
目前工業級和學術界設計輕量化神經網絡模型主要有4個方向:
- 人工設計輕量化神經網絡模型
- 基於神經網絡架構搜索(Neural Architecture Search,NAS)的自動化設計神經網絡
- CNN模型壓縮
- 基於AutoML的自動模型壓縮
本文首先介紹基本卷積計算單元,並基於這些單元介紹MobileNet V1&V2,ShuffleNet V1&V2的設計思路。其次,最后介紹自動化設計神經網絡的主流方法和基本思路。最后概述CNN模型壓縮的主要方法,詳細說明基於AutoML的自動模型壓縮的相關算法:AMC、PockFlow以及TensorFlow lite的代碼實現。
基本卷積運算
標准卷積
卷積層的 輸入為$(N,C_{in},H_{in},W_{in})$。輸出為 $(N,C_{out},H_{out},W_{out})$,其中$H_{\text{out}}$和$W_{\text{out}}$ 分別為特征圖的高度和寬度。卷積核(Kernel)的高和寬:$K[0]$和$K[1]$
$$FLOPS=(C_{in}*K[0]·K[1])*H_{\text{out}}·W_{\text{out}}*C_{out}\quad(考慮bias)$$
輸出特征圖中有$H_{\text{out}}*W_{\text{out}}*C_{out}$個像素;每個像素對應一個立體卷積核$k[0]*k[1]*C_{in}$在輸入特征圖上做立體卷積卷積出來的;而這個立體卷積操作,卷積核上每個點都對應一次MACC操作
圖3標准卷積:空間維度和通道維度示意圖
吃個例子
輸入shape為(7*7*3),卷積核大小為(filter size)(3*3*3),卷積核個數(filter num \ channel_out)為2,輸出shape為(3*3*2)。
Grouped Convolution
分組卷積是標准卷積的變體,其中輸入特征通道被為G組(圖4),並且對於每個分組的信道獨立地執行卷積,則分組卷積計算量為標准卷積計算量的1/G:
$$FLOPS=\frac{(C_{in}*K[0]*K[1])*H_{\text{out}}*W_{\text{out}}*C_{out}}{G}$$
分組卷積:空間維度和通道維度示意圖
Depthwise convolution
引用:Chollet F. Xception: Deep learning with depthwise separable convolutions[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2017: 1251-1258.
Depthwise convolution 是指將輸入特征圖$(batch\_size, H\_{in}, W\_{in}, C\_{in})$分為group組,Group=$C\_{in}$(既Depthwise 是Grouped Convlution的特殊簡化形式),然后每一組做k*k卷積,Depthwise convolution的計算量為普通卷積的$1/C_{in}$,通過忽略通道維度的卷積顯著降低計算量
$$FLOPS=K[0]*K[1]*H_{\text{out}}*W_{\text{out}}*C_{in}$$
Depthwise相當於單獨收集每個Channel的空間特征。
Depthwise卷積:空間維度和通道維度示意圖
pointwise convolution
Pointwise是指對輸入$(batch\_size, H\_{in}, W\_{in}, C\_{in})$做$k$個普通的 1x1卷積,主要用於改變輸出通道特征維度,相當於在通道之間“混合”信息。Pointwise計算量為
$$FLOPS=H_{\text{out}}*W_{\text{out}}*C_{in}*C_{out}$$
Pointwise卷積:空間維度和通道維度示意圖
Channel Shuffle
Grouped Convlution導致模型的信息流限制在各個group內,組與組之間沒有信息交換,這會影響模型的表示能力。因此,需要引入group之間信息交換的機制,即Channel Shuffle操作。
Channel shuffle是ShuffleNet提出的,通過張量的reshape 和transpose,實現改變通道之間順序。Channel shuffle沒有卷積計算,僅簡單改變通道的順序。
Channel shuffle:空間維度和通道維度示意圖
2 輕量化模型設計
SequeezeNet
Iandola F N, Han S, Moskewicz M W, et al. SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and< 0.5 MB model size[J]. arXiv preprint arXiv:1602.07360, 2016.
在網絡結構設計方面主要采取以下三種方式:
- 用1*1卷積核替換3*3卷積:理論上一個1*1卷積核的參數是一個3*3卷積核的1/9,可以將模型尺寸壓縮9倍。
- 減小3*3卷積的輸入通道數:根據上述公式,減少輸入通道數不僅可以減少卷積的運算量,而且輸入通道數與輸出通道數相同時還可以減少MAC。
- 延遲降采樣:分辨率越大的輸入能夠提供更多特征的信息,有利於網絡的訓練判斷,延遲降采樣可以提高網絡精度。
SqueezeNet提出一種多分支結構——fire model,其中是由Squeeze層和expand層構成。Squeeze層是由s1個1*1卷積組成,主要是通過1*1的卷積降低expand層的輸入維度;expand層利用e1個1*1和e3個3*3卷積構成多分支結構提取輸入特征,以此提高網絡的精度(其中e1=e3=4*s1)。
DepthwiseSeparableConv
Howard A G, Zhu M, Chen B, et al. MobileNets: Efficient convolutional neural networks for mobile vision applications[J]. arXiv preprint arXiv:1704.04861, 2017.
深度可分離卷積由 一個深度卷積(depthwise convolution)和一個逐點卷積(pointwise convolution)組成。
- 采用深度卷積(depthwise convolution)在減少參數數量的同時提升運算速度。但是由於每個feature map只被一個卷積核卷積,因此經過深度卷積輸出的feature map不能只包含輸入特征圖的全部信息,而且特征之間的信息不能進行交流,導致“信息流通不暢”。
- 采用逐點卷積(pointwise convolution)實現通道特征信息交流,解決深度卷積卷積導致“信息流通不暢”的問題。
深度可分離卷積總計算量是:
$$FLOPS = depthwise+pointwise =K[0]*K[1]*H_{\text{out}}*W_{\text{out}}*C_{in}+H_{\text{out}}*W_{\text{out}}*C_{in}*C_{out}=H_{\text{out}}*W_{\text{out}}*C_{in}(K[0]*K[1]+C_{out})$$
$$\frac{depthwise+pointwise}{conv}=\frac{H_{\text{out}}*W_{\text{out}}*C_{in}(K[0]*K[1]+C_{out})}{(C_{in}*K[0]·K[1])*H_{\text{out}}·W_{\text{out}}*C_{out}}=\frac{1}{C_{out}}+\frac{1}{(K[0]·K[1]}$$
一般網絡架構中$C_{out}$遠大於卷積核尺寸,(e.g. K=3 and M ≥ 32),既深度可分離卷積計算量可顯著降低標准卷積計算量的1/8–1/9。
深度可分離卷積:空間維度和通道維度示意圖
MobileNet-v2
Sandler M, Howard A, Zhu M, et al. Mobilenetv2: Inverted residuals and linear bottlenecks[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2018: 4510-4520.
MobileNet V1設計時參考傳統的VGGNet等鏈式架構,但層疊過多的卷積層會出現一個問題,就是梯度彌散(Vanishing)。殘差網絡使信息更容易在各層之間流動,包括在前向傳播時提供特征重用,在反向傳播時緩解梯度信號消失。於是改進版的MobileNet V2[3]增加skip connection,並且對ResNet和Mobilenet V1基本Block如下改進:
- 采用Inverted residuals:為了保證網絡可以提取更多的特征,在residual block中第一個1*1 Conv和3*3 DW Conv之前進行通道擴充
- Linear bottlenecks:為了避免ReLU對特征的破壞,在residual block的Eltwise sum之前的那個 1*1 Conv 不再采用ReLU
- stride=2的Conv不使用shot-cot,stride=1的Conv使用shot-cut
Inverted residuals
ResNet中Residuals block先經過1*1的卷積,把feature map的通道數降下來,再經過3*3 卷積,最后經過一個1*1 的卷積將通道數再“擴張”回去。即采用先壓縮,后擴張的方式。inverted residuals采用先擴張,后壓縮的方式。
原因:MobileNet采用DW conv提取特征,由於DW conv本身提取的特征數就少,再經過傳統residuals block進行“壓縮”,此時提取的特征數會更少,因此inverted residuals對其進行“擴張”,保證網絡可以提取更多的特征。
Linear bottlenecks
ReLu激活函數會破壞特征。ReLu對於負的輸入,輸出全為0,而本來DW conv特征通道已經被“壓縮”,再經過ReLu的話,又會損失一部分特征。采用Linear,目的是防止Relu破壞特征。
shortcut
stride=2的conv不使用shot-cot,stride=1的conv使用shot-cut
ShuffleNet-v1
Zhang X, Zhou X, Lin M, et al. Shufflenet: An extremely efficient convolutional neural network for mobile devices[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2018: 6848-6856.
MobileNet中1*1卷積的操作占據了約95%的計算量,所以ShuffleNet將1*1也更改為group卷積,使得相比MobileNet的計算量大大減少。group卷積與DW存在同樣使“通道信息交流不暢”的問題,MobileNet中采用pointwise(PW) Conv解決上述問題,SheffleNet中采用channel shuffle,將輸入的group進行打散,從而保證每個卷積核的感受野能夠分散到不同group的輸入中,增加了模型的學習能力。
- 采用group conv減少大量參數:roup conv與DW conv存在相同的“信息流通不暢”問題
- 采用channel shuffle解決上述問題:MobileNet中采用PW conv解決上述問題,SheffleNet中采用channel shuffle
- 采用concat替換add操作:avg pooling和DW conv(s=2)會減小feature map的分辨率,采用concat增加通道數從而彌補分辨率減小而帶來信息的損失
ShuffleNet的shuffle操作如圖所示
avg pooling和DW conv(s=2)會減小feature map的分辨率,采用concat增加通道數從而彌補分辨率減小而帶來信息的損失;實驗表明:多使用多通道(提升通道的使用率),有助於提高小模型的准確率。
ResNet bootleneck計算量:
$$FLOPS=H_{out}*W_{out}(2*C_{in}*C_{in}+K[0]*K[1]*C_{in}*C_{in})$$
ShuffleNet stride=1計算量:
$FLOPS=H_{out}*W_{out}(\frac{2*C_{in}*C_{in}}{8}+K*C_{in}*C_{in})$
對比可知,ShuffleNet和ResNet結構可知,ShuffleNet計算量降低主要是通過分組卷積實現。ShuffleNet雖然降低了計算量,但是引入兩個新的問題:
- channel shuffle在工程實現占用大量內存和指針跳轉,這部分很耗時。
- channel shuffle的規則是人工設計,分組之間信息交流存在隨意性,沒有理論指導。
ShuffleNet-v2
Ma N, Zhang X, Zheng H T, et al. Shufflenet v2: Practical guidelines for efficient cnn architecture design[C]//Proceedings of the European conference on computer vision (ECCV). 2018: 116-131.
ShuffleNet-v2提出影響神經網絡速度的4個因素:
- FLOPs(FLOPs就是網絡執行了多少multiply-adds操作)
- MAC(內存訪問成本)
- 並行度(如果網絡並行度高,速度明顯提升)
- 計算平台(GPU,ARM)
ShuffleNet-v2 提出了4點網絡結構設計策略:
- 輸入輸出的channel相同時,MAC最小
- 組卷積會增加MAC
- 多分支降低運算效率;
- 元素級運算增加計算量
depthwise convolution 和 瓶頸結構增加了 MAC,用了太多的 group,跨層連接中的 element-wise Add 操作也是可以優化的點。所以在 shuffleNet V2 中增加了幾種新特性。
ShuffleNet V2 引入通道分割(channel split)操作,將輸入通道分為兩組:一個分支為shortcut流,另一個分支含三個卷積(且三個分支的通道數一樣),分支合並采用拼接(concat),讓前后的channel數相同,最后進行Channel Shuffle。元素級的三個運算channel split、concat、Channel Shuffle合並一個Element-wise,顯著降低計算復雜度。
所謂的 channel split 其實就是將通道數一分為2,化成兩分支來代替原先的分組卷積結構,並且每個分支中的卷積層都是保持輸入輸出通道數相同,其中一個分支不采取任何操作減少基本單元數,最后使用了 concat 代替原來的 elementy-wise add,並且后面不加 ReLU,再加入channle shuffle 來增加通道之間的信息交流。 對於下采樣層,在這一層中對通道數進行翻倍。 在網絡結構的最后,即平均值池化層前加入一層 1x1 的卷積層來進一步的混合特征。
(a)ShuffleNet 基本單元;(b)用於空間下采樣 (2×) 的 ShuffleNet 單元
(c)ShuffleNet V2 的基本單元;(d)用於空間下采樣 (2×) 的 ShuffleNet V2 單元
由於高效,可以增加更多的channel,增加網絡容量,采用split使得一部分特征直接與下面的block相連,特征復用(DenseNet)
Xception
Chollet F. Xception: Deep learning with depthwise separable convolutions[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2017: 1251-1258.
Xception假設卷積的時候要將通道的卷積與空間的卷積進行分離,這樣會比較好。Xception是對Inception v3的另一種改進,主要是采用depthwise separable convolution來替換原來Inception v3中的卷積操作。
與原版的Depth-wise convolution有兩個不同之處:
- 原版Depth-wise convolution,先逐通道卷積,再1*1卷積;而Xception是反過來,先1*1卷積,再逐通道卷積;
- 原版Depth-wise convolution的兩個卷積之間是不帶激活函數的,而Xception在經過1*1卷積之后會帶上一個Relu的非線性激活函數;
Xception的發展流程如下:
圖:左:Inception module (Inception V3);中:A simplified Inception module;右:XInception 模塊
總結
在移動端部署深度卷積網絡,無論什么視覺任務,選擇高精度的計算量少和參數少的骨干網是必經之路。輕量化網絡是移動端的研究重點,目前的一些主要的輕量化網絡及特點如下:
- SqueezeNet:提出Fire Module設計,主要思想是先通過1x1卷積壓縮通道數(Squeeze),再通過並行使用1x1卷積和3x3卷積來抽取特征(Expand),通過延遲下采樣階段來保證精度。綜合來說,SqueezeNet旨在減少參數量來加速。
通過減少MAdds來加速的輕量模型:
- MobileNet V1:提出深度可分離卷積;
- MobileNet V2:提出反轉殘差線性瓶頸塊;
- ShuffleNet:結合使用分組卷積和通道混洗操作;
- CondenseNet:dense連接
- ShiftNet:利用shift操作和逐點卷積代替了昂貴的空間卷積
從SqueezeNet開始模型的參數量就不斷下降,為了進一步減少模型的實際操作數(MAdds),MobileNetV1利用了深度可分離卷積提高了計算效率,而MobileNetV2則加入了線性bottlenecks和反轉殘差模塊構成了高效的基本模塊。隨后的ShuffleNet充分利用了組卷積和通道shuffle進一步提高模型效率。CondenseNet則學習保留有效的dense連接在保持精度的同時降低,ShiftNet則利用shift操作和逐點卷積代替了昂貴的空間卷積。
(1)MobileNet-v1中深度可分離卷積的理解:
將傳統卷積分解為空間濾波和特征生成兩個步驟,空間濾波對應較輕的3x3 depthwise conv layer,特征生成對應較重的1x1 pointwise conv layer.
(2)MobileNet-v2中反轉殘差線性瓶頸塊的理解:
擴張(1x1 conv) -> 抽取特征(3x3 depthwise)-> 壓縮(1x1 conv)
當且僅當輸入輸出具有相同的通道數時,才進行殘余連接
在最后“壓縮”完以后,沒有接ReLU激活,作者認為這樣會引起較大的信息損失
該結構在輸入和輸出處保持緊湊的表示,同時在內部擴展到更高維的特征空間,以增加非線性每通道變換的表現力。
(3)MnasNet理解:
在MobileNet-v2的基礎上構建,融入SENet的思想
與SE-ResBlock相比,不同點在於SE-ResBlock的SE layer加在最后一個1x1卷積后,而MnasNet的SE layer加在depthwise卷積之后,也就是在通道數最多的feature map上做Attention。
(4)MobileNet-v3的理解:
MobileNet-v3集現有輕量模型思想於一體,主要包括:swish非線性激活Squeeze and Excitation思想為了減輕計算swish中傳統sigmoid的代價,提出了hard sigmoid
這么一看就發現,輕量化主要得益於depth-wise convolution,因此大家可以考慮采用depth-wise convolution 來設計自己的輕量化網絡, 但是要注意“信息流通不暢問題”
解決“信息流通不暢”的問題,MobileNet采用了point-wise convolution,ShuffleNet采用的是channel shuffle。MobileNet相較於ShuffleNet使用了更多的卷積,計算量和參數量上是劣勢,但是增加了非線性層數,理論上特征更抽象,更高級了;ShuffleNet則省去point-wise convolution,采用channel shuffle,簡單明了,省去卷積步驟,減少了參數量。
參考
【Github文章】深度學習500問
【知乎】輕量化神經網絡綜述(文后還有NAS與神經網絡架構搜索、AutoML自動模型壓縮)
【卷積動圖】https://cs231n.github.io/assets/conv-demo/index.html
【CSDN】最全動畫詮釋各種卷積網絡及實現機制
【github】卷積動畫
【github】ShuffleNet-Series