YOLO26已正式发布

在2025年9月举办的 YOLO Vision 2025 大会上,Ultralytics 就说预期十月份发布YOLO26[1]。

结果跳票了3个月,终于在昨天正式发布出来了。

Ultralytics 发布的上一代YOLO 还是YOLO11,这次直接改名YOLO26,估计是有两方面的考量:

  • ultralytics要推商业化,必然要主导YOLO的命名权,如果还是按照之前的那种习惯,到时候别人又开始发论文占坑(比如YOLO12),这样做彻底把这条路堵死了。
  • 作为一个长期维护的开源项目,学习苹果操作系统的命名模式,估计是打算一年做一次大版本更新,这样做也更有规律和识别度。

当然,和前几代"挤牙膏"式的性能提升略有不同,这次YOLO26比前面YOLO11的提升幅度是略大的,从下面的曲线图也能看出来,在COCO数据集上的性能表现曲线明显变高了。

这一代模型依然是n/s/m/l/x五个型号,性能和速度也比RT-DETR更好。

下面来看看主要的更新亮点。

更新内容概述

根据其博客[1]描述,YOLO26主要有以下内容更新:

  • DFL 移除

    分布焦损 (DFL) 模块虽然有效,但导出过程通常较为复杂,且硬件兼容性有限。YOLO26 完全移除了 DFL,简化了推理过程,并扩展了对边缘计算和低功耗设备的支持。

  • 端到端无 NMS 推理

    与依赖非极大值抑制(NMS)作为独立后处理步骤的传统检测器不同,YOLO26 本身就是端到端的 。它直接生成预测结果,从而降低延迟,使集成到生产系统中更快、更轻量、更可靠。

  • ProgLoss + STAL

    改进的损失函数提高了检测精度,尤其是在小目标识别方面取得了显著改进,这对于物联网、机器人、航空图像和其他边缘应用来说至关重要。

  • MuSGD 优化器

    一种结合了 SGD 和 Muon 的新型混合优化器。受 Moonshot AI 的 Kimi K2 启发,MuSGD 将 LLM 训练中的先进优化方法引入计算机视觉领域,从而实现更稳定的训练和更快的收敛速度。

  • CPU 推理速度提升高达 43%

    YOLO26 专为边缘计算而优化,可提供更快的 CPU 推理速度,确保在没有 GPU 的设备上实现实时性能。

  • 实例分割增强

    引入语义分割损失以改善模型收敛性,并升级了原型模块,利用多尺度信息以获得更优的掩码质量。

  • 精确姿态估计

    集成残差对数似然估计 (RLE) 以实现更准确的关键点定位,并优化解码过程以提高推理速度。

  • 改进的 OBB 解码

    引入专门的角度损失来提高方形物体的检测精度,并优化 OBB 解码以解决边界不连续问题。

细节分析

深扒其开源代码[2],可以对上述内容进行更详细的分析。

NMS替代

在取消NMS之后,实际上是用 TopK 替代 NMS

在 ultralytics/nn/modules/head.py 代码中,可以看到相关代码:

python 复制代码
def postprocess(self, preds):                                                                                       
    """用 TopK 替代 NMS"""                                                                                          
    boxes, scores = preds.split([4, self.nc], dim=-1)                                                               
    scores, conf, idx = self.get_topk_index(scores, self.max_det)                                                   
    boxes = boxes.gather(dim=1, index=idx.repeat(1, 1, 4))                                                          
    return torch.cat([boxes, scores, conf], dim=-1)                                                                 
                                                                                                                    
