1. 分組卷積(Group Convolution)
分組卷積最早出現在AlexNet中,如下圖所示。在CNN發展初期,GPU資源不足以滿足訓練任務的要求,因此,Hinton採用了多GPU訓練的策略,每個GPU完成一部分卷積,最後把多個GPU的卷積結果進行融合。
接下來回顧一下常規卷積是怎樣進行的,假設輸入的特徵圖(Tensor)的shape爲,輸出通道數爲,那麼,卷積過程中就會有個卷積核(Convolution Kernel),每個卷積核的尺寸爲,其中,爲卷積核的大小,換句話說,就是每個卷積核會和輸入特徵圖的每個通道都進行卷積計算,每個卷積核的計算結果是各通道卷積結果的和。文字可能枯燥,下圖是是常規卷積的示意圖。
可以很明顯看出,常規卷積的計算結果中,特徵圖的每個通道和輸入特徵圖的所有通道都有關。下圖是分組卷積的示意圖,差別就非常明顯了。分組卷積的輸出特徵圖的每個通道,只和輸入特徵圖的一部分通道有關,而這部分通道,就是一個分組(Group)。依舊假設輸入特徵圖的尺寸爲,分爲3組進行分組卷積,那麼,對於每一組,輸出特徵圖的通道數都是,卷積核大小變爲,最後只需要將各個分組的計算結果按照通道進行連接(Cat)即可。
分組卷積可以很大程度上減少卷積所需的參數量,上述例子中,常規卷積所需的參數量(僅考慮卷積權重,不考慮偏置)爲:
相同的輸入輸出特徵圖,分組卷積所需的參數量爲:
即,分組卷積可將參數量減少爲原來的,爲分組數量。
2. 深度可分離卷積(Depthwise Separable Convolution)
大部分博客在介紹可分離卷積和分組卷積時,都是先介紹深度可分離卷積再介紹分組卷積。博主之所以將兩者順序做出了調換,是因爲,按照我的理解,深度可分離卷積是可以基於分組卷積進行理解和分析的。
單從名稱進行分析,Depthwise可理解爲逐深度,如此理解,深度可分離卷積就是逐個深度分開卷積,也就是逐個通道分開卷積。這樣子,深度可分離卷積就變得非常容易理解了,以分組卷積爲基礎,深度可分離卷積是分組爲的分組卷積。但是,其中也是有區別的,逐深度卷子只是深度可分離卷子的第一個過程,這個過程中,輸入特徵圖和輸出特徵圖的通道數保持一致,也就是,對於輸入特徵圖的每個通道,通過一個尺寸爲的卷積核,計算結果作爲輸出特徵圖的一個通道,不進行通道數的增加和減少。深度可分離卷積是通過**逐點卷積(Pointwise Convolution)**實現通道數改變的,這個過程使用大小爲的卷積覈實現,數量爲個,深度可分離卷積所需參數量爲:
3. PyTorch實現
Pytorch是2017年推出的深度學習框架,不同於Tensorflow基於靜態圖的模型搭建方式,PyTorch是完全動態的框架,推出以來很快成爲AI研究人員的熱門選擇並受到推崇。(介紹到此結束)
在PyTorch中,實現二維卷積是通過nn.Conv2d
實現的,這個函數是非常強大的,其功能不僅僅是實現常規卷積,通過合理的參數選擇就可以實現分組卷積、空洞卷積。API的官方介紹如下:
CLASS torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
- stride: controls the stride for the cross-correlation, a single number or a tuple.
- padding: controls the amount of implicit zero-paddings on both sides for padding number of points for each dimension.
- dilation: controls the spacing between the kernel points; also known as the à trous algorithm. It is harder to describe, but this link has a nice visualization of what dilation does.
- groups: controls the connections between inputs and outputs. in_channels and out_channels must both be divisible by groups. For example,
At groups=1, all inputs are convolved to all outputs.
At groups=2, the operation becomes equivalent to having two conv layers side by side, each seeing half the input channels, and producing half the output channels, and both subsequently concatenated.
At groups= in_channels, each input channel is convolved with its own set of filters.
3.1 分組卷積
分組卷積只需要對nn.Conv2d
中的groups
參數進行設置即可,表示需要分的組數,groups
的默認值爲1,即進行常規卷積。以下是實現分組卷積的代碼:
class CSDN_Tem(nn.Module):
def __init__(self, in_ch, out_ch, groups):
super(CSDN_Tem, self).__init__()
self.conv = nn.Conv2d(
in_channels=in_ch,
out_channels=out_ch,
kernel_size=3,
stride=1,
padding=1,
groups=groups
)
def forward(self, input):
out = self.conv(input)
return out
通過以下代碼對該模型進行測試,設定輸入特徵圖通道數爲16,輸出特徵圖通道數爲32,分組數目爲4:
conv = CSDN_Tem(16, 32, 4)
print(summary(conv, (16, 64, 64), batch_size=1))
控制檯輸出爲:
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
Conv2d-1 [1, 32, 64, 64] 1,184
================================================================
Total params: 1,184
Trainable params: 1,184
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.25
Forward/backward pass size (MB): 1.00
Params size (MB): 0.00
Estimated Total Size (MB): 1.25
----------------------------------------------------------------
這一分組卷積過程所需參數爲1184個,其中包含了偏置(Bias).
3.2 深度可分離卷積
深度可分離卷積的PyTorch代碼如下:
class CSDN_Tem(nn.Module):
def __init__(self, in_ch, out_ch):
super(CSDN_Tem, self).__init__()
self.depth_conv = nn.Conv2d(
in_channels=in_ch,
out_channels=in_ch,
kernel_size=3,
stride=1,
padding=1,
groups=in_ch
)
self.point_conv = nn.Conv2d(
in_channels=in_ch,
out_channels=out_ch,
kernel_size=1,
stride=1,
padding=0,
groups=1
)
def forward(self, input):
out = self.depth_conv(input)
out = self.point_conv(out)
return out
採用和分組卷積相同的輸入和輸出通道數,測試代碼如下:
conv = CSDN_Tem(16, 32)
print(summary(conv, (16, 64, 64), batch_size=1))
控制檯輸出結果爲:
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
Conv2d-1 [1, 16, 64, 64] 160
Conv2d-2 [1, 32, 64, 64] 544
================================================================
Total params: 704
Trainable params: 704
Non-trainable params: 0
----------------------------------------------------------------
深度可分離卷積實現相同的操作僅需704個參數。
如有疑問,歡迎留言!