寫在前面
如題,這篇文章將嘗試從卷積拆分的角度看一看各種經典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,所以常規卷積的計算量為
特別地,如果僅考慮SAME padding且\(stride = 1\)的情況,則\(F = I\),則計算量等價為
可以看成是\((K \times K \times M) \times (N \times I \times I)\),前一個括號為卷積中一次內積運算的計算量,後一個括號為需要多少次內積運算。
引數量為
網路演化
總覽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} \] -
大卷積核替換為多個堆疊的小核(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) \] -
Factorized Convolution(Inception V2),二維卷積變為行列分別卷積,先行卷積再列卷積,
\[(K \times K) \rightarrow (K \times 1 + 1 \times K) \] -
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 \] -
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 \] -
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 \] -
Depthwise Separable Convolution(MobileNet V1),depthwise +BN ReLU + pointwise + BN ReLU,相當於將channel維單獨分解出去,
\[(K \times K \times N) \rightarrow (K \times K + N) \] -
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。。。
-
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) \] -
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。
不同拆分和分組的方式排列組合就構成了各種各樣的module。