關於深度可分離卷積的理解
阿新 • • 發佈:2020-08-23
常規卷積
常規卷積中,連線的上一層一般具有多個通道(這裡假設為n個通道),因此在做卷積時,一個濾波器(filter)必須具有n個卷積核(kernel)來與之對應。一個濾波器完成一次卷積,實際上是多個卷積核與上一層對應通道的特徵圖進行卷積後,再進行相加,從而輸出下一層的一個通道特徵圖。在下一層中,若需要得到多個通道的特徵圖(這裡假設為m個通道),那麼對應的濾波器就需要m個。
用通俗的話來概括卷積,他起到的作用就是兩個:一個是對上一層的特徵圖進行尺寸調整,另一個是則是對上一層的特徵圖數量進行調整,也就是通道數的調整。
這裡不理解的可以看吳恩達有關三維卷積的講解視訊:
深度可分離卷積
深度可分離卷積,其實只對常規卷積做了一個很小的改動,但是帶來的確實引數量的下降,這無疑為網路的輕量化帶來了好處。
對於來自上一層的多通道特徵圖,首先將其全部拆分為單個通道的特徵圖,分別對他們進行單通道卷積,然後重新堆疊到一起。這被稱之為逐通道卷積(Deepthwise Convolution)。這個拆分的動作十分關鍵,在這一步裡,它只對來自上一層的特徵圖做了尺寸的調整,而通道數沒有發生變化。於是將前面得到的特徵圖進行第二次卷積,這是採取的卷積核都是1×1大小的,濾波器包含了與上一層通道數一樣數量的卷積核。一個濾波器輸出一張特徵圖,因此多個通道,則需要多個濾波器。這又被稱之為逐點卷積(Pointwise Convolution)。
引數量對比
假設存在這樣一個場景,上一層有一個64×64大小,3通道的特徵圖,需要經過卷積操作,輸出4個通道的特徵圖,並且要求尺寸不改變。我們可以對比一下采用常規卷積和深度可分離卷積引數量各是多少。
import torch.nn as nn from torchsummary import summary class normal_conv(nn.Module): def __init__(self, in_channels, out_channels): super(normal_conv, self).__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=True) def forward(self, x): return self.conv(x) class sep_conv(nn.Module): def __init__(self, in_channels, out_channels): super(sep_conv, self).__init__() self.deepthwise_conv = nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1, bias=True, groups=in_channels) self.pointwise_conv = nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0, bias=True, groups=1) def forward(self,x): d = self.deepthwise_conv(x) p = self.pointwise_conv(d) return p input_size = (3,64,64) conv1 = normal_conv(3,4) conv2 = sep_conv(3,4) print("使用常規卷積所需要的引數:") print(summary(conv1,input_size,batch_size=1)) print("使用深度可分離卷積所需要的引數:") print(summary(conv2,input_size,batch_size=1))
輸出結果:
使用常規卷積所需要的引數:
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
Conv2d-1 [1, 4, 64, 64] 112
================================================================
Total params: 112
Trainable params: 112
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.05
Forward/backward pass size (MB): 0.12
Params size (MB): 0.00
Estimated Total Size (MB): 0.17
----------------------------------------------------------------
None
使用深度可分離卷積所需要的引數:
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
Conv2d-1 [1, 3, 64, 64] 30
Conv2d-2 [1, 4, 64, 64] 16
================================================================
Total params: 46
Trainable params: 46
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.05
Forward/backward pass size (MB): 0.22
Params size (MB): 0.00
Estimated Total Size (MB): 0.27
----------------------------------------------------------------
None
可以看到,引數由112下降到了46,通道越多這種效果越明顯。