开始讲解之前推荐一下我的专栏本专栏的内容支持(分类、检测、分割、追踪、关键点检测),专栏目前为限时折扣欢迎大家订阅本专栏本专栏每周更新5-7篇最新机制更有包含我所有改进的文件和交流群提供给大家本人定期在群内分享发表论文方法和经验。一、本文介绍本文给大家带来的最新改进机制是发表于 2026 年医学图像领域的注意力模块 AFIA。 如果你的研究方向涉及医学目标检测、视频目标检测那么这个模块完全可以作为一个值得关注的创新点。 当然AFIA 并不局限于医学场景只要你的任务同样面临目标模糊、动态干扰强、背景复杂或特征易混淆等问题它同样具有较强的应用潜力。 其核心思想可以概括为通过双分支自注意力、自适应融合以及通道重排增强动态场景下的特征表达能力从而提升模型对模糊目标和复杂背景目标的检测表现。除此之外本文还进一步将 AFIA 与 C2PSA 结合完成了一个可直接用于论文写作与实验设计的二次创新模块。同时本文还讲解了在YOLOv26中使用时针对不同尺度的检测目标不同的使用方法。欢迎大家订阅我的专栏一起学习YOLO购买专栏读者联系读者入群获取进阶项目文件文字学不会的读者作者可提供视频学习方法.专栏链接YOLOv26有效涨点专栏包含Conv、注意力机制、主干/Backbone、损失函数、优化器、后处理等改进机制目录一、本文介绍二、AFIA 模块原理介绍2.1 双分支自适应自注意力一条保信息一条去噪声2.2 为什么不能只用 DSA 或只用 SSA2.3 自适应特征融合让模型自己决定更信哪一支2.4 Channel Shuffle不是主角但很关键2.5 AFIA 的最终输出是怎么得到的三、核心代码四、添加方法4.1 修改一4.2 修改二4.3 修改三4.4 修改四4.5 修改五4.6 修改六五、正式训练5.1 yaml文件5.1.1 yaml文件15.1.2 yaml文件25.2 训练代码5.3 训练过程截图五、本文总结二、AFIA 模块原理介绍论文链接官方论文链接点击此处即可跳转代码链接官方代码链接点击此处即可跳转大致介绍在动态肠镜场景中息肉检测和普通静态图像检测并不一样。论文一开始就强调结肠镜视频虽然比静态图像包含更丰富的诊断信息但由于检查过程中镜头持续运动单帧图像里会频繁出现运动模糊、镜面反射、气泡液体干扰以及尺度变化等问题。这些因素会直接破坏图像质量使得模型更容易把背景纹理当成目标或者错过真正的息肉区域。论文第 2 页的 Fig.1 就专门展示了这几类典型干扰快速运动带来的背景组织模糊和断裂、镜头与肠壁接触引起的高光和气泡以及相机远近变化导致的同一解剖结构尺度剧烈波动。在这样的背景下作者提出了 AVPDN并把 AFIAAdaptive Feature Interaction and Augmentation 作为其中最核心的特征增强模块之一。论文明确写到AFIA 位于 AFEAdaptive Feature Enhancement块的核心位置用来在特征层面完成“增强有效信息、抑制噪声干扰、改善特征表达”这几件事。输入图像先经过 ResNet-50 主干网络提取基础特征再进入一系列 AFE 块而在每个 AFE 块内部特征会先经过 LayerNorm然后进入 AFIA 做第一轮特征优化再继续后续处理。也就是说AFIA 并不是一个挂在检测头后面的附加模块而是整个特征增强链路里的关键前端单元。论文第 3–4 页对这一流程有明确描述图 2 也把 AFIA 在整体网络中的位置画得很清楚。如果从设计动机来看AFIA 其实是在回应一个很具体的问题传统 ViT 虽然擅长建模长距离依赖但在结肠镜视频这种复杂噪声背景中会把大量无关 token 一起纳入建模既增加了无效计算也会把冗余和噪声特征一起学进去。论文指出肠镜图像中的背景纹理本身就复杂再叠加运动模糊、镜面反射和尺度波动直接套用标准自注意力往往会导致特征图中噪声和冗余信息过多从而削弱检测性能。因此AFIA 的本质目标不是单纯“加一个注意力机制”而是要自适应地提升与息肉相关的特征同时压制无关区域和噪声响应。从内部结构看论文把 AFIA 总结为一个“三管齐下”的设计第一部分是双分支自适应自注意力第二部分是channel shuffle 带来的特征多样化第三部分是自适应特征融合。这三者组合起来构成了 AFIA 的核心。论文第 5 页对这三部分写得很完整。2.1 双分支自适应自注意力一条保信息一条去噪声AFIA 最关键的设计是它的双分支注意力结构。论文把这两条分支分别称为1. DSADense Self-Attention2. SSASparse Self-Attention作者认为在动态肠镜图像中模型既需要理解整个场景的全局上下文又必须主动过滤掉由模糊和反光引起的大量低质量响应只靠单一种类的注意力很难兼顾这两点所以才引入了双分支机制。其中DSA 可以理解成“保留全局信息”的那条分支。论文中它沿用了常规自注意力的思路通过 Softmax 对所有 query-key 对进行归一化从而建模长距离依赖关系。作者指出这一分支对于理解整体场景结构非常重要因为它能够帮助模型保留关键语义信息不至于因为过度筛选而丢掉有用上下文。公式上论文写成其中 (Q)、(K)、(V) 由输入特征经过 (1\times1) 卷积和 (3\times3) depthwise convolution 生成(B) 表示可学习的相对位置偏置。与之对应SSA 则可以理解成“主动降噪”的那条分支。论文没有继续使用 Softmax而是把评分函数换成了 ReLU。这样一来那些 query-key 匹配程度低、相关性弱的响应会直接被压到 0从而形成更稀疏的注意力图。作者特别强调这个设计对于结肠镜视频非常关键因为它可以更有针对性地压制由运动模糊、镜面高光和无关背景纹理造成的伪激活让模型把注意力集中在更有判别性的区域上。公式写成换句话说DSA 更偏向“别漏掉有用信息”SSA 更偏向“别把噪声也当成信息”。前者负责兜底后者负责清理。2.2 为什么不能只用 DSA 或只用 SSA这篇论文写得比较好的地方是它没有停留在“提出两个分支”这个层面而是明确解释了为什么不能只保留其中一个。作者指出如果只使用 DSA虽然能较好地保留全局信息但 Softmax 会把所有位置都纳入注意力分配中这会导致无关区域甚至噪声区域也参与特征聚合容易把背景干扰一起带进来。反过来如果只使用 SSA虽然噪声能被压制得更狠但 ReLU 带来的稀疏性也可能太强导致部分有用特征在后续处理中信息不足也就是论文里说的 over-sparsity 问题。所以AFIA 的思路并不是简单堆两个分支而是在“保留足够上下文”和“强力抑制噪声”之间找平衡。这个平衡点正是 AFIA 想解决的核心问题。2.3 自适应特征融合让模型自己决定更信哪一支有了 DSA 和 SSA 之后还存在一个问题不同图像、不同场景下两条分支的重要性其实并不一样。某些帧中背景干扰特别严重这时可能更需要 SSA 去筛噪而另一些帧中目标边界模糊但上下文关系比较重要这时 DSA 的作用就更突出。为了解决这个问题AFIA 又加入了自适应融合机制。论文中用两个可学习参数来给两条分支分配权重并通过归一化得到每一支的最终融合系数然后再将两条注意力分支的结果按权重组合并与 (V) 做逐元素作用得到注意力输出论文解释说这样的做法使模型能够根据当前输入的特点动态调整两条分支的重要性。也就是说AFIA 不是固定地“各占一半”而是由网络在训练中自己学会什么时候该更依赖全局上下文什么时候该更激进地去噪。作者还提到这些可学习参数会用对应分支的输出来初始化以增强自适应能力。。2.4 Channel Shuffle不是主角但很关键除了双分支注意力AFIA 还有一个容易被忽略但很实用的设计就是 channel shuffle。论文认为即便有了双分支注意力如果输入特征本身通道交互不足、不同通道学到的内容过于相似那么最终得到的表示仍然可能不够丰富。传统卷积网络里不同通道之间往往会学出重复或冗余的模式。为了解决这一点AFIA 在上分支中加入了 channel shuffle 操作用来打散并重组通道使不同组之间的信息发生交换。具体来说论文给出的上分支形式为其中就表示 channel shuffle先对输入张量按通道分组再重新排列之后接卷积和堆叠的卷积进行特征提取。作者解释说这样做的目的是避免 AFIA 过度依赖某些单一通道促进模型学习更互补、更多样的特征表达而且不会明显增加额外计算开销。2.5 AFIA 的最终输出是怎么得到的AFIA 的最终输出并不复杂它把 channel shuffle 分支得到的特征和 双分支注意力融合后的特征相加得到模块输出从这个结果也能看出AFIA 最终保留下来的并不是单纯的“注意力结果”而是通道重组后的局部卷积特征与自适应注意力增强后的全局/稀疏特征的联合表示。换句话说它希望同时保住两类能力一类是卷积系的局部纹理建模与通道交互能力另一类是注意力系的全局依赖建模和噪声筛除能力。个人总结AFIA 本质上是一个面向动态肠镜场景的特征净化与增强模块。它并不是简单堆叠注意力而是围绕结肠镜图像中常见的运动模糊、镜面高光和复杂背景噪声设计了一套更有针对性的特征处理流程。具体来说DSA 分支负责保留全局上下文和关键语义信息SSA 分支负责抑制低相关区域带来的噪声响应自适应融合机制负责根据输入动态平衡两者的贡献而 channel shuffle 则进一步促进跨通道信息交换提升特征多样性。最终AFIA 在保住有用上下文的同时更有效地滤除了任务无关干扰为后续检测提供了更稳定、更有判别力的特征表示。其效果也在消融实验中得到了明确验证完整 AFIA 相比基线显著提升了 AP 和 F1-score说明这种“全局建模 稀疏筛噪 通道重组”的组合对动态息肉检测是有效的。三、核心代码核心代码的使用方式看章节四import torch import torch.nn as nn import torch.nn.functional as F __all__ [AFIA, C2PSA_AFIA] class ChannelShuffle(nn.Module): def __init__(self, groups): super().__init__() self.groups groups def forward(self, x): b, c, h, w x.size() channels_per_group c // self.groups # reshape x x.view(b, self.groups, channels_per_group, h, w) # transpose x x.transpose(1, 2).contiguous() # flatten x x.view(b, -1, h, w) return x class AFIA(nn.Module): def __init__(self, in_channels, groups4): super().__init__() self.layer_norm nn.LayerNorm(in_channels) # Assuming layer norm is applied over channels self.conv1x1_q nn.Conv2d(in_channels, in_channels, kernel_size1) self.deconv3x3_q nn.ConvTranspose2d(in_channels, in_channels, kernel_size3, stride1, padding1) self.conv1x1_k nn.Conv2d(in_channels, in_channels, kernel_size1) self.deconv3x3_k nn.ConvTranspose2d(in_channels, in_channels, kernel_size3, stride1, padding1) self.conv1x1_v nn.Conv2d(in_channels, in_channels, kernel_size1) self.deconv3x3_v nn.ConvTranspose2d(in_channels, in_channels, kernel_size3, stride1, padding1) self.channel_shuffle ChannelShuffle(groups) self.stacked_conv nn.Sequential( nn.Conv2d(in_channels, in_channels, kernel_size3, padding1), nn.ReLU(inplaceTrue), nn.Conv2d(in_channels, in_channels, kernel_size3, padding1), ) self.conv1x1_out nn.Conv2d(in_channels, in_channels, kernel_size1) self.layer_norm2 nn.LayerNorm(in_channels) def depthwise_spatial_attention(self, Q, K): Calculates the Depthwise Spatial Attention Map between Q and K. Args: Q: Tensor of shape (B, C, H, W) K: Tensor of shape (B, C, H, W) Returns: A spatial attention map with shape (B, H, W) B, C, H, W Q.shape Q Q.permute(0, 2, 3, 1).reshape(B, H * W, C) # B, HW, C K K.permute(0, 2, 3, 1).reshape(B, H * W, C) # B, HW, C attention_map torch.matmul(Q, K.transpose(1, 2)) # B, HW, HW attention_map F.softmax(attention_map / (C ** 0.5), dim-1) # B, HW, HW return attention_map def spatial_wise_self_attention(self, V, attention_map): Apply spatial-wise self-attention to value feature map Args: V: Tensor of shape (B, C, H, W) attention_map: Attention map with shape (B, H, W, HW) Return: weighted V B, C, H, W V.shape V V.permute(0, 2, 3, 1).reshape(B, H * W, C) # B, HW, C weighted_V torch.matmul(attention_map, V) weighted_V weighted_V.reshape(B, H, W, C).permute(0, 3, 1, 2) return weighted_V def forward(self, x): residual x x x.permute(0, 2, 3, 1) # B,H,W,C x self.layer_norm(x).permute(0, 3, 1, 2) # B,C,H,W # Q branch Q self.conv1x1_q(x) Q self.deconv3x3_q(Q) # K branch K self.conv1x1_k(x) K self.deconv3x3_k(K) # V branch V self.conv1x1_v(x) V self.deconv3x3_v(V) # Channel Shuffle x self.channel_shuffle(x) # DSA attention_map self.depthwise_spatial_attention(Q, K) # SSA out self.spatial_wise_self_attention(V, attention_map) # Apply weights out F.relu(out) # 1x1 Conv out out self.conv1x1_out(out) # Add and output out out self.stacked_conv(x) out out residual out out.permute(0, 2, 3, 1) out self.layer_norm2(out).permute(0, 3, 1, 2) return out def autopad(k, pNone, d1): # kernel, padding, dilation Pad to same shape outputs. if d 1: k d * (k - 1) 1 if isinstance(k, int) else [d * (x - 1) 1 for x in k] # actual kernel-size if p is None: p k // 2 if isinstance(k, int) else [x // 2 for x in k] # auto-pad return p class Conv(nn.Module): Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation). default_act nn.SiLU() # default activation def __init__(self, c1, c2, k1, s1, pNone, g1, d1, actTrue): Initialize Conv layer with given arguments including activation. super().__init__() self.conv nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groupsg, dilationd, biasFalse) self.bn nn.BatchNorm2d(c2) self.act self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity() def forward(self, x): Apply convolution, batch normalization and activation to input tensor. return self.act(self.bn(self.conv(x))) def forward_fuse(self, x): Perform transposed convolution of 2D data. return self.act(self.conv(x)) class PSABlock(nn.Module): def __init__(self, c, attn_ratio0.5, num_heads4, shortcutTrue) - None: Initializes the PSABlock with attention and feed-forward layers for enhanced feature extraction. super().__init__() self.attn AFIA(c, 4) self.ffn nn.Sequential(Conv(c, c * 2, 1), Conv(c * 2, c, 1, actFalse)) self.add shortcut def forward(self, x): Executes a forward pass through PSABlock, applying attention and feed-forward layers to the input tensor. x x self.attn(x) if self.add else self.attn(x) x x self.ffn(x) if self.add else self.ffn(x) return x class C2PSA_AFIA(nn.Module): C2PSA module with attention mechanism for enhanced feature extraction and processing. This module implements a convolutional block with attention mechanisms to enhance feature extraction and processing capabilities. It includes a series of PSABlock modules for self-attention and feed-forward operations. Attributes: c (int): Number of hidden channels. cv1 (Conv): 1x1 convolution layer to reduce the number of input channels to 2*c. cv2 (Conv): 1x1 convolution layer to reduce the number of output channels to c. m (nn.Sequential): Sequential container of PSABlock modules for attention and feed-forward operations. Methods: forward: Performs a forward pass through the C2PSA module, applying attention and feed-forward operations. Notes: This module essentially is the same as PSA module, but refactored to allow stacking more PSABlock modules. def __init__(self, c1, c2, n1, e0.5): Initializes the C2PSA module with specified input/output channels, number of layers, and expansion ratio. super().__init__() assert c1 c2 self.c int(c1 * e) self.cv1 Conv(c1, 2 * self.c, 1, 1) self.cv2 Conv(2 * self.c, c1, 1) self.m nn.Sequential(*(PSABlock(self.c, attn_ratio0.5, num_headsself.c // 64) for _ in range(n))) def forward(self, x): Processes the input tensor x through a series of PSA blocks and returns the transformed tensor. a, b self.cv1(x).split((self.c, self.c), dim1) b self.m(b) return self.cv2(torch.cat((a, b), 1)) if __name__ __main__: # Generating Sample image image_size (1, 64, 240, 240) image torch.rand(*image_size) # Model mobilenet_v1 C2PSA_AFIA(64, 64) out mobilenet_v1(image) print(out.size())四、添加方法下面的步骤如果你不会或者不想麻烦操作可以联系作者获得本专栏添加所有项目文件的源代码可直接训练.4.1 修改一第一还是建立文件我们找到如下ultralytics/nn文件夹下建立一个目录名字呢就是Addmodules文件夹4.2 修改二然后在Addmodules文件夹内建立一个新的py文件将本文章节三中的“核心代码复制粘贴进去。4.3 修改三第二步我们在该目录下创建一个新的py文件名字为__init__.py然后在其内部导入我们的文件如下图所示。4.4 修改四第三步我门中到如下文件ultralytics/nn/tasks.py进行导入和注册我们的模块(此处只需要添加一次即可如果你用我其它的改进机制这里的步骤只需要添加一次)4.5 修改五在ultralytics/nn/tasks.py文件内的parse_model方法函数内位置大概在1500行左右按照图示位置添加即可此处需要自己有一定的判别能力如果不会可联系作者获得视频教程。4.6 修改六在ultralytics/nn/tasks.py文件内的parse_model方法函数内位置大概在1550行左右按照图示位置添加即可此处一定要对应好位置和缩进否则很容易报错。elif m in {此处填写本章代码的名字.}: c2 ch[f] args [c2, *args]五、正式训练5.1 yaml文件5.1.1 yaml文件1训练信息YOLO26-C2PSA-AFIA summary: 265 layers, 3,259,292 parameters, 3,259,292 gradients, 6.4 GFLOPs# 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 # Parameters nc: 80 # number of classes end2end: True # whether to use end-to-end mode reg_max: 1 # DFL bins scales: # model compound scaling constants, i.e. modelyolo26n.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 GFLOPs s: [0.50, 0.50, 1024] # summary: 260 layers, 10,009,784 parameters, 10,009,784 gradients, 22.8 GFLOPs m: [0.50, 1.00, 512] # summary: 280 layers, 21,896,248 parameters, 21,896,248 gradients, 75.4 GFLOPs l: [1.00, 1.00, 512] # summary: 392 layers, 26,299,704 parameters, 26,299,704 gradients, 93.8 GFLOPs x: [1.00, 1.50, 512] # summary: 392 layers, 58,993,368 parameters, 58,993,368 gradients, 209.5 GFLOPs # YOLO26n backbone 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]] - [-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_AFIA, [1024]] # 10 # YOLO26n head head: - [-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, Conv, [256, 3, 2]] - [[-1, 13], 1, Concat, [1]] # cat head P4 - [-1, 2, C3k2, [512, True]] # 19 (P4/16-medium) - [-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) - [[16, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5)5.1.2 yaml文件2训练信息YOLO26-Att-AFIA summary: 273 layers, 2,707,676 parameters, 2,707,676 gradients, 8.4 GFLOPs# 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 # Parameters nc: 80 # number of classes end2end: True # whether to use end-to-end mode reg_max: 1 # DFL bins scales: # model compound scaling constants, i.e. modelyolo26n.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 GFLOPs s: [0.50, 0.50, 1024] # summary: 260 layers, 10,009,784 parameters, 10,009,784 gradients, 22.8 GFLOPs m: [0.50, 1.00, 512] # summary: 280 layers, 21,896,248 parameters, 21,896,248 gradients, 75.4 GFLOPs l: [1.00, 1.00, 512] # summary: 392 layers, 26,299,704 parameters, 26,299,704 gradients, 93.8 GFLOPs x: [1.00, 1.50, 512] # summary: 392 layers, 58,993,368 parameters, 58,993,368 gradients, 209.5 GFLOPs # YOLO26n backbone 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]] - [-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 head head: - [-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, Conv, [256, 3, 2]] - [[-1, 13], 1, Concat, [1]] # cat head P4 - [-1, 2, C3k2, [512, True]] # 19 (P4/16-medium) - [-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) - [16, 1, AFIA, []] # 23 # - [19, 1, AFIA, []] # 24 # - [22, 1, AFIA, []] # 25 # 此处的使用说法注释: 其中上面的三个注意力机制目前仅使用了23层如果你想使用24层那么就取消掉代码注释 # 并将下面检测头中的19改为24,如果想使用第25层注意力机制同理将下面检测头中的22改为25即可。 # 此处用法比较复杂如过不会联系Snu77博主获取视频教程 - [[23, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5)5.2 训练代码大家可以创建一个py文件将我给的代码复制粘贴进去配置好自己的文件路径即可运行。import warnings warnings.filterwarnings(ignore) from ultralytics import YOLO if __name__ __main__: model YOLO(模型配置文件地址,也就是5.1你保存到本地文件的地址) # 如何切换模型版本, 上面的ymal文件可以改为 yolo26s.yaml就是使用的26s, # 类似某个改进的yaml文件名称为yolo26-XXX.yaml那么如果想使用其它版本就把上面的名称改为yolo26l-XXX.yaml即可改的是上面YOLO中间的名字不是配置文件的 # model.load(yolo26n.pt) # 是否加载预训练权重,科研不建议大家加载否则很难提升精度 model.train( datar数据集文件地址, # 如果大家任务是其它的ultralytics/cfg/default.yaml找到这里修改task可以改成detect, segment, classify, pose cacheFalse, imgsz640, epochs20, single_clsFalse, # 是否是单类别检测 batch16, close_mosaic0, workers0, device0, optimizerMuSGD, # using SGD/MuSGD # resume, # 这里是填写last.pt地址 ampTrue, # 如果出现训练损失为Nan可以关闭amp projectruns/train, nameexp, )5.3 训练过程截图五、本文总结到此本文的正式分享内容就结束了在这里给大家推荐我的YOLOv26改进有效涨点专栏本专栏目前为新开的平均质量分98分后期我会根据各种最新的前沿顶会进行论文复现也会对一些老的改进机制进行补充如果大家觉得本文帮助到你了订阅本专栏关注后续更多的更新~专栏链接YOLOv26有效涨点专栏包含Conv、注意力机制、主干/Backbone、损失函数、优化器、后处理等改进机制
yolov26改进 | 添加注意力机制篇 | 2026医学最新注意力机制AFIA抑制图像噪声环境影响(全网独家首发)
发布时间:2026/6/1 10:40:56
开始讲解之前推荐一下我的专栏本专栏的内容支持(分类、检测、分割、追踪、关键点检测),专栏目前为限时折扣欢迎大家订阅本专栏本专栏每周更新5-7篇最新机制更有包含我所有改进的文件和交流群提供给大家本人定期在群内分享发表论文方法和经验。一、本文介绍本文给大家带来的最新改进机制是发表于 2026 年医学图像领域的注意力模块 AFIA。 如果你的研究方向涉及医学目标检测、视频目标检测那么这个模块完全可以作为一个值得关注的创新点。 当然AFIA 并不局限于医学场景只要你的任务同样面临目标模糊、动态干扰强、背景复杂或特征易混淆等问题它同样具有较强的应用潜力。 其核心思想可以概括为通过双分支自注意力、自适应融合以及通道重排增强动态场景下的特征表达能力从而提升模型对模糊目标和复杂背景目标的检测表现。除此之外本文还进一步将 AFIA 与 C2PSA 结合完成了一个可直接用于论文写作与实验设计的二次创新模块。同时本文还讲解了在YOLOv26中使用时针对不同尺度的检测目标不同的使用方法。欢迎大家订阅我的专栏一起学习YOLO购买专栏读者联系读者入群获取进阶项目文件文字学不会的读者作者可提供视频学习方法.专栏链接YOLOv26有效涨点专栏包含Conv、注意力机制、主干/Backbone、损失函数、优化器、后处理等改进机制目录一、本文介绍二、AFIA 模块原理介绍2.1 双分支自适应自注意力一条保信息一条去噪声2.2 为什么不能只用 DSA 或只用 SSA2.3 自适应特征融合让模型自己决定更信哪一支2.4 Channel Shuffle不是主角但很关键2.5 AFIA 的最终输出是怎么得到的三、核心代码四、添加方法4.1 修改一4.2 修改二4.3 修改三4.4 修改四4.5 修改五4.6 修改六五、正式训练5.1 yaml文件5.1.1 yaml文件15.1.2 yaml文件25.2 训练代码5.3 训练过程截图五、本文总结二、AFIA 模块原理介绍论文链接官方论文链接点击此处即可跳转代码链接官方代码链接点击此处即可跳转大致介绍在动态肠镜场景中息肉检测和普通静态图像检测并不一样。论文一开始就强调结肠镜视频虽然比静态图像包含更丰富的诊断信息但由于检查过程中镜头持续运动单帧图像里会频繁出现运动模糊、镜面反射、气泡液体干扰以及尺度变化等问题。这些因素会直接破坏图像质量使得模型更容易把背景纹理当成目标或者错过真正的息肉区域。论文第 2 页的 Fig.1 就专门展示了这几类典型干扰快速运动带来的背景组织模糊和断裂、镜头与肠壁接触引起的高光和气泡以及相机远近变化导致的同一解剖结构尺度剧烈波动。在这样的背景下作者提出了 AVPDN并把 AFIAAdaptive Feature Interaction and Augmentation 作为其中最核心的特征增强模块之一。论文明确写到AFIA 位于 AFEAdaptive Feature Enhancement块的核心位置用来在特征层面完成“增强有效信息、抑制噪声干扰、改善特征表达”这几件事。输入图像先经过 ResNet-50 主干网络提取基础特征再进入一系列 AFE 块而在每个 AFE 块内部特征会先经过 LayerNorm然后进入 AFIA 做第一轮特征优化再继续后续处理。也就是说AFIA 并不是一个挂在检测头后面的附加模块而是整个特征增强链路里的关键前端单元。论文第 3–4 页对这一流程有明确描述图 2 也把 AFIA 在整体网络中的位置画得很清楚。如果从设计动机来看AFIA 其实是在回应一个很具体的问题传统 ViT 虽然擅长建模长距离依赖但在结肠镜视频这种复杂噪声背景中会把大量无关 token 一起纳入建模既增加了无效计算也会把冗余和噪声特征一起学进去。论文指出肠镜图像中的背景纹理本身就复杂再叠加运动模糊、镜面反射和尺度波动直接套用标准自注意力往往会导致特征图中噪声和冗余信息过多从而削弱检测性能。因此AFIA 的本质目标不是单纯“加一个注意力机制”而是要自适应地提升与息肉相关的特征同时压制无关区域和噪声响应。从内部结构看论文把 AFIA 总结为一个“三管齐下”的设计第一部分是双分支自适应自注意力第二部分是channel shuffle 带来的特征多样化第三部分是自适应特征融合。这三者组合起来构成了 AFIA 的核心。论文第 5 页对这三部分写得很完整。2.1 双分支自适应自注意力一条保信息一条去噪声AFIA 最关键的设计是它的双分支注意力结构。论文把这两条分支分别称为1. DSADense Self-Attention2. SSASparse Self-Attention作者认为在动态肠镜图像中模型既需要理解整个场景的全局上下文又必须主动过滤掉由模糊和反光引起的大量低质量响应只靠单一种类的注意力很难兼顾这两点所以才引入了双分支机制。其中DSA 可以理解成“保留全局信息”的那条分支。论文中它沿用了常规自注意力的思路通过 Softmax 对所有 query-key 对进行归一化从而建模长距离依赖关系。作者指出这一分支对于理解整体场景结构非常重要因为它能够帮助模型保留关键语义信息不至于因为过度筛选而丢掉有用上下文。公式上论文写成其中 (Q)、(K)、(V) 由输入特征经过 (1\times1) 卷积和 (3\times3) depthwise convolution 生成(B) 表示可学习的相对位置偏置。与之对应SSA 则可以理解成“主动降噪”的那条分支。论文没有继续使用 Softmax而是把评分函数换成了 ReLU。这样一来那些 query-key 匹配程度低、相关性弱的响应会直接被压到 0从而形成更稀疏的注意力图。作者特别强调这个设计对于结肠镜视频非常关键因为它可以更有针对性地压制由运动模糊、镜面高光和无关背景纹理造成的伪激活让模型把注意力集中在更有判别性的区域上。公式写成换句话说DSA 更偏向“别漏掉有用信息”SSA 更偏向“别把噪声也当成信息”。前者负责兜底后者负责清理。2.2 为什么不能只用 DSA 或只用 SSA这篇论文写得比较好的地方是它没有停留在“提出两个分支”这个层面而是明确解释了为什么不能只保留其中一个。作者指出如果只使用 DSA虽然能较好地保留全局信息但 Softmax 会把所有位置都纳入注意力分配中这会导致无关区域甚至噪声区域也参与特征聚合容易把背景干扰一起带进来。反过来如果只使用 SSA虽然噪声能被压制得更狠但 ReLU 带来的稀疏性也可能太强导致部分有用特征在后续处理中信息不足也就是论文里说的 over-sparsity 问题。所以AFIA 的思路并不是简单堆两个分支而是在“保留足够上下文”和“强力抑制噪声”之间找平衡。这个平衡点正是 AFIA 想解决的核心问题。2.3 自适应特征融合让模型自己决定更信哪一支有了 DSA 和 SSA 之后还存在一个问题不同图像、不同场景下两条分支的重要性其实并不一样。某些帧中背景干扰特别严重这时可能更需要 SSA 去筛噪而另一些帧中目标边界模糊但上下文关系比较重要这时 DSA 的作用就更突出。为了解决这个问题AFIA 又加入了自适应融合机制。论文中用两个可学习参数来给两条分支分配权重并通过归一化得到每一支的最终融合系数然后再将两条注意力分支的结果按权重组合并与 (V) 做逐元素作用得到注意力输出论文解释说这样的做法使模型能够根据当前输入的特点动态调整两条分支的重要性。也就是说AFIA 不是固定地“各占一半”而是由网络在训练中自己学会什么时候该更依赖全局上下文什么时候该更激进地去噪。作者还提到这些可学习参数会用对应分支的输出来初始化以增强自适应能力。。2.4 Channel Shuffle不是主角但很关键除了双分支注意力AFIA 还有一个容易被忽略但很实用的设计就是 channel shuffle。论文认为即便有了双分支注意力如果输入特征本身通道交互不足、不同通道学到的内容过于相似那么最终得到的表示仍然可能不够丰富。传统卷积网络里不同通道之间往往会学出重复或冗余的模式。为了解决这一点AFIA 在上分支中加入了 channel shuffle 操作用来打散并重组通道使不同组之间的信息发生交换。具体来说论文给出的上分支形式为其中就表示 channel shuffle先对输入张量按通道分组再重新排列之后接卷积和堆叠的卷积进行特征提取。作者解释说这样做的目的是避免 AFIA 过度依赖某些单一通道促进模型学习更互补、更多样的特征表达而且不会明显增加额外计算开销。2.5 AFIA 的最终输出是怎么得到的AFIA 的最终输出并不复杂它把 channel shuffle 分支得到的特征和 双分支注意力融合后的特征相加得到模块输出从这个结果也能看出AFIA 最终保留下来的并不是单纯的“注意力结果”而是通道重组后的局部卷积特征与自适应注意力增强后的全局/稀疏特征的联合表示。换句话说它希望同时保住两类能力一类是卷积系的局部纹理建模与通道交互能力另一类是注意力系的全局依赖建模和噪声筛除能力。个人总结AFIA 本质上是一个面向动态肠镜场景的特征净化与增强模块。它并不是简单堆叠注意力而是围绕结肠镜图像中常见的运动模糊、镜面高光和复杂背景噪声设计了一套更有针对性的特征处理流程。具体来说DSA 分支负责保留全局上下文和关键语义信息SSA 分支负责抑制低相关区域带来的噪声响应自适应融合机制负责根据输入动态平衡两者的贡献而 channel shuffle 则进一步促进跨通道信息交换提升特征多样性。最终AFIA 在保住有用上下文的同时更有效地滤除了任务无关干扰为后续检测提供了更稳定、更有判别力的特征表示。其效果也在消融实验中得到了明确验证完整 AFIA 相比基线显著提升了 AP 和 F1-score说明这种“全局建模 稀疏筛噪 通道重组”的组合对动态息肉检测是有效的。三、核心代码核心代码的使用方式看章节四import torch import torch.nn as nn import torch.nn.functional as F __all__ [AFIA, C2PSA_AFIA] class ChannelShuffle(nn.Module): def __init__(self, groups): super().__init__() self.groups groups def forward(self, x): b, c, h, w x.size() channels_per_group c // self.groups # reshape x x.view(b, self.groups, channels_per_group, h, w) # transpose x x.transpose(1, 2).contiguous() # flatten x x.view(b, -1, h, w) return x class AFIA(nn.Module): def __init__(self, in_channels, groups4): super().__init__() self.layer_norm nn.LayerNorm(in_channels) # Assuming layer norm is applied over channels self.conv1x1_q nn.Conv2d(in_channels, in_channels, kernel_size1) self.deconv3x3_q nn.ConvTranspose2d(in_channels, in_channels, kernel_size3, stride1, padding1) self.conv1x1_k nn.Conv2d(in_channels, in_channels, kernel_size1) self.deconv3x3_k nn.ConvTranspose2d(in_channels, in_channels, kernel_size3, stride1, padding1) self.conv1x1_v nn.Conv2d(in_channels, in_channels, kernel_size1) self.deconv3x3_v nn.ConvTranspose2d(in_channels, in_channels, kernel_size3, stride1, padding1) self.channel_shuffle ChannelShuffle(groups) self.stacked_conv nn.Sequential( nn.Conv2d(in_channels, in_channels, kernel_size3, padding1), nn.ReLU(inplaceTrue), nn.Conv2d(in_channels, in_channels, kernel_size3, padding1), ) self.conv1x1_out nn.Conv2d(in_channels, in_channels, kernel_size1) self.layer_norm2 nn.LayerNorm(in_channels) def depthwise_spatial_attention(self, Q, K): Calculates the Depthwise Spatial Attention Map between Q and K. Args: Q: Tensor of shape (B, C, H, W) K: Tensor of shape (B, C, H, W) Returns: A spatial attention map with shape (B, H, W) B, C, H, W Q.shape Q Q.permute(0, 2, 3, 1).reshape(B, H * W, C) # B, HW, C K K.permute(0, 2, 3, 1).reshape(B, H * W, C) # B, HW, C attention_map torch.matmul(Q, K.transpose(1, 2)) # B, HW, HW attention_map F.softmax(attention_map / (C ** 0.5), dim-1) # B, HW, HW return attention_map def spatial_wise_self_attention(self, V, attention_map): Apply spatial-wise self-attention to value feature map Args: V: Tensor of shape (B, C, H, W) attention_map: Attention map with shape (B, H, W, HW) Return: weighted V B, C, H, W V.shape V V.permute(0, 2, 3, 1).reshape(B, H * W, C) # B, HW, C weighted_V torch.matmul(attention_map, V) weighted_V weighted_V.reshape(B, H, W, C).permute(0, 3, 1, 2) return weighted_V def forward(self, x): residual x x x.permute(0, 2, 3, 1) # B,H,W,C x self.layer_norm(x).permute(0, 3, 1, 2) # B,C,H,W # Q branch Q self.conv1x1_q(x) Q self.deconv3x3_q(Q) # K branch K self.conv1x1_k(x) K self.deconv3x3_k(K) # V branch V self.conv1x1_v(x) V self.deconv3x3_v(V) # Channel Shuffle x self.channel_shuffle(x) # DSA attention_map self.depthwise_spatial_attention(Q, K) # SSA out self.spatial_wise_self_attention(V, attention_map) # Apply weights out F.relu(out) # 1x1 Conv out out self.conv1x1_out(out) # Add and output out out self.stacked_conv(x) out out residual out out.permute(0, 2, 3, 1) out self.layer_norm2(out).permute(0, 3, 1, 2) return out def autopad(k, pNone, d1): # kernel, padding, dilation Pad to same shape outputs. if d 1: k d * (k - 1) 1 if isinstance(k, int) else [d * (x - 1) 1 for x in k] # actual kernel-size if p is None: p k // 2 if isinstance(k, int) else [x // 2 for x in k] # auto-pad return p class Conv(nn.Module): Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation). default_act nn.SiLU() # default activation def __init__(self, c1, c2, k1, s1, pNone, g1, d1, actTrue): Initialize Conv layer with given arguments including activation. super().__init__() self.conv nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groupsg, dilationd, biasFalse) self.bn nn.BatchNorm2d(c2) self.act self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity() def forward(self, x): Apply convolution, batch normalization and activation to input tensor. return self.act(self.bn(self.conv(x))) def forward_fuse(self, x): Perform transposed convolution of 2D data. return self.act(self.conv(x)) class PSABlock(nn.Module): def __init__(self, c, attn_ratio0.5, num_heads4, shortcutTrue) - None: Initializes the PSABlock with attention and feed-forward layers for enhanced feature extraction. super().__init__() self.attn AFIA(c, 4) self.ffn nn.Sequential(Conv(c, c * 2, 1), Conv(c * 2, c, 1, actFalse)) self.add shortcut def forward(self, x): Executes a forward pass through PSABlock, applying attention and feed-forward layers to the input tensor. x x self.attn(x) if self.add else self.attn(x) x x self.ffn(x) if self.add else self.ffn(x) return x class C2PSA_AFIA(nn.Module): C2PSA module with attention mechanism for enhanced feature extraction and processing. This module implements a convolutional block with attention mechanisms to enhance feature extraction and processing capabilities. It includes a series of PSABlock modules for self-attention and feed-forward operations. Attributes: c (int): Number of hidden channels. cv1 (Conv): 1x1 convolution layer to reduce the number of input channels to 2*c. cv2 (Conv): 1x1 convolution layer to reduce the number of output channels to c. m (nn.Sequential): Sequential container of PSABlock modules for attention and feed-forward operations. Methods: forward: Performs a forward pass through the C2PSA module, applying attention and feed-forward operations. Notes: This module essentially is the same as PSA module, but refactored to allow stacking more PSABlock modules. def __init__(self, c1, c2, n1, e0.5): Initializes the C2PSA module with specified input/output channels, number of layers, and expansion ratio. super().__init__() assert c1 c2 self.c int(c1 * e) self.cv1 Conv(c1, 2 * self.c, 1, 1) self.cv2 Conv(2 * self.c, c1, 1) self.m nn.Sequential(*(PSABlock(self.c, attn_ratio0.5, num_headsself.c // 64) for _ in range(n))) def forward(self, x): Processes the input tensor x through a series of PSA blocks and returns the transformed tensor. a, b self.cv1(x).split((self.c, self.c), dim1) b self.m(b) return self.cv2(torch.cat((a, b), 1)) if __name__ __main__: # Generating Sample image image_size (1, 64, 240, 240) image torch.rand(*image_size) # Model mobilenet_v1 C2PSA_AFIA(64, 64) out mobilenet_v1(image) print(out.size())四、添加方法下面的步骤如果你不会或者不想麻烦操作可以联系作者获得本专栏添加所有项目文件的源代码可直接训练.4.1 修改一第一还是建立文件我们找到如下ultralytics/nn文件夹下建立一个目录名字呢就是Addmodules文件夹4.2 修改二然后在Addmodules文件夹内建立一个新的py文件将本文章节三中的“核心代码复制粘贴进去。4.3 修改三第二步我们在该目录下创建一个新的py文件名字为__init__.py然后在其内部导入我们的文件如下图所示。4.4 修改四第三步我门中到如下文件ultralytics/nn/tasks.py进行导入和注册我们的模块(此处只需要添加一次即可如果你用我其它的改进机制这里的步骤只需要添加一次)4.5 修改五在ultralytics/nn/tasks.py文件内的parse_model方法函数内位置大概在1500行左右按照图示位置添加即可此处需要自己有一定的判别能力如果不会可联系作者获得视频教程。4.6 修改六在ultralytics/nn/tasks.py文件内的parse_model方法函数内位置大概在1550行左右按照图示位置添加即可此处一定要对应好位置和缩进否则很容易报错。elif m in {此处填写本章代码的名字.}: c2 ch[f] args [c2, *args]五、正式训练5.1 yaml文件5.1.1 yaml文件1训练信息YOLO26-C2PSA-AFIA summary: 265 layers, 3,259,292 parameters, 3,259,292 gradients, 6.4 GFLOPs# 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 # Parameters nc: 80 # number of classes end2end: True # whether to use end-to-end mode reg_max: 1 # DFL bins scales: # model compound scaling constants, i.e. modelyolo26n.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 GFLOPs s: [0.50, 0.50, 1024] # summary: 260 layers, 10,009,784 parameters, 10,009,784 gradients, 22.8 GFLOPs m: [0.50, 1.00, 512] # summary: 280 layers, 21,896,248 parameters, 21,896,248 gradients, 75.4 GFLOPs l: [1.00, 1.00, 512] # summary: 392 layers, 26,299,704 parameters, 26,299,704 gradients, 93.8 GFLOPs x: [1.00, 1.50, 512] # summary: 392 layers, 58,993,368 parameters, 58,993,368 gradients, 209.5 GFLOPs # YOLO26n backbone 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]] - [-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_AFIA, [1024]] # 10 # YOLO26n head head: - [-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, Conv, [256, 3, 2]] - [[-1, 13], 1, Concat, [1]] # cat head P4 - [-1, 2, C3k2, [512, True]] # 19 (P4/16-medium) - [-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) - [[16, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5)5.1.2 yaml文件2训练信息YOLO26-Att-AFIA summary: 273 layers, 2,707,676 parameters, 2,707,676 gradients, 8.4 GFLOPs# 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 # Parameters nc: 80 # number of classes end2end: True # whether to use end-to-end mode reg_max: 1 # DFL bins scales: # model compound scaling constants, i.e. modelyolo26n.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 GFLOPs s: [0.50, 0.50, 1024] # summary: 260 layers, 10,009,784 parameters, 10,009,784 gradients, 22.8 GFLOPs m: [0.50, 1.00, 512] # summary: 280 layers, 21,896,248 parameters, 21,896,248 gradients, 75.4 GFLOPs l: [1.00, 1.00, 512] # summary: 392 layers, 26,299,704 parameters, 26,299,704 gradients, 93.8 GFLOPs x: [1.00, 1.50, 512] # summary: 392 layers, 58,993,368 parameters, 58,993,368 gradients, 209.5 GFLOPs # YOLO26n backbone 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]] - [-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 head head: - [-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, Conv, [256, 3, 2]] - [[-1, 13], 1, Concat, [1]] # cat head P4 - [-1, 2, C3k2, [512, True]] # 19 (P4/16-medium) - [-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) - [16, 1, AFIA, []] # 23 # - [19, 1, AFIA, []] # 24 # - [22, 1, AFIA, []] # 25 # 此处的使用说法注释: 其中上面的三个注意力机制目前仅使用了23层如果你想使用24层那么就取消掉代码注释 # 并将下面检测头中的19改为24,如果想使用第25层注意力机制同理将下面检测头中的22改为25即可。 # 此处用法比较复杂如过不会联系Snu77博主获取视频教程 - [[23, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5)5.2 训练代码大家可以创建一个py文件将我给的代码复制粘贴进去配置好自己的文件路径即可运行。import warnings warnings.filterwarnings(ignore) from ultralytics import YOLO if __name__ __main__: model YOLO(模型配置文件地址,也就是5.1你保存到本地文件的地址) # 如何切换模型版本, 上面的ymal文件可以改为 yolo26s.yaml就是使用的26s, # 类似某个改进的yaml文件名称为yolo26-XXX.yaml那么如果想使用其它版本就把上面的名称改为yolo26l-XXX.yaml即可改的是上面YOLO中间的名字不是配置文件的 # model.load(yolo26n.pt) # 是否加载预训练权重,科研不建议大家加载否则很难提升精度 model.train( datar数据集文件地址, # 如果大家任务是其它的ultralytics/cfg/default.yaml找到这里修改task可以改成detect, segment, classify, pose cacheFalse, imgsz640, epochs20, single_clsFalse, # 是否是单类别检测 batch16, close_mosaic0, workers0, device0, optimizerMuSGD, # using SGD/MuSGD # resume, # 这里是填写last.pt地址 ampTrue, # 如果出现训练损失为Nan可以关闭amp projectruns/train, nameexp, )5.3 训练过程截图五、本文总结到此本文的正式分享内容就结束了在这里给大家推荐我的YOLOv26改进有效涨点专栏本专栏目前为新开的平均质量分98分后期我会根据各种最新的前沿顶会进行论文复现也会对一些老的改进机制进行补充如果大家觉得本文帮助到你了订阅本专栏关注后续更多的更新~专栏链接YOLOv26有效涨点专栏包含Conv、注意力机制、主干/Backbone、损失函数、优化器、后处理等改进机制