YOLO26改进 – C3k2 C3k2融合 EVA Block高效视觉注意力块:融合多尺度特征自适应融合与通道级特征精炼 ICIP 2025
# 前言
本文介绍了双边高效视觉注意力网络(BEVANet),并将其核心特征提取单元EVA集成进YOLO26。实时语义分割面临捕捉大感受野和细化精细轮廓的挑战,BEVANet通过SDLSKA、CKS、CFFN等模块解决这些问题,扩大感受野、提升性能、丰富上下文特征。我们将EVA相关代码集成到YOLO26中,创建C3k2_EVA模块,并在tasks文件中进行注册。实验证明,YOLO26-C3k2_EVA在目标检测任务中表现良好,实现了实时分割速度和较高的交并比。
文章目录: YOLO26改进大全:卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总
专栏链接: YOLO26改进专栏
介绍

摘要
实时语义分割面临双重挑战:需设计高效架构,既要捕捉大感受野以实现语义理解,又要细化精细轮廓。视觉 Transformer(Vision Transformers)能有效建模长程依赖关系,但计算成本高昂。为应对这些挑战,我们提出了大核注意力(Large Kernel Attention, LKA)机制。所设计的双边高效视觉注意力网络(Bilateral Efficient Visual Attention Network, BEVANet)通过稀疏分解大分离核注意力(Sparse Decomposed Large Separable Kernel Attentions, SDLSKA)扩大感受野、捕捉上下文信息,并提取视觉与结构特征。综合核选择(Comprehensive Kernel Selection, CKS)机制可动态调整感受野,进一步提升性能。此外,深层大核金字塔池化模块(Deep Large Kernel Pyramid Pooling Module, DLKPPM)通过协同结合空洞卷积与大核注意力,丰富上下文特征。双边架构促进分支间的频繁交互,而边界引导自适应融合(Boundary Guided Adaptive Fusion, BGAF)模块在边界引导下融合空间特征与语义特征,提升边界描绘精度。BEVANet 实现了 33 帧 / 秒(FPS)的实时分割速度,无预训练时的交并比(mIoU)达 79.3%,经 ImageNet 预训练后在 Cityscapes 数据集上的 mIoU 达 81.0%,展现出最先进的性能。相关代码和模型已开源至:https://github.com/maomao0819/BEVANet。
文章链接
论文地址:论文地址
代码地址:代码地址
基本原理
EVA(Efficient Visual Attention Block,高效视觉注意力块)是BEVANet的核心特征提取单元,专为解决实时语义分割中“大感受野捕捉语义上下文”与“细节轮廓精炼”的矛盾而设计,同时通过结构优化控制计算成本,适配实时性需求。其设计灵感源于VAN [13] 和LSKA [14] 的鲁棒块结构,核心是以大核注意力(LKA)为基础,融合多尺度特征自适应融合与通道级特征精炼,形成“注意力建模+特征优化”的端到端复合模块。
关键子模块详解
1. SDLSKA:稀疏分解大分离核注意力(LKA的核心执行单元)
SDLSKA(Sparse Decomposed Large Separable Kernel Attention)是EVA模块扩大感受野、降低计算成本的核心,通过“大核稀疏分解+带孔卷积复用”实现高效大核注意力。
(1)设计思路
传统大核卷积(如31×31、51×51)虽能扩大感受野,但计算量呈平方级增长;SDLSKA借鉴SLaK [12] 的稀疏分组思想和LSKA [14] 的带孔卷积优化,将单一超大核分解为“小核卷积+带孔条带卷积”,在保持等效感受野的同时降低参数复杂度。
(2)具体结构与操作
- 基础卷积层:先用5×5普通卷积聚焦局部特征,为后续大感受野捕捉奠定基础;
- 带孔条带卷积:通过两个正交的条带卷积(1×11和11×1)进一步扩大感受野,且卷积核 dilation 率设为3——这种设计既保留了2D结构信息,又避免了全尺寸大核的高计算开销;
- 特征融合:将5×5卷积输出与两个条带卷积输出自适应融合,最终实现35×35的等效感受野(远超传统3×3卷积的感受野);
- 稀疏分组优化:通过稀疏分组策略减少冗余计算,相比同等感受野的大核卷积,参数与计算量降低60%以上。
(3)核心优势
- 感受野大:35×35的感受野可有效捕捉长程语义依赖;
- 计算高效:分解后的小核+条带卷积避免了全尺寸大核的平方级计算量;
- 结构适配:同时捕捉局部细节(5×5卷积)和全局上下文(条带卷积),平衡语义与细节。
2. CKS:综合核选择(LKA的自适应融合单元)
CKS(Comprehensive Kernel Selection)是EVA模块实现多尺度特征自适应融合的关键,突破了SKNet [16]、LSKNet [15] 对“通道维度”和“空间维度”的解耦处理局限。
(1)设计痛点
现有核选择机制(如SKNet)仅关注通道维度的权重分配,LSKNet虽引入空间维度,但二者是独立优化(解耦),无法捕捉通道与空间的 interdependence(相互依赖),导致多尺度融合不充分。
(2)具体结构与操作
CKS通过“通道分支+空间分支+联合权重融合”实现动态适配,结构如图2(c)所示:
- 特征输入:接收SDLSKA分解后的多尺度核特征(小核、条带核输出);
- 空间分支:通过卷积操作生成3个特征通道,计算空间维度的注意力权重,聚焦关键空间区域;
- 通道分支:通过1×1点卷积和深度卷积(depthwise convolution)精炼通道特征,计算通道维度的注意力权重,筛选有效特征通道;
- 联合融合:将空间权重与通道权重通过乘法融合,动态调整不同核特征的贡献度,实现“多尺度核+通道-空间联合优化”的特征整合。
(3)核心优势
- 联合优化:首次实现通道与空间维度的联合权重调整,捕捉二者相互依赖关系;
- 多尺度适配:适配不同形状(小核、条带核)、不同尺度的特征,提升融合灵活性;
- 性能更优:相比LSKNet的解耦机制,CKS在仅降低0.5 FPS的情况下,mIoU提升0.26%(消融实验验证)。
3. CFFN:卷积前馈网络(EVA的特征精炼单元)
CFFN(Convolution Feed-Forward Network)是EVA模块的“特征精炼器”,承接LKA块输出的多尺度融合特征,通过通道级优化消除冗余、提升特征紧凑性。
(1)核心操作
- 1×1点卷积:调整特征通道维度,平衡通道间的特征分布;
- 激活函数(GELU):引入非线性,增强特征表达能力;
- 二次精炼:通过深度卷积进一步优化特征空间分布,确保输出特征的有效性。
(2)核心作用
- 消除冗余:过滤LKA模块输出的无效特征,降低后续模块的计算负担;
- 特征平衡:调整通道维度的特征强度,避免部分通道特征过强或过弱;
- 保持实时性:仅使用轻量的点卷积和深度卷积,计算开销可忽略(占EVA模块总计算量的不足10%)。
核心代码
class EVAN(nn.Module):
"""Implementation of Efficient Visual Attention Network Block."""
def __init__(self, lka=SDLSKA, dwconv=DWConv, pwconv=PWConv, dim=512, kernel_size=35, mlp_expand=4., drop=0.,drop_path=0., act_layer=nn.GELU):
super().__init__()
self.norm1 = nn.BatchNorm2d(dim)
self.attn = SpatialAttention(lka, dim, kernel_size, dwconv=dwconv, pwconv=pwconv)
self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
self.norm2 = nn.BatchNorm2d(dim)
mlp_hidden_dim = int(dim * mlp_expand)
self.mlp = MLP(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
layer_scale_init_value = 1e-2
self.layer_scale_1 = nn.Parameter(
layer_scale_init_value * torch.ones((dim)), requires_grad=True)
self.layer_scale_2 = nn.Parameter(
layer_scale_init_value * torch.ones((dim)), requires_grad=True)
self.apply(self._init_weights)
def _init_weights(self, m):
if isinstance(m, nn.Linear):
nn.init.trunc_normal_(m.weight, std=.02)
if m.bias is not None:
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.LayerNorm):
nn.init.constant_(m.bias, 0)
nn.init.constant_(m.weight, 1.0)
elif isinstance(m, nn.Conv2d):
fan_out = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
fan_out //= m.groups
nn.init.normal_(m.weight, 0, math.sqrt(2.0 / fan_out))
if m.bias is not None:
nn.init.constant_(m.bias, 0)
def forward(self, x):
x = x + self.drop_path(self.layer_scale_1.unsqueeze(-1).unsqueeze(-1) * self.attn(self.norm1(x)))
x = x + self.drop_path(self.layer_scale_2.unsqueeze(-1).unsqueeze(-1) * self.mlp(self.norm2(x)))
return x
实验
脚本
import warnings
warnings.filterwarnings('ignore')
from ultralytics import YOLO
if __name__ == '__main__':
# 修改为自己的配置文件地址
model = YOLO('./ultralytics/cfg/models/26/yolo26-C3k2_EVA.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-C3k2_EVA',
)
结果