def get_topk_index(self, scores, max_det):                                                                          
    """选择 Top-K 个最高分的预测"""                                                                                 
    k = max_det                                                                                        
    ori_index = scores.max(dim=-1)[0].topk(k)[1].unsqueeze(-1)                                                      
    scores = scores.gather(dim=1, index=ori_index.repeat(1, 1, nc))                                                 
    scores, index = scores.flatten(1).topk(k)                                                                       
    idx = ori_index[..., index // nc]                                                                               
    return scores[..., None], (index % nc)[..., None].float(), idx 

TopK是通过计算每个目标框的 预测得分,选择得分最高的 max_det 个框。

例如,假设有 1000 个候选框,在推理阶段,通过 TopK 筛选出前300个具有最高置信度的框。

python 复制代码
y = self._inference(preds["one2one"] if self.end2end else preds)                                                
if self.end2end:                                                                                                
    y = self.postprocess(y.permute(0, 2, 1))  # TopK 后处理                                              
return y 

在模型训练的时候,通过一个 One2One分支 来进行一对一的目标匹配,通过这种方式,让模型自身学习如何去除多余的框。

ProgLoss

取缔NMS这步是有点激进的,为此,YOLO26使用了ProgLoss去进行渐进式损失计算,旨在通过在训练过程中逐渐调整不同损失的权重,以帮助模型更有效地学习。

在 ultralytics/utils/loss.py 文件中,E2ELoss 类实现了 ProgLoss 的核心逻辑:

python 复制代码
class E2ELoss:
    def __init__(self, model, loss_fn=v8DetectionLoss):
        self.one2many = loss_fn(model, tal_topk=10)  # 一对多分配,topk=10
        self.one2one = loss_fn(model, tal_topk=7, tal_topk2=1)  # 一对一分配,topk2=1
        
        # 初始权重
        self.o2m = 0.8  # one-to-many 初始权重 80%
        self.o2o = 0.2  # one-to-one 初始权重 20%
        self.final_o2m = 0.1  # one-to-many 最终权重 10%

    def __call__(self, preds, batch):
        loss_one2many = self.one2many.loss(one2many, batch)
        loss_one2one = self.one2one.loss(one2one, batch)
        
        # 加权混合
        return loss_one2many[0] * self.o2m + loss_one2one[0] * self.o2o, ...

    def decay(self, x) -> float:
        """渐进衰减公式"""
        return max(1 - x / max(epochs - 1, 1), 0) * (0.8 - 0.1) + 0.1

翻译一下代码,这个损失的变化如下表所示:

阶段 one2many 权重 one2one 权重 目的
早期 高 (0.8) 低 (0.2) 多正样本快速学习特征
中期 渐减 渐增 平滑过渡,逐步调整模型焦点
后期 低 (0.1) 高 (0.9) 专注一对一精确匹配,减少冗余

ProgLoss 通过在训练的不同阶段调整权重,模型能够在初期专注于广泛学习特征(one-to-many),而在后期聚焦于精确地进行目标匹配(one-to-one)。

STAL

STAL (Small-Target-Aware TAL)是一个针对小目标的改进,核心代码在 ultralytics/utils/tal.py 的 select_candidates_in_gts 函数中:

python 复制代码
def select_candidates_in_gts(self, xy_centers, gt_bboxes, mask_gt, eps=1e-9):
    gt_bboxes_xywh = xyxy2xywh(gt_bboxes)  # 将边界框格式从 (x_min, y_min, x_max, y_max) 转换为 (x_center, y_center, width, height)
    
    # 关键:检测小于最小stride的目标
    wh_mask = gt_bboxes_xywh[..., 2:] < self.stride[0]  # stride[0] = 8,用来检测目标宽高小于stride的目标
    
    stride_val = torch.tensor(self.stride[1], dtype=..., device=...)  # stride[1] = 16,为大目标的stride值
    
    # 关键优化:将小目标的宽高扩展到第二个stride尺度
    gt_bboxes_xywh[..., 2:] = torch.where(
        (wh_mask * mask_gt).bool(),  # 如果是小目标且在mask中,则执行扩展
        stride_val,           # 小目标 → 扩展到16
        gt_bboxes_xywh[..., 2:]  # 其他目标 → 保持原尺寸
    )
    
    gt_bboxes = xywh2xyxy(gt_bboxes_xywh)  # 将修改后的边界框转换回 (x_min, y_min, x_max, y_max) 格式

它的原理是通过将小目标的边界框虚拟扩展到16px,使得小目标能匹配更多的锚点。

例如,原始的小目标尺寸为 6x6 px,而在特征图上,锚点的尺度通常较大(如 stride=8),导致原始的小目标无法匹配足够多的锚点,可能只有一个或者没有匹配的锚点。

虚拟扩展通过扩展小目标的边界框尺寸(将 6x6 px 扩展到 16x16 px),模拟一个较大的目标。这个扩展不是物理上修改目标的尺寸,而是改变了计算过程中的目标尺寸,使得它能够匹配更多的锚点。

扩展后的效果:扩展后的虚拟目标(如 16x16 px)可以与更多的锚点进行匹配,这样就会增加正样本的数量,同时也增强了小目标的学习信号。这样一来,模型就能够更好地识别和学习小目标的特征。

MuSGD

Muon的创新点是通过Newton-Schulz迭代对梯度矩阵进行正交化,从而让收敛速度更加稳定。

MuSGD其实不是纯创新的优化器,而是Muon和SGD的加权混合。

在代码 ultralytics/engine/trainer.py 中,可以看到具体权重。

复制代码
muon, sgd = (0.5, 0.5) if iterations > 10000 else (0.1, 1.0)

翻译一下就是:

条件 muon 权重 sgd 权重
迭代次数 > 10000 (大数据集) 0.5 0.5
迭代次数 ≤ 10000 (小数据集/微调) 0.1 1.0

这样混合是发挥了两者各自的优势:

  • Muon:提供正交化的"探索"方向
  • SGD:提供稳定的更新方向

从权重上看,Muon 只有在大数据集上才会重点使用,对于小样本的数据集来说,作用不明显。

总结

YOLO26 主要的优化倾向是增加小目标的检测性能和优化推理速度,同时,在目标检测领域,YOLO依然是那个SOTA。

参考

1\] https://docs.ultralytics.com/models/yolo26/#overview \[2\] https://github.com/ultralytics/ultralytics

相关推荐
双翌视觉2 小时前
机器视觉引导如何实现机械手的动态抓取
人工智能·数码相机
SEO_juper2 小时前
精准控制爬虫抓取:Robots.txt 核心配置解析与常见避坑指南
人工智能·爬虫·seo·数字营销
友思特 智能感知2 小时前
友思特案例 | 金属行业视觉检测案例一:彩涂钢板卷对卷检测
人工智能·计算机视觉·视觉检测·缺陷检测
Mixtral2 小时前
2026年4款面试记录工具测评:从录音到结构化复盘
人工智能·面试·职场和发展·语音识别·语音转文字
得一录2 小时前
Android AIDL 在智能体和IOT设备中的使用
android·人工智能·物联网·aigc
人工干智能2 小时前
KFold时,两个关联“编号”的迭代器:`folds.split(...)` 和 `enumerate(...)`
人工智能·机器学习
l1t2 小时前
利用豆包辅助编写数独隐式唯一数填充c程序
c语言·开发语言·人工智能·算法·豆包·deepseek
乐迪信息2 小时前
乐迪信息:智能识别船舶种类的AI解决方案
大数据·网络·人工智能·算法·无人机
2501_920953862 小时前
目前有实力的6S咨询公司推荐
大数据·人工智能