分组卷积(Group Convolution)
分组卷积将输入特征图进行分组,分别对每组的特征图进行卷积操作,得到输出的特征图,最后再将每组卷积后得到的特征图拼接在一起,就完成了整个卷积操作。
在PyTorch中,输入特征图个数与输出特征图个数需要能够被分组数整除,因为输出特征图个数需要均摊给每一组。比如输入特征图个数为X,输出特征图个数为Y,分组数为g,且g可整除X和Y,那么每一组的输入特征图个数为X/g,输出特征图个数为Y/g,总的输出特征图个数为(Y/g)*g=Y
假设输入特征图个数为6,卷积核尺寸为3*3,输出特征图个数为10,不考虑偏置项。以下操作基于本例.
普通卷积:
当分组数为1时,就是普通的卷积
import torch
import torch.nn as nn
from torchsummary import summary
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv=nn.Conv2d(in_channels=6,out_channels=10,kernel_size=3,groups=1,bias=False)
def forward(self,x):
return self.conv(x)
model=Model()
查看参数量:
参数量计算方法:
1*((3*3*(6/1))*(10/1))=540
1是分组数
3*3是卷积核尺寸
6是输入特征图个数
10是输出特征图个数
分组卷积:
当分组数不为1时,就是分组卷积
import torch
import torch.nn as nn
from torchsummary import summary
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv=nn.Conv2d(in_channels=6,out_channels=10,kernel_size=3,groups=2,bias=False)
def forward(self,x):
return self.conv(x)
model=Model()
查看参数量:
参数量计算方法:
2 * ((3*3*(6/2))*(10/2))=270
2是分组数
3*3是卷积核尺寸
6是输入特征图个数
10是输出特征图个数
可以看到,我们分了两组,参数量也减半。
深度可分离卷积(Depthwise Separable Convolution)
深度可分离卷积包含两个步骤:逐通道卷积和逐点卷积。
假设输入特征图个数为6,卷积核尺寸为3*3,输出特征图个数为12,不考虑偏置项。以下操作基于本例.
逐通道卷积(Depthwise Convolution)
当分组卷积的分组数=输入特征图个数=输出特征图个数时,就得到了逐通道卷积:
import torch
import torch.nn as nn
from torchsummary import summary
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv=nn.Conv2d(in_channels=6,out_channels=6,kernel_size=3,groups=6,bias=False)
def forward(self,x):
return self.conv(x)
model=Model()
查看参数量:
参数量计算方法:
6 * ((3*3*(6/6))*(6/6))=54
6是分组数,等于输入特征图个数
3*3是卷积核尺寸
6是输入特征图个数,也是输出特征图个数
逐点卷积(Pointwise Convolution)
逐点卷积就是普通的1*1卷积(分组数为1)
import torch
import torch.nn as nn
from torchsummary import summary
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv=nn.Conv2d(in_channels=6,out_channels=12,kernel_size=1,groups=1,bias=False)
def forward(self,x):
return self.conv(x)
model=Model()
查看参数量:
参数量计算方法:
1 * ((1*1*(6/1))*(12/1))=72
1是分组数,等于输入特征图个数
1*1是卷积核尺寸
6是输入特征图个数
12是输出特征图个数
至此,逐通道卷积与逐点卷积的参数量之和为:54+72=126
深度可分离卷积可以描述为:
import torch
import torch.nn as nn
from torchsummary import summary
class Model(nn.Module):
def __init__(self):
super().__init__()
self.depthwise_conv=nn.Conv2d(in_channels=6,out_channels=6,kernel_size=3,groups=6,bias=False)#groups=in_channels=out_channels
self.pointwise_conv=nn.Conv2d(in_channels=6,out_channels=12,kernel_size=1,groups=1,bias=False)
def forward(self,x):
return self.pointwise_conv(self.depthwise_conv(x))
model=Model()
查看参数量:
参数量也是54+72=126
由此可见,深度可分离卷积正是逐通道卷积与逐点卷积的叠加。
普通卷积
import torch
import torch.nn as nn
from torchsummary import summary
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv=nn.Conv2d(in_channels=6,out_channels=12,kernel_size=3,groups=1,bias=False)
def forward(self,x):
return self.conv(x)
model=Model()
查看参数量:
参数量计算方法:
1 * ((3*3*(6/1))*(12/1))=648
1是分组数
3*3是卷积核尺寸
6是输入特征图个数
12是输出特征图个数
看,输出特征图个数一样的前提下,普通卷积的参数量远多于深度可分离卷积。
正因为深度可分离卷积的参数量较少,使得它在轻量化网络中得到了广泛应用,有时间可以盘点下这些轻量化网络。
参考:
[1] https://zhuanlan.zhihu.com/p/92134485 [2] https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html
南极Python交流群已成立,长按下方二维码添加我的微信,备注加群即可,欢迎进群学习交流(划水
)

原创不易,感谢点赞,分享和在看的你!




