0


在网络中添加特征金字塔,和自注意力机制

目录

原网络结构

某"D网络"是用来进行睡眠微事件检测的深度学习模型。但是我发现该网络的性能并非十分完善;正如论文中所述的那样,在SSC、WSC睡眠数据集上对于纺锤波、K复合波等睡眠微事件的检测性能方面(包括precision、recall、F1-score)有待提高。
为此鄙人不才,希望能够改进该网络的结构,从而提高模型对睡眠微事件检测的性能。
下面是对该网络模型的简单描述。

1.空间滤波

空间滤波是由一个简单的二维卷积和转置操作组成的,这个做法通过使用卷积来对输入的信号进行线性的空间滤波操作,从而增加输入信号的信噪比。(但是我发现,在源码中真的只是用一个简单的卷积操作 ┭┮﹏┭┮)
真的很简单的卷积结构!!!

            nn.Conv2d(
                in_channels=1,
                out_channels=self.number_of_channels,
                kernel_size=(self.number_of_channels,1),
                stride=1,
                padding=0)

2.特征提取

这个特征提取模块,也是我改进非常大的地方,因为我发现在作者提供的网络源代码中,只是用k个简单的卷积block组成(我想说仅仅通过卷积层、batchnorm、relu和maxpool真的能有好的性能么 ,ԾㅂԾ,)
这是该模块的大致结构,可以看见由k个包含二维卷积层的块组成。

