加入金字塔分割注意力模块的目标检测 您所在的位置:网站首页 特征金字塔注意力 加入金字塔分割注意力模块的目标检测

加入金字塔分割注意力模块的目标检测

2024-07-07 13:36| 来源: 网络整理| 查看: 265

原文: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 实验室设备网 版权所有