参考论文:《Pyramidal Convolution: Rethinking Convolutional Neural Networks for Visual Recognition》
论文链接: http://arxiv.org/abs/2006.11538
1. 金字塔卷积形式:
核心是使用多个大小不同的卷积对input feature maps进行卷积操作
标准的卷积操作中,每个卷积核的通道和input feature的通道一致。
PyConv中,随着卷积核size增大,通道大小减少,此时需要使用Grouped Convolution。Group分组的对象是input feature的通道,每n个为一组,
torch.nn.Conv2d(in_channels: int,
out_channels: int,
kernel_size: Union[T, Tuple[T, T]],
stride: Union[T, Tuple[T, T]] = 1,
padding: Union[T, Tuple[T, T]] = 0,
dilation: Union[T, Tuple[T, T]] = 1,
groups: int = 1,
bias: bool = True,
padding_mode: str = 'zeros')
这是pytorch的Conv2d函数的参数列表,其中groups就代表grouped convolution的参数,将输入channel和输出channel划分为groups段(因此要求channel数量和groups具有一定的整除关系)。每一段内部单独进行卷积操作,卷积核大小为函数传入的kernel_size。由此,通过grouped convolution便可以实现使用不同大小卷积核进行卷积的操作
class PyConv4(nn.Module):
def __init__(self, inplans, planes, pyconv_kernels=[3, 5, 7, 9], stride=1, pyconv_groups=[1, 4, 8, 16]):
super(PyConv4, self).__init__()
self.conv2_1 = conv(inplans, planes//4, kernel_size=pyconv_kernels[0], padding=pyconv_kernels[0]//2,
stride=stride, groups=pyconv_groups[0])
self.conv2_2 = conv(inplans, planes//4, kernel_size=pyconv_kernels[1], padding=pyconv_kernels[1]//2,
stride=stride, groups=pyconv_groups[1])
self.conv2_3 = conv(inplans, planes//4, kernel_size=pyconv_kernels[2], padding=pyconv_kernels[2]//2,
stride=stride, groups=pyconv_groups[2])
self.conv2_4 = conv(inplans, planes//4, kernel_size=pyconv_kernels[3], padding=pyconv_kernels[3]//2,
stride=stride, groups=pyconv_groups[3])
def forward(self, x):
return torch.cat((self.conv2_1(x), self.conv2_2(x), self.conv2_3(x), self.conv2_4(x)), dim=1)
2. Local PyConv and Global PyConv
1x1的identity层主要是将channel统一至512。在Global Pyconv Block中,Adaptive Avg Poll目的是将input feature的size下降到9x9,恰好是最大的卷积核的大小,从而能够获取到全局信息,故而称之为“全局”。同时需要将局部和全局信息进行合并,方法类似于上面PyConv Block的实现形式,利用torch.cat连接结果。
3. 疑问1:卷积核大小不一致,最后output feature的size不会不一致吗?
具体可见Convolution Arthimetic.md
o
s
i
z
e
=
f
l
o
o
r
(
i
n
s
i
z
e
+
2
p
−
k
s
t
r
i
d
e
)
+
1
o_{size} = floor(\frac{in_{size}+2p-k}{stride})+1
osize=floor(strideinsize+2p−k)+1
同时应当注意到,源码中,padding的大小设置为了k//2,stride采用同样大小,如此一来,只要
2
∗
(
k
/
/
2
)
−
k
2*(k//2)-k
2∗(k//2)−k相同,输出size就相同,又可以看到kernel的size都是奇数,该式结果也必定为-1.
而这,也叫做:Half(same) Padding