nn.Sequential(
                    OrderedDict([("conv_{}".format(k), nn.Conv2d(
                            in_channels=4*(2**(k -1))if k >1else1,
                            out_channels=4*(2** k),
                            kernel_size=(1,3),
                            padding=(0,1),
                            stride=1)),# ("cbam_{}".format(k),cbam(in_channel=4 * (2 ** k))),("batchnorm_{}".format(k), nn.BatchNorm2d(4*(2** k))),("relu_{}".format(k), nn.ReLU()),("max_pooling_{}".format(k), nn.MaxPool2d(kernel_size=(1,2),stride=(1,2))),]))for k inrange(1, self.k_max-1)

3.分类和定位

分类和定位模块也是通过卷积层实现的。【这里就不过多描述了 O(∩_∩)O】

改变特征提取模块中网络结构

这里只是简单的给网路进行改进,结合Yolov5当中FPN特征金字塔,并添加相应的CBAM注意力机制,希望能够使得网络的性能增强些。(目前新增结构正在训练验证中…)

1.使用ResNet-50网络加入FPN提取多尺度特征

特征金字塔设计的思路是因为,对于图像特征来说,底层具有较强的定位特征,而顶层具有较强的语义特征,那么就需要结合多尺度的特征来将高维和低维的特征进行融合。
在这里插入图片描述
从上图FPN的结构中可以很好的进行观察,随着左半部分网络的加深,会使得语义信息更加得丰富。同时通过上采样的方法,不断放大特征图,能够使得低层特征也有丰富的语义信息。

在这里插入图片描述
在上述结构当中,是将上采样的结果和自底向上生成的特征图进行融合。从左侧过来的特征图,需要先通过1x1的卷积进行通道的改变;然后和自顶向下而来的特征图进行add,之后还需要经过一个3x3的卷积(这里通过3x3的卷积是消除上采样产生的混叠效应,因为上采样和原图叠加后会造成特征的不连续,在原来特征图上失真,在灰度变化的地方可能出现明显的锯齿状

在这,我是在ResNet-50的网络中添加FPN(FPN结构的部分代码):

self.layer1 = nn.Sequential(*layers[:5])
        self.layer2 = nn.Sequential(*layers[5])
        self.layer3 = nn.Sequential(*layers[6])
        self.layer4 = nn.Sequential(*layers[7])# 使用1x1卷积进行侧向连接
        self.lateral5 = nn.Conv2d(in_channels=2048,out_channels=256,kernel_size=1)
        self.lateral4 = nn.Conv2d(in_channels=1024, out_channels=256, kernel_size=1)
        self.lateral3 = nn.Conv2d(in_channels=512, out_channels=256, kernel_size=1)
        self.lateral2 = nn.Conv2d(in_channels=256, out_channels=256, kernel_size=1)# 进行上采样
        self.upsample2 = nn.ConvTranspose2d(in_channels=256, out_channels=256, kernel_size=4, stride=2, padding=1)
        self.upsample3 = nn.ConvTranspose2d(in_channels=256, out_channels=256, kernel_size=4, stride=2, padding=1)
        self.upsample4 = nn.ConvTranspose2d(in_channels=256,out_channels=256, kernel_size=4, stride=2, padding=1)# 使用3x3的卷积,为了消除上采样产生的混叠效应
        self.smooth2 = nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1)
        self.smooth3 = nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1)
        self.smooth4 = nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1)

然后将该模块加入到对应的网络当中。(ps:在这之前,需要将在该模块之前通过一个1x1的卷积层,用来改变通道数,从而能够符合该模块的输入通道。)

p2,p3,p4,p5 = self.fpn(self.conv1(x))

最终得到的p2,p3,p4,p5即为经过FPN后得到的多尺度特征图,接下来可以进行后续操作。

2.增加CBAM自注意力机制

在网络中添加注意力机制,可以提升网络的检测性能,在改进的网络中,我添加的是CBAM注意力机制。
CBAM注意力机制有两个模块,包括通道注意力机制和空间注意力机制。通过在通道和空间两个维度的分析,实现从通道到空间的注意力结构。
1.通道注意力机制
在这里插入图片描述
以上图能够很好的将通道注意力机制的结构展现。通道注意力机制先将特征图进行全局最大池化和平均池化,从而获得两张不同维度的特征图(进行相应的转化:[b,c,h,w]==>[b,c,1,1],可以看到后面两个维度都变成1,可以看成在通道维的操作);然后通过一个公用的多层感知机网络,在这里需要使用1x1的卷积来改变通道数;将两个特征图在通道维度进行堆叠,最后通过激活函数进行权重归一化。
在这里展示通道注意力机制的部分代码:

classChannelAttentionModule(nn.Module):def__init__(self, channel, ratio=4):super(ChannelAttentionModule, self).__init__()# 全局平均池化
        self.avg_pool = nn.AdaptiveAvgPool2d(1)# 全局最大池化
        self.max_pool = nn.AdaptiveMaxPool2d(1)# 公用的多层感知机网络
        self.shared_MLP = nn.Sequential(# 使用1x1卷积作为全连接层
            nn.Conv2d(channel, channel // ratio,1, bias=False),
            nn.ReLU(),
            nn.Conv2d(channel // ratio, channel,1, bias=False))
        self.sigmoid = nn.Sigmoid()defforward(self, x):
        avgout = self.shared_MLP(self.avg_pool(x))
        maxout = self.shared_MLP(self.max_pool(x))# 将两张图在通道维度进行堆叠return self.sigmoid(avgout + maxout)

2.空间注意力机制
在这里插入图片描述
在这里,是要对之前通道注意力机制输出的特征图进行空间域方向的处理,可以看成将通道维度视为1,然后观察其他维。
首先需要对特征图进行最大池化和平均池化操作;然后将这两个特征图在通道维度进行concat;使用7x7或3x3(在这里我用的是7x7)的卷积融合通道信息;再经过激活函数对空间权重归一化。
空间注意力机制的代码如下所示:

# 空间注意力机制classSpatialAttentionModule(nn.Module):def__init__(self):super(SpatialAttentionModule, self).__init__()
        self.conv2d = nn.Conv2d(in_channels=2, out_channels=1, kernel_size=7, stride=1, padding=3)
        self.sigmoid = nn.Sigmoid()defforward(self, x):# 平均池化
        avgout = torch.mean(x, dim=1, keepdim=True)# 最大池化
        maxout, _ = torch.max(x, dim=1, keepdim=True)# 将两张特征图在通道维度进行concat
        out = torch.cat([avgout, maxout], dim=1)
        out = self.sigmoid(self.conv2d(out))return out

ps:注意,以上需要将特征图和权重相乘,我都将此操作放到最后构造CBAM的forward()函数当中了 O(∩_∩)O

接下来就是将CBAM模块加入到改进后的网络中了,在这里我在网络最后的卷积后添加了CBAM模块,在这里为了保持原有网络结构的某些特征,我保留了原来DOSED网络中的两个卷积块,在这之后添加了CBAM。


本文转载自: https://blog.csdn.net/weixin_56068397/article/details/129835892
版权归原作者 CH339 所有, 如有侵权,请联系我们删除。

“在网络中添加特征金字塔,和自注意力机制”的评论:

还没有评论