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

原文: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

版权声明:本文为CSDN博主「MiracleHong」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40671801/article/details/118380538

MiracleHong

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

yolov5训练数据集划分

yolov5训练数据集划分 按照默认8:1:1划分训练集,测试集,验证集。 txt文件出现在imageset文件夹。 import os import randomtrainval_pe

深度学习之目标检测YOLOv5

一.简介 YOLOV4出现之后不久,YOLOv5横空出世。YOLOv5在YOLOv4算法的基础上做了进一步的改进,检测性能得到进一步的提升。虽然YOLOv5算法并没有与YOLOv4算法进行性能比较与分析&#xff0