部落格:[部落格園](https://www.cnblogs.com/shine-lee/) | [CSDN](https://blog.csdn.net/blogshinelee) | [blog](https://blog.shinelee.me/) # 寫在前面 如題,這篇文章將嘗試從卷積拆分的角度看一看各種經典CNN backbone網路module是如何演進的,為了視角的統一,僅分析單條路徑上的卷積形式。 # 形式化 方便起見,對常規卷積操作,做如下定義, - $I$:輸入尺寸,長$H$ 寬$W$ ,令長寬相同,即$I = H = W$ - $M$:輸入channel數,可以看成是tensor的高 - $K$:卷積核尺寸$K \times K$,channel數與輸入channel數相同,為$M$ - $N$:卷積核個數 - $F$:卷積得到的feature map尺寸$F \times F$,channel數與卷積核個數相同,為$N$ 所以,輸入為$M \times I \times I$的tensor,卷積核為$N \times M \times K \times K$的tensor,feature map為$N \times F \times F$的tensor,所以常規卷積的計算量為 $$ FLOPS = K \times K \times M \times N \times F \times F $$ 特別地,如果僅考慮SAME padding且$stride = 1$的情況,則$F = I$,則計算量等價為 $$ FLOPS = K \times K \times M \times N \times I \times I $$ 可以看成是$(K \times K \times M) \times (N \times I \times I)$,前一個括號為卷積中一次內積運算的計算量,後一個括號為需要多少次內積運算。 引數量為 $$ \#Params = N \times M \times K \times K $$ # 網路演化 總覽SqueezeNet、MobileNet V1 V2、ShuffleNet等各種輕量化網路,可以看成對卷積核$M \times K \times K$ 進行了各種拆分或分組(同時引入啟用函式),這些拆分和分組通常會減少引數量和計算量,這就為進一步增加捲積核數量$N$讓出了空間,同時這種結構上的變化也是一種正則,通過上述變化來獲得性能和計算量之間的平衡。 這些變化,從整體上看,相當於對原始$FLOPS = K \times K \times M \times N \times I \times I$做了各種變換。 下面就從這個視角進行一下疏理,簡潔起見,只列出其中發生改變的因子項, - **Group Convolution(AlexNet)**,對輸入進行分組,卷積核數量不變,但channel數減少,相當於 $$ M \rightarrow \frac{M}{G} $$ ![Convolution VS Group Convolution](https://s2.ax1x.com/2019/01/08/FLPc1x.png) - **大卷積核替換為多個堆疊的小核(VGG)**,比如$5\times 5$替換為2個$3\times 3$,$7\times 7$替換為3個$3\times 3$,保持感受野不變的同時,減少引數量和計算量,相當於把 大數乘積 變成 小數乘積之和, $$ (K \times K) \rightarrow (k \times k + \dots + k \times k) $$ ![https://discuss.pytorch.org/t/dynamic-structure-of-cnn/45870/2](https://s1.ax1x.com/2020/05/14/YDA7Mq.png) - **Factorized Convolution(Inception V2)**,二維卷積變為行列分別卷積,先行卷積再列卷積, $$ (K \times K) \rightarrow (K \times 1 + 1 \times K) $$ ![source: http://arxiv.org/abs/1512.00567](https://s1.ax1x.com/2020/03/25/8jioCt.png) - **Fire module(SqueezeNet)**,pointwise+ReLU+(pointwise + 3x3 conv)+ReLU,pointwise降維,同時將一定比例的$3\times 3$卷積替換為為$1 \times 1$, $$ (K \times K \times M \times N) \rightarrow (M \times \frac{N}{t} + \frac{N}{t} \times (1-p)N + K \times K \times \frac{N}{t} \times pN) \\ K = 3 $$ ![https://arxiv.org/abs/1602.07360](https://s1.ax1x.com/2020/05/14/YDE40K.png) - **Bottleneck(ResNet)**,**pointwise+BN ReLU+3x3 conv+BN ReLU+pointwise**,類似於對channel維做SVD, $$ (K \times K \times M \times N) \rightarrow (M \times \frac{N}{t} + K \times K \times \frac{N}{t} \times \frac{N}{t} + \frac{N}{t} \times N) \\ t = 4 $$ ![https://arxiv.org/abs/1512.03385](https://s2.ax1x.com/2020/02/21/3K34c8.png) - **ResNeXt Block(ResNeXt)**,相當於引入了group $3\times 3$ convolution的bottleneck, $$ (K \times K \times M \times N) \rightarrow (M \times \frac{N}{t} + K \times K \times \frac{N}{tG} \times \frac{N}{t} + \frac{N}{t} \times N) \\t = 2, \ G = 32 $$ ![https://arxiv.org/abs/1611.05431](https://s1.ax1x.com/2020/05/14/YDZxJg.png) - **Depthwise Separable Convolution(MobileNet V1)**,**depthwise +BN ReLU + pointwise + BN ReLU**,相當於將channel維單獨分解出去, $$ (K \times K \times N) \rightarrow (K \times K + N) $$ ![https://mc.ai/review-xception-with-depthwise-separable-convolution-better-than-inception-v3-image/](https://s1.ax1x.com/2020/05/14/YDmdCF.png) - **Separable Convolution(Xception)**,**pointwise + depthwise + BN ReLU**,也相當於將channel維分解出去,但前後順序不同(但因為是連續堆疊,其實跟基本Depthwise Separable Convolution等價),同時移除了兩者間的ReLU, $$ (K \times K \times M) \rightarrow (M + K \times K) $$ 但實際在實現時還是depthwise + pointwise + ReLU。。。 ![https://mc.ai/review-xception-with-depthwise-separable-convolution-better-than-inception-v3-image/](https://s1.ax1x.com/2020/05/14/YDmf8e.png) - **pointwise group convolution and channel shuffle(ShuffleNet)**,**group pointwise+BN ReLU+Channel Shuffle+depthwise+BN+group pointwise+BN**,相當於bottleneck中2個pointwise引入相同的group,同時$3\times 3$ conv變成depthwise,也就是說3個卷積層都group了,這會阻礙不同channel間(分組間)的資訊交流,所以在第一個group pointwise後加入了channel shuffle,即 $$ (K \times K \times M \times N) \rightarrow (\frac{M}{G} \times \frac{N}{t} + channel \ shuffle +K \times K \times \frac{N}{t} + \frac{N}{tG} \times N) $$ ![https://arxiv.org/abs/1707.01083](https://s1.ax1x.com/2020/05/14/YDuvBn.png) - **Inverted Linear Bottleneck(MobileNet V2)**,bottleneck是先通過pointwise降維、再卷積、再升維,Inverted bottleneck是先升維、再卷積、再降維,**pointwise+BN ReLU6+depthwise+BN ReLU6+pointwise+BN**, $$ (K \times K \times M \times N) \rightarrow (M \times tM + K \times K \times tM + tM \times N) \\t = 6 $$ # 小結 最後小結一下,早期的CNN由一個個常規卷積層堆疊而成,而後,開始模組化,由一個個 module構成,module的演化,可以看成是不停地在常規卷積的計算量$FLOPS = K \times K \times M \times N \times I \times I$上做文章。 - **拆分**:卷積核是個3 D 的tensor,可以在不同維度上進行拆分,行列可拆分,高也可拆分,還可以拆分成多段串聯(類似SVD)。 - **分組**:如果多個卷積核放在一起,可以構成4D的tensor,增加的這一數量維上可以分組group。 不同拆分和分組的方式排列組合就構成了各種各樣的m