加入金字塔分割注意力模块的目标检测 | 您所在的位置:网站首页 › 特征金字塔注意力 › 加入金字塔分割注意力模块的目标检测 |
原文:EPSANet: An Efficient Pyramid Split Attention Block on Convolutional Neural Network 代码链接:https://github.com/murufeng/EPSANet 前言:论文在CenterNet基础上增加通道注意力,所以基于CenterNet代码进行了修改,由于CenterNet有三种主干网络(hourglass、ResNet、 DLA),此文针对的是基于ResNet骨干网络的Centernet。(插入的代码部分基于Pytorch) 核心:基于CenterNet目标检测算法;引入通道注意力,并加入多尺度思想,提出金字塔分割注意力模块,PSA module; 论文的方法(默认已经对CenterNet有所了解):建立PSA模块,主要包含以下4个步骤 1,利用SPC模块提取通道特征图上的多尺度特征 很多文献将此处提取过程翻译为切分为四个部分,这是不恰当的。对照源码(如下代码部分)可以看到这并不是一个切分的操作,而是对该特征图重复四次卷积,每次提取得到通道数为 原有通道数 / 4 的特征图,之后经过ConCat操作叠加回来(简单的堆叠)。 class PSAModule(nn.Module): def __init__(self, inplans, planes, conv_kernels=[3, 5, 7, 9], stride=1, conv_groups=[1, 4, 8, 16]): super(PSAModule, self).__init__() self.conv_1 = conv(inplans, planes//4, kernel_size=conv_kernels[0], padding=conv_kernels[0]//2, stride=stride, groups=conv_groups[0]) self.conv_2 = conv(inplans, planes//4, kernel_size=conv_kernels[1], padding=conv_kernels[1]//2, stride=stride, groups=conv_groups[1]) self.conv_3 = conv(inplans, planes//4, kernel_size=conv_kernels[2], padding=conv_kernels[2]//2, stride=stride, groups=conv_groups[2]) self.conv_4 = conv(inplans, planes//4, kernel_size=conv_kernels[3], padding=conv_kernels[3]//2, stride=stride, groups=conv_groups[3]) self.se = SEWeightModule(planes // 4) self.split_channel = planes // 4 self.softmax = nn.Softmax(dim=1) def forward(self, x): batch_size = x.shape[0] x1 = self.conv_1(x) x2 = self.conv_2(x) x3 = self.conv_3(x) x4 = self.conv_4(x) feats = torch.cat((x1, x2, x3, x4), dim=1) feats = feats.view(batch_size, 4, self.split_channel, feats.shape[2], feats.shape[3]) x1_se = self.se(x1) x2_se = self.se(x2) x3_se = self.se(x3) x4_se = self.se(x4) x_se = torch.cat((x1_se, x2_se, x3_se, x4_se), dim=1) attention_vectors = x_se.view(batch_size, 4, self.split_channel, 1, 1) attention_vectors = self.softmax(attention_vectors) feats_weight = feats * attention_vectors for i in range(4): x_se_weight_fp = feats_weight[:, i, :, :] if i == 0: out = x_se_weight_fp else: out = torch.cat((x_se_weight_fp, out), 1) return out可以看到在forward中,对输入的x经过四次卷积得到x1,x2,x3,x4,卷积和的大小是分别指定的(源码为3,5,7,9),所以可以提取到不同尺度的特征图,并分别经过self.se操作(即SE注意力模块)。 真正的切分则存在于分组卷积中,正如原文所说,因为采用了不同的卷积核,所以导致参数量提高,所以使用分组卷积的方式,降低参数量。 2.提取不同尺度特征图的通道注意力 即通过SEWeight得到通道注意力向量,这点没什么好说的,具体可以参考注意力机制的相关文献,比较简单。 3.使用Softmax对输出的注意力向量重新标定,得到注意力权重 为什么使用softmax,以下是我的理解:如果看了SENet的应该知道,上一步注意力模块输出后的值是经过Sigmoid函数的输出,但我们需要的是通道间的权重,权重除了满足值为[0,1]还应当满足的条件就是所有权重相加的和为1,所以需要经过Softmax。 4.最后和单纯的SE模块相同,需要和源特征图想乘得到加权后的特征图。 梳理一下模块发生的流程:整个PSA模块发生在ResNet框架中的残差块。替换了ResNet中的3×3卷积操作即 参考:https://blog.csdn.net/weixin_47196664/article/details/117857949 |
CopyRight 2018-2019 实验室设备网 版权所有 |