從卷積拆分和分組的角度看CNN模型的演化

lee發表於2020-05-14

部落格:部落格園 | CSDN | blog

寫在前面

如題,這篇文章將嘗試從卷積拆分的角度看一看各種經典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

  • 大卷積核替換為多個堆疊的小核(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

  • Factorized Convolution(Inception V2),二維卷積變為行列分別卷積,先行卷積再列卷積,

    \[(K \times K) \rightarrow (K \times 1 + 1 \times K) \]

    source: http://arxiv.org/abs/1512.00567

  • 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

  • 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

  • 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

  • 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/

  • 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/

  • 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

  • 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 \]
    https://arxiv.org/abs/1801.04381

小結

最後小結一下,早期的CNN由一個個常規卷積層堆疊而成,而後,開始模組化,由一個個 module構成,module的演化,可以看成是不停地在常規卷積的計算量\(FLOPS = K \times K \times M \times N \times I \times I\)上做文章。

  • 拆分:卷積核是個3 D 的tensor,可以在不同維度上進行拆分,行列可拆分,高也可拆分,還可以拆分成多段串聯(類似SVD)。
  • 分組:如果多個卷積核放在一起,可以構成4D的tensor,增加的這一數量維上可以分組group。

不同拆分和分組的方式排列組合就構成了各種各樣的module。

相關文章