【yolov8】|小目标优化|:增加CA机制 运行成功

🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀

你好,我是@努力的小巴掌

之前用baseline跑了yolov8。

为了提升性能,我们需要对yolov8进行优化。

本次的优化,我们从增加注意力机制开始。

🚀CA:注意力机制

增强yolov8对于小目标的识别,加入CA机制。

论文是这样说的:

CA(Hou et al., 2021)机制:“该机制可以同时捕获远处的空间和通道信息,显着提高模型针对复杂情况准确定位和识别目标物体的能力”

“CA机制纳入YOLOv8的主干网络中,并与C2f模块相结合,将C2f模块重新设计为C2f_CA,可用于替换网络中原有的C2f模块。”

🚀优化步骤

一、增加CA注意力机制模块到conv.py里面

CA机制的代码

#CA注意力机制
class h_sigmoid(nn.Module):
    def __init__(self, inplace=True):
        super(h_sigmoid, self).__init__()
        self.relu = nn.ReLU6(inplace=inplace)

    def forward(self, x):
        return self.relu(x + 3) / 6
class h_swish(nn.Module):
    def __init__(self, inplace=True):
        super(h_swish, self).__init__()
        self.sigmoid = h_sigmoid(inplace=inplace)
    def forward(self, x):
        return x * self.sigmoid(x)

class CoordAtt(nn.Module):
    def __init__(self, inp, reduction=32):
        super(CoordAtt, self).__init__()
        self.pool_h = nn.AdaptiveAvgPool2d((None, 1))
        self.pool_w = nn.AdaptiveAvgPool2d((1, None))
        mip = max(8, inp // reduction)
        self.conv1 = nn.Conv2d(inp, mip, kernel_size=1, stride=1, padding=0)
        self.bn1 = nn.BatchNorm2d(mip)
        self.act = h_swish()
        self.conv_h = nn.Conv2d(mip, inp, kernel_size=1, stride=1, padding=0)
        self.conv_w = nn.Conv2d(mip, inp, kernel_size=1, stride=1, padding=0)
    def forward(self, x):
        identity = x
        n, c, h, w = x.size()
        #c*1*W
        x_h = self.pool_h(x)
        #c*H*1
        #C*1*h
        x_w = self.pool_w(x).permute(0, 1, 3, 2)
        y = torch.cat([x_h, x_w], dim=2)
        #C*1*(h+w)
        y = self.conv1(y)
        y = self.bn1(y)
        y = self.act(y)
        x_h, x_w = torch.split(y, [h, w], dim=2)
        x_w = x_w.permute(0, 1, 3, 2)
        a_h = self.conv_h(x_h).sigmoid()
        a_w = self.conv_w(x_w).sigmoid()
        out = identity * a_w * a_h
        return out

这里有几个点要注意,网上的有的代码是不对的,这份是对的,可以跑起来。

class CoordAtt(nn.Module):
    def __init__(self, inp, reduction=32):  # 这里是输入通道的inp
        super(CoordAtt, self).__init__()
        self.pool_h = nn.AdaptiveAvgPool2d((None, 1))
        self.pool_w = nn.AdaptiveAvgPool2d((1, None))
        mip = max(8, inp // reduction)
        self.conv1 = nn.Conv2d(inp, mip, kernel_size=1, stride=1, padding=0)
        self.bn1 = nn.BatchNorm2d(mip)
        self.act = h_swish()
        self.conv_h = nn.Conv2d(mip, inp, kernel_size=1, stride=1, padding=0)  #这里也是输入通道
        self.conv_w = nn.Conv2d(mip, inp, kernel_size=1, stride=1, padding=0)

在conv.py中增加这个CA的类:

直接在conv.py下拉到最下面,添加。

conv.py在ultralytics-main/ultralytics/nn/modules/conv.py

二、并且在conv.py的all中添加CoorAtt:

三、在__init__.py中的all进行引用:

ultralytics-main/ultralytics/nn/modules/__init__.py

四、在tasks.py中导入

ultralytics-main/ultralytics/nn/tasks.py

打开nn  =》 tasks.py

1、首先新增导入:import

nn.module中导入

2、然后在parse_model增加:

elif m in {CoordAtt}:
            args=[ch[f],*args]

直接crtl+F 搜索,找到定义算子层那里:

五、修改配置文件

先复制一份yolov8-seg.yaml,然后重命名为yolov8CA-seg.yaml

注意,之前在做语义分割的时候,用的是yolov8n-seg.yaml ,除了最后的任务是

- [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Segment(P3, P4, P5)

其实,n的意思是,在yaml中定义了一个scale,是模型的缩放比例,如果是model = yolov8n-seg.yaml,那么就会调用yolov8-seg.yaml的带有“n”的缩放的yolov8-seg.yaml

要使用哪个,就把其他的注释掉。

修改yolov8CA-seg.yaml

好了,这里有个问题,我们看到,yolov8-seg.yaml一共有26层,我们应该把注意力机制加到什么地方?

以VGG16神经网络来看,随着网络的深入增加,特征张量的w和h在不断缩小,通道数不断增加。

越往后的图片,像素越小,分辨率越低,通道数越来越丰富;随着卷积的不断加深,特征图上的空间信息越来越少,而通道的信息会越来越丰富。

如果把空间注意力机制放在前面,通道注意力机制放在后面,往往会有比较好的效果。

加在head中,关于加到哪里,是实验经验得知的。

优化如下:

注意inp这个输入通道数是需要写的,输入通道数就是上一层的输出

具体可对照yolov8网络图看

然后我做的是小目标的分割,所以,把s保留,其他的注释掉。

完整的yaml配置文件是:

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8-seg instance segmentation model. For Usage examples see https://docs.ultralytics.com/tasks/segment

# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n-seg.yaml' will call yolov8-seg.yaml with scale 'n'
  # [depth, width, max_channels]
  #n: [0.33, 0.25, 1024]
  s: [0.33, 0.50, 1024]
 # m: [0.67, 0.75, 768]
  #l: [1.00, 1.00, 512]
  #x: [1.00, 1.25, 512]

# YOLOv8.0n backbone
backbone:
  # [from, repeats, module, args]
  - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
  - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
  - [-1, 3, C2f, [128, True]]
  - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
  - [-1, 6, C2f, [256, True]]
  - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16
  - [-1, 6, C2f, [512, True]]
  - [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32
  - [-1, 3, C2f, [1024, True]]
  - [-1, 1, SPPF, [1024, 5]] # 9

# YOLOv8.0n head
head:
  - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  - [[-1, 6], 1, Concat, [1]] # cat backbone P4
  - [-1, 3, C2f, [512]] # 12

  - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  - [[-1, 4], 1, Concat, [1]] # cat backbone P3
  - [-1, 3, C2f, [256]] # 15 (P3/8-small)
  - [-1, 1, CoordAtt,[256]]

  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 12], 1, Concat, [1]]# cat head P4
  - [-1, 3, C2f, [512]] # 18 (P4/16-medium)
  - [-1, 1, CoordAtt,[512]]

  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 9], 1, Concat, [1]]# cat head P5
  - [-1, 3, C2f, [1024]] # 21 (P5/32-large)
  - [-1, 1, CoordAtt,[1024]]

  - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Segment(P3, P4, P5)

