前言
本文介绍了高效局部注意力(ELA)机制及其在YOLO26中的结合。ELA旨在解决传统注意力机制在利用空间信息时的不足,通过“条带池化”提取空间信息,使用一维卷积和组归一化进行特征增强,生成空间注意力图,具有高效、轻量化和泛化能力强等优势。我们精心设计了三个超参数,形成四个不同版本以适应不同任务。将ELA集成进YOLO26,在检测头部分引入该模块。实验表明,ELA在图像分类、目标检测和语义分割任务上优于现有方法。
文章目录: YOLO26改进大全:卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总
专栏链接: YOLO26改进专栏
文章目录
- 前言
- 介绍
- 摘要
- 文章链接
- 基本原理
- 1. **背景与动机**
- 2. **ELA的结构**
- 3. **ELA的优势**
- 核心代码
- YOLO26引入代码
- tasks注册
- 步骤1:
- 步骤2
- 配置yolo26-ELA.yaml
- 实验
- 脚本
- 结果
介绍
摘要
注意力机制在计算机视觉领域获得了广泛认可,因为它能够有效提升深度神经网络的性能。然而,现有方法往往难以有效利用空间信息,或者即使能够利用空间信息,也通常以减少通道维度或增加神经网络复杂性为代价。为了解决这些局限性,本文提出了一种高效的局部注意力(Efficient Local Attention,ELA)方法,该方法通过简单的结构实现了显著的性能提升。
通过分析 Coordinate Attention 方法的局限性,我们发现其在使用批量归一化时缺乏泛化能力,通道注意力的维度压缩会带来负面影响,并且注意力生成过程较为复杂。为克服这些挑战,我们提出结合一维卷积和组归一化的特征增强技术。此方法通过有效编码两个一维位置特征图,准确定位感兴趣区域,无需进行维度压缩,同时实现轻量化的实现。
我们精心设计了 ELA 中的三个超参数,形成了四个不同版本:ELA-T、ELA-B、ELA-S 和 ELA-L,以满足图像分类、目标检测和语义分割等不同视觉任务的特定需求。ELA 可以无缝集成到 ResNet、MobileNet 和 DeepLab 等深度 CNN 网络中。在 ImageNet、MSCOCO 和 Pascal VOC 数据集上的大量评估表明,ELA 模块在上述三类视觉任务中均优于当前的最先进方法。
文章链接
论文地址:论文地址
代码地址:代码地址
基本原理
ELA(Efficient Local Attention)是一种新提出的注意力机制,旨在提高深度卷积神经网络(CNN)在计算机视觉任务中的表现。以下是ELA的详细介绍:
1.背景与动机
在计算机视觉中,注意力机制被广泛应用于增强深度学习模型的性能。传统的注意力机制往往在利用空间信息时存在不足,或者在有效利用空间信息的同时,降低了通道维度,导致模型的表现受到影响。因此,ELA的提出旨在解决这些问题,提供一种高效且轻量的注意力机制。
2.ELA的结构
ELA的设计主要包括以下几个关键步骤:
特征提取:ELA首先通过“条带池化”(strip pooling)方法提取输入特征图的空间信息。这种方法在水平和垂直方向上分别进行平均池化,生成包含位置信息的特征向量。
1D卷积:在获得特征向量后,ELA对这两个方向的特征向量分别应用1D卷积。这种卷积方式能够更好地处理序列信号,且计算效率高于2D卷积。
分组归一化(Group Normalization):在卷积之后,ELA使用分组归一化来替代批量归一化。分组归一化在小批量情况下表现更为稳定,能够提高模型的泛化能力。
注意力生成:最后,ELA通过将两个方向的注意力特征向量相乘,生成最终的空间注意力图。这种方法确保了对感兴趣区域的准确定位,同时保持了输入特征图的通道维度。
3.ELA的优势
- 高效性:ELA能够在不降低通道维度的情况下,准确捕捉空间信息,避免了传统方法的缺陷。
- 轻量化:与其他注意力机制相比,ELA的参数更少,计算开销更小,适合在资源受限的环境中使用。
- 更好的泛化能力:通过使用分组归一化,ELA在小批量训练时表现更为稳定,提升了模型的泛化能力。
- 易于集成:ELA可以无缝集成到现有的深度学习框架中,如ResNet、MobileNet和DeepLab等,便于实际应用。
核心代码
importtorchimporttorch.nnasnnclassELA(nn.Module):"""Constructs an Efficient Local Attention module. Args: channel: Number of channels of the input feature map kernel_size: Adaptive selection of kernel size """def__init__(self,channel,kernel_size=7):super(ELA,self).__init__()self.conv=nn.Conv1d(channel,channel,kernel_size=kernel_size,padding=kernel_size//2,groups=channel,bias=False)self.gn=nn.GroupNorm(16,channel)self.sigmoid=nn.Sigmoid()defforward(self,x):B,C,H,W=x.size()x_h=torch.mean(x,dim=3,keepdim=True).view(B,C,H)x_w=torch.mean(x,dim=2,keepdim=True).view(B,C,W)x_h=self.sigmoid(self.gn(self.conv(x_h))).view(B,C,H,1)x_w=self.sigmoid(self.gn(self.conv(x_w))).view(B,C,1,W)returnx*x_h*x_wYOLO26引入代码
在根目录下的ultralytics/目录,新建一个attention目录,然后新建一个以ELA为文件名的py文件, 把代码拷贝进去。
importtorchimporttorch.nnasnnclassELA(nn.Module):"""Constructs an Efficient Local Attention module. Args: channel: Number of channels of the input feature map kernel_size: Adaptive selection of kernel size """def__init__(self,channel,kernel_size=7):super(ELA,self).__init__()self.conv=nn.Conv1d(channel,channel,kernel_size=kernel_size,padding=kernel_size//2,groups=channel,bias=False)self.gn=nn.GroupNorm(16,channel)self.sigmoid=nn.Sigmoid()defforward(self,x):B,C,H,W=x.size()x_h=torch.mean(x,dim=3,keepdim=True).view(B,C,H)x_w=torch.mean(x,dim=2,keepdim=True).view(B,C,W)x_h=self.sigmoid(self.gn(self.conv(x_h))).view(B,C,H,1)x_w=self.sigmoid(self.gn(self.conv(x_w))).view(B,C,1,W)returnx*x_h*x_wtasks注册
在ultralytics/nn/tasks.py中进行如下操作:
步骤1:
fromultralytics.nn.attention.ELAimportELA步骤2
修改def parse_model(d, ch, verbose=True):
elifmisELA:c1,c2=ch[f],args[0]ifc2!=nc:c2=make_divisible(min(c2,max_channels)*width,8)args=[c1,*args[1:]]配置yolo26-ELA.yaml
ultralytics/cfg/models/26/yolo26-ELA.yaml
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license# Ultralytics YOLO26 object detection model with P3/8 - P5/32 outputs# Model docs: https://docs.ultralytics.com/models/yolo26# Task docs: https://docs.ultralytics.com/tasks/detect# Parametersnc:80# number of classesend2end:True# whether to use end-to-end modereg_max:1# DFL binsscales:# model compound scaling constants, i.e. 'model=yolo26n.yaml' will call yolo26.yaml with scale 'n'# [depth, width, max_channels]n:[0.50,0.25,1024]# summary: 260 layers, 2,572,280 parameters, 2,572,280 gradients, 6.1 GFLOPss:[0.50,0.50,1024]# summary: 260 layers, 10,009,784 parameters, 10,009,784 gradients, 22.8 GFLOPsm:[0.50,1.00,512]# summary: 280 layers, 21,896,248 parameters, 21,896,248 gradients, 75.4 GFLOPsl:[1.00,1.00,512]# summary: 392 layers, 26,299,704 parameters, 26,299,704 gradients, 93.8 GFLOPsx:[1.00,1.50,512]# summary: 392 layers, 58,993,368 parameters, 58,993,368 gradients, 209.5 GFLOPs# YOLO26n backbonebackbone:# [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]]-[-1,1,Conv,[256,3,2]]# 3-P3/8-[-1,2,C3k2,[512,False,0.25]]-[-1,1,Conv,[512,3,2]]# 5-P4/16-[-1,2,C3k2,[512,True]]-[-1,1,Conv,[1024,3,2]]# 7-P5/32-[-1,2,C3k2,[1024,True]]-[-1,1,SPPF,[1024,5,3,True]]# 9-[-1,2,C2PSA,[1024]]# 10# YOLO26n headhead:-[-1,1,nn.Upsample,[None,2,"nearest"]]-[[-1,6],1,Concat,[1]]# cat backbone P4-[-1,2,C3k2,[512,True]]# 13-[-1,1,nn.Upsample,[None,2,"nearest"]]-[[-1,4],1,Concat,[1]]# cat backbone P3-[-1,2,C3k2,[256,True]]# 16 (P3/8-small)-[-1,1,ELA,[256]]#17-[-1,1,Conv,[256,3,2]]-[[-1,13],1,Concat,[1]]# cat head P4-[-1,2,C3k2,[512,True]]# 19 (P4/16-medium)-[-1,1,ELA,[512]]# 21-[-1,1,Conv,[512,3,2]]-[[-1,10],1,Concat,[1]]# cat head P5-[-1,1,C3k2,[1024,True,0.5,True]]# 22 (P5/32-large)-[-1,1,ELA,[1024]]# 25-[[17,21,25],1,Detect,[nc]]# Detect(P3, P4, P5)实验
脚本
importwarnings warnings.filterwarnings('ignore')fromultralyticsimportYOLOif__name__=='__main__':# 修改为自己的配置文件地址model=YOLO('./ultralytics/cfg/models/26/yolo26-ELA.yaml')# 修改为自己的数据集地址model.train(data='./ultralytics/cfg/datasets/coco8.yaml',cache=False,imgsz=640,epochs=10,single_cls=False,# 是否是单类别检测batch=8,close_mosaic=10,workers=0,# optimizer='MuSGD',optimizer='SGD',amp=False,project='runs/train',name='yolo26-ELA',)