YOLO26骨干网络中添加CBAM模块
引言:
CBAM(Convolutional Block Attention Module)是一种轻量级的注意力机制模块,用于增强卷积神经网络的特征提取能力。在YOLO(You Only Look Once)目标检测框架的骨干网络中,CBAM模块通过通道注意力和空间注意力的双重机制,显著提升了模型对重要特征的关注能力。
CBAM在YOLO中的应用优势
-
特征增强:CBAM模块通过动态调整通道和空间权重,使YOLO骨干网络更关注目标物体的关键特征,抑制背景噪声。
-
轻量化设计:CBAM的计算开销较小,适合嵌入YOLO的实时检测框架,几乎不影响推理速度。
-
性能提升:实验表明,添加CBAM模块的YOLO变体(如YOLOv5-CBAM)在COCO等数据集上mAP提升约1-2%
YOLO26主要功能
-
DFL 移除
分布式焦点损失(DFL)模块虽然有效,但常常使导出复杂化并限制了硬件兼容性。YOLO26 完全移除了 DFL,简化了推理过程,并拓宽了对边缘和低功耗设备的支持。 -
端到端无NMS推理
与依赖NMS作为独立后处理步骤的传统检测器不同,YOLO26是原生端到端的。预测结果直接生成,减少了延迟,并使集成到生产系统更快、更轻量、更可靠。 -
ProgLoss + STAL
改进的损失函数提高了检测精度,在小目标识别方面有显著改进,这是物联网、机器人、航空影像和其他边缘应用的关键要求。 -
MuSGD Optimizer
一种新型混合优化器,结合了SGD和Muon。灵感来自 Moonshot AI 的Kimi K2,MuSGD 将 LLM 训练中的先进优化方法引入计算机视觉,从而实现更稳定的训练和更快的收敛。 -
CPU推理速度提升高达43%
YOLO26专为边缘计算优化,提供显著更快的CPU推理,确保在没有GPU的设备上实现实时性能。
由于YOLO26n在轻量化和边缘部署优势明显,所以改变骨干架构会使性能降低,且在轻量化方面提升不大
一,准备
电脑要有conda环境,且部署ultralytics的YOLO26系列https://docs.ultralytics.com/zh/这是官方链接。
CBAM代码(CBAM.py)
import torch
import torch.nn as nn
import torch.nn.functional as F
class CBAM(nn.Module):
def __init__(self, in_channels, reduction_ratio=16, kernel_size=7):
super(CBAM, self).__init__()
#通道注意力模块
# 全局平均池化分支
self.channel_avg_pool = nn.AdaptiveAvgPool2d(1) # [batch, channels, 1, 1]
# 全局最大池化分支
self.channel_max_pool = nn.AdaptiveMaxPool2d(1) # [batch, channels, 1, 1]
# 共享MLP
self.channel_mlp = nn.Sequential(
nn.Conv2d(in_channels, in_channels // reduction_ratio, kernel_size=1, bias=False),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels // reduction_ratio, in_channels, kernel_size=1, bias=False)
)
# 空间注意力模块
self.spatial_conv = nn.Conv2d(
in_channels=2, # 输入为2个通道
out_channels=1, # 输出1个通道
kernel_size=kernel_size,
padding=kernel_size // 2, # 保持输出空间尺寸与输入一致
bias=False
)
self.spatial_sigmoid = nn.Sigmoid() # 将输出压缩到0~1之间,作为空间权重
def forward(self, x):
# 通道注意力计算
avg_pool = self.channel_avg_pool(x) # [B, C, 1, 1]
max_pool = self.channel_max_pool(x) # [B, C, 1, 1]
# MLP学习通道权重
avg_out = self.channel_mlp(avg_pool) # [B, C, 1, 1]
max_out = self.channel_mlp(max_pool) # [B, C, 1, 1]
# 相加后通过sigmoid得到通道注意力权重,在0-1之间
channel_att = F.sigmoid(avg_out + max_out) # [B, C, 1, 1]
# 特征图与通道权重逐通道相乘
x = x * channel_att # [B, C, H, W]
# 空间注意力计算
avg_pool_spatial = torch.mean(x, dim=1, keepdim=True) # [B, 1, H, W]
max_pool_spatial, _ = torch.max(x, dim=1, keepdim=True) # [B, 1, H, W]
# 拼接两个池化
spatial_input = torch.cat([avg_pool_spatial, max_pool_spatial], dim=1) # [B, 2, H, W]
# 通过卷积和sigmoid得到空间注意力权重
spatial_att = self.spatial_sigmoid(self.spatial_conv(spatial_input)) # [B, 1, H, W]
# 特征图与空间权重逐元素相乘
x = x * spatial_att # [B, C, H, W]
return x
二,将CBAM添加到骨干网络架构中
1,在初始化文件中注册CBAM
编辑 ultralytics/nn/modules/__init__.py,添加 CBAM 的导入和导出。

2,修改模型解析器以支持 CBAM
编辑 ultralytics/nn/tasks.py,找到 parse_model 函数,在模块映射字典中添加 CBAM

大约就在1600多行,vscode可以用Ctrl+F检索
3. 修改 YAML 配置文件
这里我直接在卷积下面加了三个CBAM,由于下面有SPPF,所以加下面没必要
找到YOLO26的yaml文件(cfg\models\26\yolo26.yaml)
# YOLO26n backbone with CBAM
backbone:
# [from, repeats, module, args]
- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
- [-1, 2, C3k2, [256, False, 0.25]] # 2
- [-1, 1, CBAM, [256]] # 3 <- 插入 CBAM (P3 特征)
- [-1, 1, Conv, [256, 3, 2]] # 4-P3/8
- [-1, 2, C3k2, [512, False, 0.25]] # 5
- [-1, 1, CBAM, [512]] # 6 <- 插入 CBAM (P4 特征)
- [-1, 1, Conv, [512, 3, 2]] # 7-P4/16
- [-1, 2, C3k2, [512, True]] # 8
- [-1, 1, CBAM, [512]] # 9 <- 插入 CBAM (P5 特征)
- [-1, 1, Conv, [1024, 3, 2]] # 10-P5/32
- [-1, 2, C3k2, [1024, True]] # 11
- [-1, 1, SPPF, [1024, 5, 3, True]] # 12
- [-1, 2, C2PSA, [1024]] # 13
更新 Head 部分的连接索引
我们插入了三层 CBAM,分别位于原索引 2、4、6 之后。因此 P3 特征的输出由原索引 4 变成了索引 6(CBAM 输出),P4 特征由原索引 6 变成了索引 9,P5 特征仍由 C2PSA(索引 13)提供。

图上那两个C3K2有连接别的部分接口,所以在head部分改变检索
# YOLO26n head
head:
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 9], 1, Concat, [1]] # cat backbone P4
- [-1, 2, C3k2, [512, True]] # 13
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 6], 1, Concat, [1]] # cat backbone P3
- [-1, 2, C3k2, [256, True]] # 16 (P3/8-small)
- [-1, 1, Conv, [256, 3, 2]]
- [[-1, 16], 1, Concat, [1]] # cat head P4
- [-1, 2, C3k2, [512, True]] # 19 (P4/16-medium)
- [-1, 1, Conv, [512, 3, 2]]
- [[-1, 13], 1, Concat, [1]] # cat head P5
- [-1, 1, C3k2, [1024, True, 0.5, True]] # 22 (P5/32-large)
- [[19, 22, 25], 1, Detect, [nc]] # Detect(P3, P4, P5)
解释:
-
P3 特征:由原索引 4 变为现索引 6(CBAM 输出层,精炼后的 P3)
-
P4 特征:由原索引 6 变为现索引 9(CBAM 输出层,精炼后的 P4)
-
P5 特征:由原索引 10 变为现索引 13(C2PSA 输出,未直接加 CBAM,但索引顺延)
三,检测图像验证
from ultralytics import YOLO
model = YOLO('yolo26-cbam.yaml')
model = YOLO("yolo26n.pt")
results = model('kl.jpg',save = True)
这里简单预测一个图,能跑就是没出问题

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)