首先看官方文档
1 groups = 1(默认值)
就如同普通的卷积
import torch
import torch.nn as nn
N,C_in,H,W,C_out = 10,4,16,16,6
x = torch.randn(N,C_in,H,W).float()
conv = nn.Conv2d(C_in,C_out,kernel_size=3,stride=3,padding=1)
y = conv(x)
print(y.size())
'''torch.Size([10, 6, 6, 6])'''
2 groups = 2 分组卷积
简单翻译一下,当groups = 2时,相当于有两个卷积层,每一层的输入为原来输入通道数的一半,输出也为原来输出的一半,然后再连接:
import torch
import torch.nn as nn
N,C_in,H,W,C_out = 10,4,16,16,6
x = torch.randn(N,C_in,H,W).float()
conv = nn.Conv2d(C_in,C_out,kernel_size=3,stride=3,padding=1)
conv_group = nn.Conv2d(C_in,C_out,kernel_size=3,stride=3,padding=1,groups = 2)
y = conv(x)
y_group = conv_group(x)
print(y.size())
print(y_group.size())
'''torch.Size([10, 6, 6, 6])'''
'''torch.Size([10, 6, 6, 6])'''
3 深度卷积depthwise
此时group=in_channels,也就是对每一个输入的通道分别用不同的卷积核卷积。out_channels必须是in_channels的整数倍,即
-
当k = 1时,out_channels = in_channels,每一个卷积核分别和每一个输入的通道进行卷积,最后在concat起来。如图
[2].png
例如:
import torch
import torch.nn as nn
N,C_in,H,W,C_out = 10,4,16,16,4
x = torch.randn(N,C_in,H,W).float()
conv = nn.Conv2d(C_in,C_out,kernel_size=3,stride=3,padding=1,bias = False)
conv_group = nn.Conv2d(C_in,C_out,kernel_size=3,stride=3,padding=1,groups = C_in,bias=False)
y = conv(x)
y_group = conv_group(x)
conv_1x1 = nn.Conv2d(C_in,C_out,kernel_size=1)
print("groups=1时参数大小:%d"%sum(param.numel() for param in conv.parameters()))
print("groups=in_channels时参数大小:%d"%sum(param.numel() for param in conv_group.parameters()))
'''
groups=1时参数大小:144
groups=in_channels时参数大小:36
'''
在上面的例子中,in_channels = out_channels = 4,kernal_size = 3
当groups=1时,参数大小为即4*3*3*4 = 144
当groups = in_channels时,参数大小为
即4*3*3 = 36
- 当为k>1的整数时,此时每一个输入的特征图对应k个卷积核,生成k特征图,最终生成的特征图个数就是k×in_channel .