Yolov8添加注意力机制

文章介绍了如何在Ultralytics的YOLOv8框架中集成MSHA注意力机制,包括从GitHub下载代码、添加注意力模块至任务和模型配置,以及如何通过修改train.py进行训练。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、下载代码

点击下方链接到github下载

GitHub - ultralytics/ultralytics: NEW - YOLOv8 🚀 in PyTorch > ONNX > OpenVINO > CoreML > TFLiteNEW - YOLOv8 🚀 in PyTorch > ONNX > OpenVINO > CoreML > TFLite - GitHub - ultralytics/ultralytics: NEW - YOLOv8 🚀 in PyTorch > ONNX > OpenVINO > CoreML > TFLiteicon-default.png?t=N7T8https://github.com/ultralytics/ultralyticsgithub有时会打不开,可以到国内镜像Gitee下载,链接如下

ultralytics: YOLOv8 🚀 Ultralytics 同步更新官方最新版 YOLOv8 (gitee.com)icon-default.png?t=N7T8https://gitee.com/monkeycc/ultralytics本文下载的代码版本为8.0.154,不同版本的代码结构可能会不同

二、注意力机制代码

本文使用MSHA注意力机制,代码如下

class MHSA(nn.Module):
    def __init__(self, n_dims, width=14, height=14, heads=4, pos_emb=False):
        super(MHSA, self).__init__()

        self.heads = heads
        self.query = nn.Conv2d(n_dims, n_dims, kernel_size=1)
        self.key = nn.Conv2d(n_dims, n_dims, kernel_size=1)
        self.value = nn.Conv2d(n_dims, n_dims, kernel_size=1)
        self.pos = pos_emb
        if self.pos:
            self.rel_h_weight = nn.Parameter(torch.randn([1, heads, (n_dims) // heads, 1, int(height)]),
                                             requires_grad=True)
            self.rel_w_weight = nn.Parameter(torch.randn([1, heads, (n_dims) // heads, int(width), 1]),
                                             requires_grad=True)
        self.softmax = nn.Softmax(dim=-1)

    def forward(self, x):
        n_batch, C, width, height = x.size()
        q = self.query(x).view(n_batch, self.heads, C // self.heads, -1)
        k = self.key(x).view(n_batch, self.heads, C // self.heads, -1)
        v = self.value(x).view(n_batch, self.heads, C // self.heads, -1)
        content_content = torch.matmul(q.permute(0, 1, 3, 2), k)  # 1,C,h*w,h*w
        c1, c2, c3, c4 = content_content.size()
        if self.pos:
            content_position = (self.rel_h_weight + self.rel_w_weight).view(1, self.heads, C // self.heads, -1).permute(
                0, 1, 3, 2)  # 1,4,1024,64

            content_position = torch.matmul(content_position, q)  # ([1, 4, 1024, 256])
            content_position = content_position if (
                    content_content.shape == content_position.shape) else content_position[:, :, :c3, ]
            assert (content_content.shape == content_position.shape)
            energy = content_content + content_position
        else:
            energy = content_content
        attention = self.softmax(energy)
        out = torch.matmul(v, attention.permute(0, 1, 3, 2))  # 1,4,256,64
        out = out.view(n_batch, C, width, height)
        return out

三、添加进Yolov8

1.在Yolov8的ultralytics/nn这个路径下创建文件,建议与注意力机制的模块同名。

 2.在task.py中添加代码

task.py还是在上述的路径下。打开,找到parse_model(d, ch, verbose=True)函数,做如下添加。

 3.创建新的yaml文件

在ultralytics/cfg/models/v8这个路径下创建新的yaml文件,yolov8n_att.yaml文件

将yolov8.yaml文件的内容复制到yolov8n_att.yaml文件中,防止错误。

在要添加注意力模块的层下方添加,本文是对SPPF层做注意力机制,所以就在SPPF层下方。

 修改head的内容

就是修改原来函数中层数发生变化的地方。

至此,修改完成。 

四、训练

yolov8训练分为可以分为两种,命令行与代码。这里推荐的是通过修改train.py代码来实现。

在主文件夹下找到train.py文件,如下图。

一般来说,添加注意力机制之后,只需要修改yaml与data两个参数,如图中红线画住的区域。这里解释一下,yaml参数的default后面的路径指的是你要训练的模型的结构文件,这本文中就是修改为yolov8n_att.yaml文件的路径;data参数default路径是你要训练的数据的data.yaml文件的路径,修改训练数据时修改它。还有其他参数可以去ultralytics官网查看。

在本文中,在不修改训练数据的情况下,修改yaml参数后的路径为yolov8_att.yaml路径,然后运行train.py即可开始训练。

### 在 YOLOv8 中集成 SE 和 CA 注意力机制 #### 实现方法概述 为了在 YOLOv8 中同时集成 Squeeze-and-Excitation (SE)[^3] 和 Coordinate Attention (CA)[^1] 两种注意力机制,可以通过修改 YOLOv8 的网络架构来完成。以下是具体的实现过程: --- #### 修改步骤 ##### 1. 添加 SE 注意力机制到卷积层 SE 注意力机制主要作用于通道维度上,通过对不同通道的重要性进行重新加权,从而增强有用特征并抑制无用特征。 - **代码实现** 需要在 `conv.py` 文件中定义 SE 模块,并将其嵌入到现有的卷积操作中。 ```python import torch.nn as nn import torch class SELayer(nn.Module): def __init__(self, channel, reduction=16): super(SELayer, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.fc = nn.Sequential( nn.Linear(channel, channel // reduction, bias=False), nn.ReLU(inplace=True), nn.Linear(channel // reduction, channel, bias=False), nn.Sigmoid() ) def forward(self, x): b, c, _, _ = x.size() y = self.avg_pool(x).view(b, c) y = self.fc(y).view(b, c, 1, 1) return x * y.expand_as(x) ``` - **应用位置** 将上述 SE 层插入到 YOLOv8 的骨干网络(Backbone)或颈部网络(Neck)中的某些关键卷积层之后。 --- ##### 2. 添加 CA 注意力机制到卷积层 CA 注意力机制则关注空间维度上的信息分布,通过捕获坐标轴方向的相关性来提高特征表达能力。 - **代码实现** 定义 CA 模块,并同样嵌入到现有卷积操作中。 ```python 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, oup, 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, oup, kernel_size=1, stride=1, padding=0) self.conv_w = nn.Conv2d(mip, oup, kernel_size=1, stride=1, padding=0) def forward(self, x): identity = x n, c, h, w = x.size() x_h = self.pool_h(x) x_w = self.pool_w(x).permute(0, 1, 3, 2) y = torch.cat([x_h, x_w], dim=2) 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 ``` - **应用位置** 类似于 SE,将 CA 模块应用于 Backbone 或 Neck 的特定阶段。 --- ##### 3. 调整配置文件 (`yolov8.yaml`) 为了让模型加载自定义的注意力模块,需更新 YAML 配置文件以反映新的网络结构变化。 - 增加 SE 和 CA 到对应的层定义中。 - 示例片段如下: ```yaml backbone: # Example of adding attention modules to backbone layers [[-1, Conv, [64, 3]], [-1, SELayer, []], [-1, CoordAtt, []]] neck: # Similar adjustments can be made here for neck layers [[-1, C3, [128, 3]], [-1, SELayer, []], [-1, CoordAtt, []]] ``` --- ##### 4. 更新训练脚本 最后一步是在主程序中导入新定义的类,并确保它们被正确初始化和调用。 ```python from conv import SELayer, CoordAtt def build_model(): model = YOLOv8() # Assume this is the base class definition # Add custom layers where needed... return model ``` --- ### 性能评估与优化建议 结合 SE 和 CA 可显著改善模型对复杂场景的理解能力和鲁棒性。然而需要注意的是,额外加入这些组件可能会稍微增加计算开销;因此应仔细调整超参数(如缩减因子),平衡精度增益与运行时间之间的关系。 --- ####
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值