124、Decoupled Head 替换 YOLOv11 Detect Head:分类与回归分支分离的完整代码
124、Decoupled Head 替换 YOLOv11 Detect Head:分类与回归分支分离的完整代码
从一次诡异的mAP震荡说起
去年秋天调一个工业检测项目,YOLOv11s在VisDrone上跑得好好的,换到自建数据集后mAP@0.5:0.95从0.52掉到0.47,而且每轮验证的AP值像心电图一样上下跳。排查了数据增强、学习率调度、甚至怀疑是DDP同步bug,最后用torch.jit.trace抓了一下前向图,发现分类和回归分支在最后一层共享了同一个卷积的梯度流——这就是YOLOv11默认耦合头的典型问题:两个任务的特征在深层互相拉扯,导致优化方向冲突。
Decoupled Head(解耦头)不是新东西,YOLOX在2021年就用它把mAP提了2个点以上。但YOLOv11的Detect Head结构更复杂,有DFL(Distribution Focal Loss)和动态标签分配,直接套用YOLOX的代码会崩。这篇文章手把手改一个能跑通、能收敛、能出效果的Decoupled Head,代码全部基于YOLOv11官方源码(ultralytics v8.3+),踩过的坑都标在注释里。
先看YOLOv11原版Detect Head的痛点
YOLOv11的Detect Head在ultralytics/nn/modules/head.py里,核心是Detect类。它的forward方法里,