到这里就优化好了

六、测试有没有改成功

接下来,试下能不能运行成功。

新建一个脚本用来训练:mytrain-segCA.py

import multiprocessing

if __name__ == '__main__':
    multiprocessing.freeze_support()
    from ultralytics import YOLO

    # Load a model
    #model = YOLO("yolov8n-seg.yaml")  # build a new model from YAML
    model = YOLO('E:\\yolov8\\ultralytics-main\\ultralytics\\cfg\\models\\v8\\yolov8n-seg-CA.yaml')
    #model = YOLO("yolov8n-seg.yaml").load("yolov8n.pt")  # build from YAML and transfer weights

    # Train the model
    results = model.train(**{'data': 'E:\\yolov8\\ultralytics-main\\mydata.yaml',
                             'epochs':1})

首先,是定义了训练的模型,是我们刚刚优化的那个配置文件,第二个就是,定义了data在哪里。

从网络结构这,看到CoordAtt 机制加进去了。

所以,就修改成功了。

而且她提示,WARNING ⚠️ no model scale passed. Assuming scale='s'.

那就是用s了。

参考资料:

YOLOv5改进系列(3)——添加CA注意力机制-阿里云开发者社区

YOLOv5 v6.1添加SE,CA,CBAM,ECA注意力机制教学,即插即用_哔哩哔哩_bilibili

  • 31
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLOv8 是一种被广泛应用于目标检测领域的神经网络模型,尤其擅长实时检测多个不同类别的目标。为了进一步提高其检测性能,研究人员引入了CA(Channel Attention)注意力机制,这是一种能够有效提取输入特征图中重要通道信息的方法。 在 YOLOv8 中添加 CA 注意力机制的小怪兽是为了增强模型在特征提取阶段的能力。该小怪兽通过观察输入的特征图,并将其映射为附加的特征图。对于每个位置,小怪兽会计算输入特征图通道维度上的最大值并输出到附加的特征图。这个过程实际上是在提取输入特征图的重要通道信息,使得模型可以更好地关注重要的特征。 在 YOLOv8 中使用 CA 注意力机制的好处是提高了目标检测的精度和召回率。通过增强重要通道的表示能力,模型可以更好地学习和理解不同类别目标的特征,从而提高检测的准确性。CA 注意力机制还帮助模型抑制了输入特征图中的噪声和无用信息,从而进一步提升了目标检测性能。 然而,虽然 CA 注意力机制YOLOv8 中表现出优越的性能,但它也带来了一定的计算复杂度。这是因为在通道维度上进行注意力计算和映射的操作会增加模型的参数和计算量。因此,在实际应用中,我们需要权衡精度和计算效率,找到适合特定场景的平衡点。 总之,YOLOv8 添加 CA 注意力机制的小怪兽是一种有效的目标检测技术,通过强调输入特征图的重要通道信息,提高了模型的检测精度和召回率。然而,其在计算复杂度方面也需要注意,同时权衡模型性能和计算效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值