在pytorch官网有如下介绍:
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode=‘zeros’, device=None, dtype=None)
in_channels
: 输入通道数
out_channels
: 输出通道数
kernel_size
: 卷积核尺寸
stride
: 卷积核移动步长
padding
: 图像以0扩张
dilation
: 是否开启空洞卷积
groups
: 分组设置,每(in_channels/groups)张输入通道数对应一个输出通道
bias
: 是否设定要学习的偏置
padding_mode
: padding的模式
device
: 设备
dtype
: 数据类型
import torch
import torch.nn as nn
# 设定一个[1, 3, 5, 5]的输入
input = torch.Tensor([[[[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5]],
[[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5]],
[[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5]]]])
# 设定一个卷积
conv = nn.Conv2d(in_channels=3,
out_channels=3,
kernel_size=3,
stride=1,
padding=0,
dilation=1,
groups=3)
# 设定卷积的权重数值
conv.weight.data = torch.Tensor([[[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]],
[[[2, 2, 2],
[2, 2, 2],
[2, 2, 2]]],
[[[3, 3, 3],
[3, 3, 3],
[3, 3, 3]]]])
# 利用卷积得到输出
output = conv(input)
print(output)
>>> tensor([[[[ 18.2388, 27.2388, 36.2388],
[ 18.2388, 27.2388, 36.2388],
[ 18.2388, 27.2388, 36.2388]],
[[ 36.1347, 54.1347, 72.1347],
[ 36.1347, 54.1347, 72.1347],
[ 36.1347, 54.1347, 72.1347]],
[[ 53.7555, 80.7555, 107.7555],
[ 53.7555, 80.7555, 107.7555],
[ 53.7555, 80.7555, 107.7555]]]], grad_fn=<ConvolutionBackward0>)
# 发现有一点偏差,这是由于conv.bias.data引起
print(conv.bias.data)
>>> tensor([ 0.2388, 0.1347, -0.2445])
import torch
import torch.nn as nn
class DepthwiseSeparableConvModule(nn.Module):
def __init__(self, input_channels, output_channels):
super().__init__()
self.layer1 = nn.Conv2d(input_channels,
input_channels,
kernel_size=3,
padding=0,
stride=1,
dilation=1,
groups=input_channels,
bias=False)
self.layer = nn.Conv2d(input_channels,
output_channels,
kernel_size=1,
padding=0,
stride=1,
dilation=1,
groups=1,
bias=False)
def forward(self, x):
return self.layer2(self.layer1(x))
def autopad(k, p=None, d=1): # kernel, padding, dilation
if d > 1:
k = d * (k - 1) + 1 if isinstance(k, int) else [d * (x - 1) + 1 for x in k] # actual kernel-size
if p is None:
p = k // 2 if isinstance(k, int) else [x // 2 for x in k] # auto-pad
return p
autopad使用前提是默认kernel为奇数、stride = 1
空洞卷积的操作是在原本的卷积核相邻的两个元素之间插入0值,插入数量=dilation-1
(input_size - k + 2p)/s +1