YOLOv8添加注意力机制(ShuffleAttention为例)

1 前言

注意力机制是非常重要的改进手段,yolov8是目标检测目前最先进的技术,本文将详细展示如何在yolov8中添加注意力机制。
最新版代码见此贴【新版yolov8添加注意力机制(以NAMAttention注意力机制为例)】

2. 如何改进

2.1 注意力机制代码

本文以ShuffleAttention为例:
在这里插入图片描述

在ultralytics\文件夹下创建ShuffleAttention.py,以下是代码。

import numpy as np
import torch
from torch import nn
from torch.nn import init
from torch.nn.parameter import Parameter


class ShuffleAttention(nn.Module):

    def __init__(self, channel=512, reduction=16, G=8):
        super().__init__()
        self.G = G
        self.channel = channel
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.gn = nn.GroupNorm(channel // (2 * G), channel // (2 * G))
        self.cweight = Parameter(torch.zeros(1, channel // (2 * G), 1, 1))
        self.cbias = Parameter(torch.ones(1, channel // (2 * G), 1, 1))
        self.sweight = Parameter(torch.zeros(1, channel // (2 * G), 1, 1))
        self.sbias = Parameter(torch.ones(1, channel // (2 * G), 1, 1))
        self.sigmoid = nn.Sigmoid()

    def init_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                init.kaiming_normal_(m.weight, mode='fan_out')
                if m.bias is not None:
                    init.constant_(m.bias, 0)
            elif isinstance(m, nn.BatchNorm2d):
                init.constant_(m.weight, 1)
                init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                init.normal_(m.weight, std=0.001)
                if m.bias is not None:
                    init.constant_(m.bias, 0)

    @staticmethod
    def channel_shuffle(x, groups):
        b, c, h, w = x.shape
        x = x.reshape(b, groups, -1, h, w)
        x = x.permute(0, 2, 1, 3, 4)

        # flatten
        x = x.reshape(b, -1, h, w)

        return x

    def forward(self, x):
        b, c, h, w = x.size()
        # group into subfeatures
        x = x.view(b * self.G, -1, h, w)  # bs*G,c//G,h,w

        # channel_split
        x_0, x_1 = x.chunk(2, dim=1)  # bs*G,c//(2*G),h,w

        # channel attention
        x_channel = self.avg_pool(x_0)  # bs*G,c//(2*G),1,1
        x_channel = self.cweight * x_channel + self.cbias  # bs*G,c//(2*G),1,1
        x_channel = x_0 * self.sigmoid(x_channel)

        # spatial attention
        x_spatial = self.gn(x_1)  # bs*G,c//(2*G),h,w
        x_spatial = self.sweight * x_spatial + self.sbias  # bs*G,c//(2*G),h,w
        x_spatial = x_1 * self.sigmoid(x_spatial)  # bs*G,c//(2*G),h,w

        # concatenate along channel axis
        out = torch.cat([x_channel, x_spatial], dim=1)  # bs*G,c//G,h,w
        out = out.contiguous().view(b, -1, h, w)

        # channel shuffle
        out = self.channel_shuffle(out, 2)
        return out


2.2 修改task.py

打开task.py
在这里插入图片描述
导入刚刚添加的包:
在这里插入图片描述
ctrl+f找到def parse_model(d, ch, verbose=True): 方法。如下图

在这里插入图片描述
如上图,找到if m in xxx
在这里插入图片描述
在下方elif里面添加自己的注意力机制,如果只有一个注意力机制,则如下代码,如果有多个,像上方截图。

elif m in {ShuffleAttention}: #在此处添加自己的注意力机制,命名是刚刚的类名
            args = [ch[f], *args] 

2.3 修改模型

找到模型的位置ultralytics/models/v8/yolov8n.yaml,将此模型拷贝一次,在模型中添加自己的注意力机制,如下代码所示。

如果用的yolov8s,则修改yolov8s.yaml

 # Ultralytics YOLO 🚀, GPL-3.0 license

# Parameters
nc: 1  # number of classes
depth_multiple: 0.33  # scales module repeats
width_multiple: 0.25  # scales convolution channels

# YOLOv8.0n backbone
backbone:
  # [from, repeats, module, args]
  - [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2            0
  - [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4            1
  - [-1, 3, C2f, [128, True]]                       # 2
  - [-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']] #10
  - [[-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, ShuffleAttention, [16, 8]] #16
  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 12], 1, Concat, [1]]  # cat head P4
  - [-1, 3, C2f, [512]]  # 19 (P4/16-medium)

  - [-1, 1, ShuffleAttention, [16, 8]] #20
  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 9], 1, Concat, [1]]  # cat head P5  22
  - [-1, 3, C2f, [1024]]  # 23 (P5/32-large)

  - [[15, 19, 23], 1, Detect, [nc]]  # Detect(P3, P4, P5)


在这里插入图片描述

3. 以下汇总了常见的注意力机制(修改与上述大同小异)

可以看此贴,目前收集的注意力机制,常见注意力机制代码实现,持续更新中…

### 如何在YOLOv8添加自定义模块或组件 #### 创建新的Python文件并定义模块 为了向YOLOv8框架中加入自定义模块,可以在`models`目录下创建一个新的`.py`文件,比如命名为`my_module.py`。在这个新文件里定义所需的模块逻辑,参照已有的模块(像`yolo.py`、`anchor.py`等)作为模板进行开发[^1]。 ```python # models/my_module.py import torch.nn as nn class MyCustomModule(nn.Module): def __init__(self, ...): # 定义初始化函数和其他必要的参数 super(MyCustomModule, self).__init__() ... def forward(self, x): ... return output ``` #### 更新配置文件以包含自定义结构 对于特定架构的修改,如基于AirNet改进YOLOv8,则需前往`ultralytics/cfg/models/v8/`路径下的相应子文件夹内新建一个YAML格式的配置文档,如`yolov8-airnet.yaml`用于描述网络层及其连接方式[^2]: ```yaml # ultralytics/cfg/models/v8/yolov8-airnet.yaml backbone: - [-1, 1, Conv, [64, 3, 2]] - [...] neck: - [...] head: - [...] ``` #### 调整训练脚本以便识别新增加的内容 为了让整个项目能够顺利调用到上述所作更改,在`train.py`当中应当补充有关于命令行选项解析的部分代码片段,从而允许终端用户通过指定`--model my_module`的形式来启动带有自定义功能的新模型版本;同时也要确保在此处正确设置了目标模型配置文件的位置给变量`model_cfg_path=yolov8_C2f_SCConv.yaml`这样的形式[^3]。 ```python if args.model == 'my_module': model_cfg_path = os.path.join('path/to/', 'yolov8_C2f_SCConv.yaml') else: model_cfg_path = default_model_config ``` 最后一步就是在实际执行训练过程的时候利用之前设定好的名称即可激活对应的扩展特性。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有趣的野鸭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值