保姆级教程:手把手教你给YOLOv5模型加上CA注意力模块(附完整代码)

张开发
2026/4/17 14:26:19 15 分钟阅读

分享文章

保姆级教程:手把手教你给YOLOv5模型加上CA注意力模块(附完整代码)
零基础实战YOLOv5模型集成CA注意力模块全流程解析在目标检测领域YOLOv5以其出色的性能和易用性赢得了广泛关注。而注意力机制的引入则让模型具备了选择性聚焦的能力——就像人类视觉系统会自动关注重要区域一样。本文将带你从零开始在YOLOv5中实现Coordinate AttentionCA模块的完整集成包含环境配置、代码修改、模型训练和效果验证的全套流程。1. 环境准备与项目初始化1.1 基础环境配置首先确保你的开发环境满足以下要求Python 3.8或更高版本PyTorch 1.7建议使用1.8版本以获得更好的CUDA支持CUDA 11.1如果使用GPU加速cuDNN 8.0.5推荐使用conda创建虚拟环境conda create -n yolov5_ca python3.8 conda activate yolov5_ca pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu1131.2 YOLOv5源码获取从官方仓库克隆最新代码git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt验证基础环境是否正常工作import torch print(torch.__version__, torch.cuda.is_available())2. CA模块原理与代码实现2.1 CA注意力机制核心思想Coordinate Attention的创新点主要体现在三个方面方向感知的特征编码通过水平和垂直方向的1D池化操作分别捕获两个方向的空间信息位置信息保留避免了传统注意力机制中全局池化导致的位置信息丢失轻量级设计计算开销与常规通道注意力相当适合移动端部署2.2 模块代码实现在yolov5/models/common.py文件末尾添加以下CA模块实现class h_sigmoid(nn.Module): def __init__(self, inplaceTrue): super(h_sigmoid, self).__init__() self.relu nn.ReLU6(inplaceinplace) def forward(self, x): return self.relu(x 3) / 6 class h_swish(nn.Module): def __init__(self, inplaceTrue): super(h_swish, self).__init__() self.sigmoid h_sigmoid(inplaceinplace) def forward(self, x): return x * self.sigmoid(x) class CoordinateAttention(nn.Module): def __init__(self, in_channels, out_channels, reduction32): super(CoordinateAttention, self).__init__() self.pool_h nn.AdaptiveAvgPool2d((None, 1)) # 水平方向池化 self.pool_w nn.AdaptiveAvgPool2d((1, None)) # 垂直方向池化 reduced_channels max(8, in_channels // reduction) self.conv1 nn.Conv2d(in_channels, reduced_channels, kernel_size1, stride1, padding0) self.bn1 nn.BatchNorm2d(reduced_channels) self.act h_swish() self.conv_h nn.Conv2d(reduced_channels, out_channels, kernel_size1, stride1, padding0) self.conv_w nn.Conv2d(reduced_channels, out_channels, kernel_size1, stride1, padding0) self.sigmoid nn.Sigmoid() def forward(self, x): identity x batch_size, _, height, width x.size() # 水平方向特征编码 x_h self.pool_h(x) # [batch, C, H, 1] x_w self.pool_w(x).permute(0, 1, 3, 2) # [batch, C, 1, W] - [batch, C, W, 1] # 特征融合与变换 y torch.cat([x_h, x_w], dim2) # [batch, C, HW, 1] y self.conv1(y) y self.bn1(y) y self.act(y) # 分离水平垂直特征 x_h, x_w torch.split(y, [height, width], dim2) x_w x_w.permute(0, 1, 3, 2) # 恢复原始维度 # 生成注意力权重 a_h self.sigmoid(self.conv_h(x_h)) # [batch, C, H, 1] a_w self.sigmoid(self.conv_w(x_w)) # [batch, C, 1, W] # 应用注意力 return identity * a_w * a_h3. YOLOv5模型集成3.1 修改模型解析逻辑在yolov5/models/yolo.py中找到parse_model函数添加对CA模块的支持if m in [..., CoordinateAttention]: # 在现有列表中添加CoordinateAttention args [ch[f], *args[1:]]3.2 创建自定义配置文件在yolov5/models/目录下创建yolov5s_CA.yaml配置文件# YOLOv5 by Ultralytics, GPL-3.0 license # Parameters nc: 80 # number of classes depth_multiple: 0.33 # model depth multiple width_multiple: 0.50 # layer channel multiple anchors: - [10,13, 16,30, 33,23] # P3/8 - [30,61, 62,45, 59,119] # P4/16 - [116,90, 156,198, 373,326] # P5/32 # YOLOv5 backbone backbone: # [from, number, module, args] [[-1, 1, Focus, [64, 3]], # 0-P1/2 [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 [-1, 3, C3, [128]], [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 [-1, 3, C3, [256]], [-1, 1, CoordinateAttention, [256]], # 新增CA模块 [-1, 1, Conv, [512, 3, 2]], # 6-P4/16 [-1, 3, C3, [512]], [-1, 1, CoordinateAttention, [512]], # 新增CA模块 [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 [-1, 3, C3, [1024]], [-1, 1, CoordinateAttention, [1024]], # 新增CA模块 ] # YOLOv5 head head: [[-1, 1, Conv, [512, 1, 1]], [-1, 1, nn.Upsample, [None, 2, nearest]], [[-1, 8], 1, Concat, [1]], # cat backbone P4 [-1, 3, C3, [512, False]], # 13 [-1, 1, Conv, [256, 1, 1]], [-1, 1, nn.Upsample, [None, 2, nearest]], [[-1, 6], 1, Concat, [1]], # cat backbone P3 [-1, 3, C3, [256, False]], # 17 (P3/8-small) [-1, 1, CoordinateAttention, [256]], # 新增CA模块 [-1, 1, Conv, [256, 3, 2]], [[-1, 14], 1, Concat, [1]], # cat head P4 [-1, 3, C3, [512, False]], # 21 (P4/16-medium) [-1, 1, CoordinateAttention, [512]], # 新增CA模块 [-1, 1, Conv, [512, 3, 2]], [[-1, 10], 1, Concat, [1]], # cat head P5 [-1, 3, C3, [1024, False]], # 25 (P5/32-large) [[17, 21, 25], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) ]4. 模型训练与验证4.1 启动训练使用以下命令开始训练python train.py --img 640 --batch 16 --epochs 100 --data coco.yaml --cfg models/yolov5s_CA.yaml --weights yolov5s.pt --name yolov5s_CA关键参数说明参数说明推荐值--img输入图像尺寸640--batch批次大小根据GPU内存调整--epochs训练轮数100-300--data数据集配置文件自定义数据集yaml--cfg模型配置文件yolov5s_CA.yaml--weights预训练权重yolov5s.pt4.2 训练过程监控训练过程中可以使用TensorBoard监控各项指标tensorboard --logdir runs/train重点关注以下指标变化mAP0.5IoU阈值为0.5时的平均精度mAP0.5:0.95IoU阈值从0.5到0.95的平均精度box_loss边界框回归损失obj_loss目标检测损失cls_loss分类损失4.3 模型验证训练完成后使用验证集评估模型性能python val.py --weights runs/train/yolov5s_CA/weights/best.pt --data coco.yaml --img 6405. 常见问题排查5.1 维度不匹配错误当出现类似RuntimeError: shape mismatch的错误时通常是因为CA模块的输入输出通道数设置不当。解决方法检查CoordinateAttention类初始化时的in_channels和out_channels参数确保在yaml配置文件中CA模块的通道数与前后层匹配5.2 性能下降问题如果添加CA模块后模型性能反而下降可以尝试调整CA模块的插入位置避免在网络过深或过浅处添加修改reduction参数默认32尝试16或64等不同值减少CA模块的使用数量不是每个阶段都需要添加5.3 训练不收敛遇到训练不收敛时建议降低初始学习率尝试3e-4或1e-4使用更小的batch size检查数据增强参数是否合理确保正确加载了预训练权重6. 效果对比与优化建议6.1 性能对比在COCO数据集上的对比实验结果仅供参考模型mAP0.5mAP0.5:0.95参数量(M)GFLOPsYOLOv5s56.837.47.216.5YOLOv5sCA58.1 (1.3)38.6 (1.2)7.316.76.2 优化建议位置选择CA模块更适合添加在网络的中间层如P3/P4阶段参数调整根据任务复杂度调整reduction参数简单任务可用更大的reduction值组合使用可以尝试将CA与其他注意力机制如SE组合使用量化部署CA模块适合量化部署可考虑使用TensorRT加速在实际项目中我发现将CA模块添加到YOLOv5的Neck部分特征金字塔网络通常能获得更好的效果特别是在处理多尺度目标时。此外对于小目标检测任务适当增加CA模块的数量如在每个C3模块后添加可以提升模型对小目标的敏感度。

更多文章