1. 从分类与定位的纠葛说起GFL到底想解决什么问题做过目标检测的朋友大概率都经历过这样一个阶段模型训练完了mAP看着还行但一到实际部署就发现框的位置总是差那么一点意思尤其是物体边缘、密集场景或者尺度变化剧烈的时候框的抖动特别明显。这个问题在很长一段时间里被认为是“回归精度不够”于是大家拼命调IoU loss、调回归分支的权重但效果始终有限。Generalized Focal LossGFL这篇工作的切入点很有意思它没有直接去改回归的loss形式而是回过头来重新审视了一个更根本的问题分类和定位这两个分支到底应该学什么、怎么学。这个视角的转变是理解GFL整个方法论的钥匙。在GFL之前主流检测器以FCOS、ATSS为代表的做法是分类分支输出一个one-hot式的类别概率定位分支回归一个确定性的坐标值或者距离值。训练时分类用Focal Loss定位用IoU系列loss或者L1/L2。这套范式看起来没什么问题但GFL的作者指出这里面藏着两个被忽视的缺陷。第一个缺陷是分类分支的表达能力被浪费了。一个anchor point或者一个正样本点它对应的ground truth框其实只有一个所以训练目标就是一个one-hot向量。但实际推理时这个点可能落在物体边缘它预测出来的分类分数和定位质量之间往往不一致——分类分数高的框不一定IoU高IoU高的框分类分数又可能被压得很低。这种不一致直接导致NMS阶段会把一些真正的好框给抑制掉。第二个缺陷是定位分支学的是一个“死”的值。传统的回归把框的每条边当成一个确定性的标量来学但实际上物体边界本身就有模糊性。比如一个人的头发边缘、一只鸟的翅膀尖你说它的精确边界在哪里不同标注者画出来的框可能差好几个像素。让网络去拟合一个本身就存在歧义的值本质上是在制造训练噪声。GFL的核心思路就是针对这两个问题分别开出药方用**Quality Focal LossQFL把分类分支从one-hot升级成软标签让分类分数直接携带定位质量信息用Distribution Focal LossDFL**把定位分支从学一个确定值改成学一个分布让网络表达出边界的不确定性。这两个loss合在一起就是Generalized Focal Loss。这里需要强调一点GFL不是一个具体的网络结构而是一套训练策略和loss设计。你可以把它挂到FCOS上、挂到ATSS上、挂到任何anchor-free或者anchor-based的检测器上只要那个检测器有独立的分类和回归分支。这种“即插即用”的特性是GFL在工业界被广泛采用的重要原因。适合读这篇内容的人如果你正在做目标检测的落地项目发现模型mAP还行但实际框的质量不稳定如果你在复现FCOS、ATSS这类anchor-free检测器想进一步提升精度如果你对分类与回归的联合建模感兴趣想理解软标签和分布学习在检测里的具体玩法——那GFL这套东西值得你花时间吃透。2. 拆开GFL的两个核心组件QFL与DFL的设计逻辑2.1 为什么分类分支需要软标签QFL的动机与实现先想清楚一个问题在FCOS这类anchor-free检测器里一个正样本点的分类目标是什么标准做法是这个点落在哪个GT框里就把那个GT的类别设为1其他类别设为0。这是一个硬标签没有任何商量余地。但推理的时候这个点预测出来的分类分数实际上要承担两个职责一是告诉NMS“我是什么类别”二是隐含地告诉NMS“我这个框有多准”。问题在于训练时分类分支只学了第一个职责第二个职责是靠定位分支的IoU来间接体现的。这就导致了分类分数和定位质量之间的错位。QFL的做法很直接把分类标签从硬标签换成软标签这个软标签的值就是该点预测框与GT框的IoU。具体来说对于一个正样本点它的分类目标不再是一个one-hot向量而是一个向量其中对应GT类别的那个位置的值是IoU连续值0到1之间其他类别位置仍然是0。这样一来分类分支在训练时就被迫去学习“我这个点的定位质量有多高”。推理时分类分数本身就携带了质量信息NMS阶段直接按这个分数排序就能同时考虑类别置信度和定位精度。但这里有一个技术难点传统的Focal Loss是为硬标签设计的它的公式是FL(p) -α * (1-p)^γ * log(p) 当标签为1 FL(p) -(1-α) * p^γ * log(1-p) 当标签为0这个公式假设标签只能是0或1。现在标签变成了连续值比如0.73Focal Loss就没法直接用了。QFL的解决方案是把Focal Loss的调制因子进行扩展使其能够处理连续标签。具体推导过程涉及将交叉熵的离散形式推广到连续域最终得到的QFL形式可以理解为对于正样本调制因子是|y - p|^β其中y是软标签IoUp是预测概率。实操心得QFL里的β参数控制调制强度论文里默认取2.0。我在实际项目里试过1.5和2.5发现对于小目标密集的数据集β取1.5左右更稳因为小目标的IoU本身波动大调制太强反而会让网络忽略那些“中等质量”的样本。这个参数没有绝对最优建议在自己的验证集上扫一遍。2.2 定位分支的分布学习DFL如何让框“活”起来传统回归分支的做法是对于框的左边距离l网络直接输出一个标量。训练时用L1或者IoU loss去逼近GT的l值。但前面说了物体边界本身有模糊性让网络去拟合一个确定值等于强迫它忽略这种模糊性。DFL的思路是不要让网络输出一个值而是输出一个分布。具体来说把框的每条边左、上、右、下的距离值离散化成一系列区间比如从0到16分成16个bin每个bin的宽度是1。网络对每条边输出一个长度为16的向量经过softmax之后就是一个概率分布。最终的回归值是这个分布的期望l Σ (i * P(i)) 其中i是bin的索引P(i)是第i个bin的概率这样做的好处是网络可以表达“这条边大概率在7到9之间但8的可能性最大”这种不确定性。对于边界清晰的物体分布会很尖锐对于边界模糊的物体分布会相对平坦。这种表达能力是标量回归给不了的。但DFL的训练目标怎么定如果直接用GT的l值去监督那又回到了拟合确定值的老路。DFL的做法是只监督GT值所在的那两个相邻bin。比如GT的l是7.3那么就让网络去最大化第7个bin和第8个bin的概率具体来说用交叉熵的形式让网络学会把概率质量集中在这两个bin上。最终的期望值自然就会接近7.3。这个设计很巧妙它没有强迫网络去学一个精确值而是让网络学会“GT落在哪个区间附近”然后通过期望来得到连续值。这样既保留了分布的灵活性又保证了回归的精度。注意事项DFL的bin数量和范围是需要根据数据集调的。论文里默认是16个bin范围0到16对于FCOS这种基于point的检测器回归的是到四条边的距离。但如果你的数据集里物体尺度很大比如遥感图像里的飞机、舰船16的范围可能不够需要适当放大。我见过有人直接设成32个bin、范围0到32效果也不错但计算量会上去一点。2.3 QFL与DFL的联合训练GFL的完整形态把QFL和DFL合在一起就是GFL。训练时的总loss是L L_QFL λ0 * L_DFL λ1 * L_GIoU其中L_QFL负责分类分支L_DFL负责定位分支的分布学习L_GIoU是额外的IoU loss用来加速收敛。论文里λ0默认取0.25λ1取2.0。这里有一个细节值得注意DFL只监督GT值相邻的两个bin但最终的回归值是通过期望算出来的。这意味着网络在训练时其实是在学一个“局部”的分布但推理时用的是全局期望。这种训练和推理的“不一致”是有意为之的——它让网络在训练时专注于把概率质量放在正确的位置而不是去拟合一个精确值。另外QFL和DFL之间有一个隐式的协同QFL让分类分数携带IoU信息而IoU的计算又依赖于DFL学出来的分布期望。所以两个loss不是独立的它们在训练过程中会相互影响。实际训练时我建议先让DFL的loss稳定下来大概前几个epoch再观察QFL的收敛情况。如果QFL的loss震荡厉害可以适当降低它的权重。3. 把GFL挂到检测器上实操流程与关键配置3.1 选择基础检测器FCOS还是ATSSGFL本身不限定基础检测器但论文里的实验主要基于FCOS和ATSS。我的建议是如果你是从零开始搭优先选FCOS因为它的结构更干净分类和回归分支完全解耦挂GFL的时候改动最小。如果你已经在用ATSS也可以直接改ATSS的anchor匹配策略和GFL的软标签其实挺搭的。具体来说FCOS的head部分原本是分类分支输出C个通道C是类别数回归分支输出4个通道l、t、r、b四个距离。改成GFL之后分类分支的通道数不变但loss从Focal Loss换成QFL回归分支的通道数从4变成4*1664每条边16个binloss从IoU loss换成DFLGIoU。实操心得回归分支通道数变成64之后参数量会增加一些但推理时的计算量增加很小因为最后只是多了一个softmax和期望计算。我在1080Ti上测过FCOSGFL比原版FCOS的推理时间只多了不到5%但mAP能涨1.5到2个点性价比很高。3.2 数据准备与标注格式的适配GFL对数据格式没有特殊要求标准的COCO格式或者VOC格式都能用。但有一个点需要注意QFL的软标签是IoU而IoU的计算依赖于预测框和GT框。在训练初期预测框还很差IoU普遍很低这时候QFL的软标签会普遍偏小导致分类分支学到的分数整体偏低。这是正常现象随着训练进行IoU会逐渐上升软标签也会变得更合理。另外如果你的数据集里有很多小目标建议在数据增强阶段不要用太激进的裁剪因为小目标被裁掉之后正样本点会急剧减少QFL的软标签会变得很稀疏。我一般用Mosaic增强的时候会把小目标的裁剪概率调低一些或者对小目标做单独的过采样。3.3 训练配置学习率、batch size与loss权重GFL的训练配置和基础检测器基本一致但有几个参数需要微调参数推荐值说明初始学习率0.01SGD或 1e-4Adam比原版FCOS略低因为QFL的梯度更平滑batch size16单卡或 64多卡和原版一致GFL对batch size不敏感QFL的β2.0论文默认值小目标多可降到1.5DFL的bin数16大尺度目标可增到32DFL的λ00.25论文默认值GIoU的λ12.0论文默认值训练时的warmup策略建议保留因为QFL在训练初期软标签不稳定warmup可以让网络先学到一个粗略的定位再逐渐引入QFL的软标签。我一般用500个iteration的warmup学习率从0.001线性升到初始值。常见坑如果你发现训练过程中QFL的loss一直不下降或者下降很慢先检查一下IoU的计算是否正确。有些框架里IoU是在GPU上算的如果GT框的格式和预测框的格式不一致比如一个是xyxy一个是ltrbIoU会算错导致软标签全是0或者全是1。这个坑我踩过排查了半天才发现是格式问题。3.4 推理阶段的改动从分布到框的转换推理时回归分支输出的是4*16的向量需要先对每条边的16个bin做softmax然后计算期望得到l、t、r、b四个距离值。这个过程是纯矩阵运算可以用GPU加速速度很快。分类分支的输出直接就是类别分数不需要额外处理。但有一点需要注意QFL训练出来的分类分数是携带IoU信息的所以NMS的时候可以直接用这个分数排序不需要再乘一个IoU预测值像IoU-Net那样。这也是GFL的一个优势——它把质量信息内化到了分类分数里省去了额外的质量预测分支。实操心得推理时如果发现框的抖动还是比较大可以试一下对DFL的分布做平滑比如用温度系数对softmax的输出做缩放。温度系数大于1会让分布更平坦期望值更稳定小于1会让分布更尖锐期望值更接近最大概率的bin。我一般用1.0但在视频检测这种对时序稳定性要求高的场景里会用1.2左右来减少帧间抖动。4. 实战中遇到的问题与排查思路4.1 QFL的软标签不收敛怎么办这是最常见的问题。表现是训练初期QFL的loss下降很慢或者震荡厉害。排查思路如下第一检查IoU的计算。前面说了格式不一致会导致IoU算错。建议在训练脚本里加一个debug输出打印几个正样本点的IoU值看看是不是在合理范围内0到1之间且分布比较均匀。第二检查正样本点的匹配策略。FCOS用的是center sampling如果一个点被匹配到多个GT框IoU的计算会变得复杂。建议先用最简单的匹配策略只匹配中心点附近的点等QFL稳定了再换更复杂的策略。第三调整QFL的β参数。如果软标签普遍偏小比如大部分IoU都在0.3以下β可以适当降低让调制因子不要那么强。我试过β1.0的情况虽然mAP会掉一点但训练稳定性好很多。4.2 DFL的分布学偏了怎么调DFL的分布学偏的表现是期望值算出来的框和GT框偏差很大或者分布集中在错误的bin上。排查思路第一检查bin的范围和数量。如果你的数据集里物体尺度变化很大固定的bin范围可能覆盖不了。建议统计一下训练集里所有GT框的l、t、r、b的分布然后根据分位数来设定bin的范围。比如95%的l都在0到20之间那bin范围就设0到20bin数设20。第二检查DFL的监督信号。DFL只监督GT值相邻的两个bin如果GT值正好落在bin的边界上比如7.0那相邻的两个bin是6和7还是7和8这个细节不同框架的实现可能不一样建议统一成“左闭右开”或者“左开右闭”避免歧义。第三检查softmax的温度。有些框架在DFL的softmax里加了温度系数如果温度设得不对分布会过于平坦或者过于尖锐。建议先用默认温度1.0等训练稳定了再调。4.3 训练后期mAP不升反降这种情况通常发生在训练的中后期mAP先升到一个峰值然后开始缓慢下降。原因可能是QFL的软标签在训练后期变得过于自信导致分类分数普遍偏高NMS时抑制了太多框。解决方案在训练后期降低QFL的权重或者对软标签做一个clip把IoU限制在0.1到0.9之间避免极端值。我一般会在最后20%的epoch里把QFL的权重从1.0降到0.5同时把软标签的clip范围设成0.05到0.95。这个trick在多个数据集上都有效。4.4 常见问题速查表问题现象可能原因排查方法解决方案QFL loss不下降IoU计算错误打印正样本IoU值检查框格式统一为ltrbQFL loss震荡β参数过大观察软标签分布降低β到1.0-1.5DFL分布学偏bin范围不合适统计GT距离分布调整bin范围和数量训练后期mAP下降软标签过于自信观察分类分数分布clip软标签降低QFL权重推理框抖动大分布过于尖锐观察DFL输出分布提高softmax温度小目标mAP低正样本点太少统计小目标正样本数降低Mosaic裁剪概率独家避坑技巧GFL的训练对随机种子比较敏感同一个配置跑两次可能mAP差0.5个点。建议在最终确定配置之前至少跑3个不同的随机种子取平均值。另外如果你用的是混合精度训练AMPQFL的softmax部分可能会溢出建议把QFL的计算强制转成float32。这个坑我在A100上踩过loss直接变成nan排查了很久才发现是AMP的问题。5. GFL的延展与变体从2D到3D从检测到分割GFL这套思路其实不局限于2D目标检测。它的核心思想——用软标签替代硬标签、用分布替代确定值——可以迁移到很多相关任务上。在三维目标检测里框的边界模糊性问题比2D更严重因为点云的稀疏性导致物体边缘本身就很难界定。已经有一些工作把DFL的思路用到3D框的回归上把每条边的距离离散化成分布然后取期望。效果比直接回归要好尤其是在远处物体和遮挡物体上。在实例分割里mask的边缘同样存在模糊性。有些工作把QFL的思路用到mask的分类上让每个像素的分类分数携带它与GT mask的IoU信息。这样在推理时mask的质量可以直接从分类分数里读出来不需要额外的质量评估分支。在旋转目标检测里角度的回归也可以用DFL来处理。把角度离散化成一系列bin然后学一个分布最后取期望。这样做的好处是避免了角度回归的周期性跳变问题比如359度和1度其实只差2度但直接回归会差358度。我个人在实际项目里的体会是GFL最大的价值不是它涨了多少个点而是它改变了你对检测器训练目标的思考方式。以前我们习惯把分类和回归当成两个独立的任务但GFL告诉我们这两个任务其实可以相互渗透——分类分数可以携带定位质量定位分布可以表达边界不确定性。这种“你中有我、我中有你”的设计思路在别的任务里同样有借鉴意义。最后再分享一个小技巧如果你在复现GFL的时候发现mAP和论文对不上先别急着改代码检查一下你的基础检测器的配置是否和论文一致。GFL论文里的FCOS用的是ResNet-50 backbone训练了24个epoch如果你只训了12个epochmAP差2到3个点是正常的。另外论文里的数据增强用了RandomFlip和MultiScale如果你没开MultiScalemAP也会差一些。这些细节看起来不起眼但往往是复现失败的主要原因。
