ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

GFL实战指南:从Focal Loss到QFL与DFL的工业级目标检测优化

GFL实战指南:从Focal Loss到QFL与DFL的工业级目标检测优化 目标检测这个领域每年都有新东西出来但真正能在工业界落地的改进其实不多。GFLGeneralized Focal Loss算是其中一个——它不是那种刷点的论文而是真正解决了一线工程师天天头疼的问题为什么我的模型分类得分很高但框出来的位置就是不准为什么NMS之后明明该保留的框被滤掉了这些问题的根源都指向了传统目标检测中分类分支和回归分支各自为政的设计缺陷。GFL做的事情就是把这两个分支的监督信号统一起来让模型学到的质量估计真正反映定位精度。我第一次接触GFL是在处理一个密集小目标检测的项目上当时用的还是基于FCOS的架构分类分支用Focal Loss回归分支用IoU Loss训练日志里cls loss降得很漂亮但mAP就是卡在某个点位上不去。后来把分类分支的one-hot标签换成IoU加权的soft label再引入DFL把框的回归从学一个值变成学一个分布效果立竿见影。这篇文章就把GFL的核心机制、代码实现、调参经验和踩过的坑完整地梳理一遍。1. 从Focal Loss到GFL分类分支到底缺了什么1.1 传统Focal Loss的局限性Focal Loss本身是为了解决正负样本极度不平衡的问题设计的公式很简洁FL(p) -α(1-p)^γ log(p)。它的核心思想是让模型把注意力集中在难分类的样本上降低易分类样本的权重。在RetinaNet那篇论文里这个损失函数确实把one-stage检测器的精度拉到了two-stage的水平。但问题在于Focal Loss只关心这个框是不是目标它不关心这个框定位得准不准。在推理阶段NMS依赖分类得分来排序和筛选框如果分类得分不能反映定位质量就会出现一个尴尬的局面一个分类得分0.9但IoU只有0.5的框会排在一个分类得分0.7但IoU有0.85的框前面。NMS一执行好的框反而被抑制掉了。这个问题在密集场景下尤其致命。我做过一个交通监控的项目画面里几十辆车挤在一起传统Focal Loss训练出来的模型分类得分和实际定位质量的相关性很差NMS阈值稍微调高一点就漏检调低一点就重复框。后来分析预测结果发现很多分类得分高的框实际IoU分布非常分散说明模型根本没有学到得分高等于定位准这个映射关系。1.2 质量估计的两种思路针对这个问题学术界主要有两条路线。一条是引入额外的质量估计分支比如IoU-Net、GCNet这些让网络单独学一个预测IoU的分支然后在NMS阶段用这个预测的IoU来加权分类得分。另一条路线就是GFL的思路不增加额外分支直接在分类分支的监督信号里嵌入定位质量信息。GFL的核心洞察是分类分支的输出不应该是一个one-hot的硬标签而应该是一个软标签这个软标签的值就是预测框和真实框之间的IoU。这样一来分类得分天然就携带了定位质量信息推理时直接用分类得分做NMS就能同时考虑分类置信度和定位精度。这个思路听起来简单但实现起来有几个关键问题需要解决。第一个问题是训练初期预测框的IoU波动很大直接用IoU作为软标签会导致训练不稳定。第二个问题是分类分支的输出是离散的类别概率而IoU是连续值如何让分类分支的输出能够表达连续的质量估计第三个问题是回归分支本身也需要改进传统的回归是学一个确定的值但框的边界其实存在模糊性尤其是小目标边界像素的归属本身就不确定。1.3 GFL的整体框架GFL的整体框架可以概括为分类分支用Quality Focal LossQFL监督回归分支用Distribution Focal LossDFL监督。QFL解决的是分类得分和定位质量解耦的问题DFL解决的是框回归的模糊性和不确定性问题。具体来说QFL的标签是IoU加权的soft label损失函数在Focal Loss的基础上做了推广支持连续值的监督。DFL则把框的回归从预测一个值变成预测一个离散的概率分布然后通过积分得到最终的框坐标。这个设计的好处是网络可以表达框边界的不确定性对于模糊边界的目标预测的分布会更平坦对于清晰边界的目标分布会更尖锐。在实际部署中GFL的这些改进几乎不增加推理开销。QFL只是在训练时改变了标签的生成方式推理时分类分支的输出维度不变。DFL虽然把回归分支的输出从4个值变成了4×(reg_max1)个值但通过积分操作后最终输出的还是4个坐标值推理速度的影响可以忽略不计。2. QFL的标签设计IoU加权到底怎么算2.1 软标签的生成逻辑QFL的标签生成是GFL里最容易被忽视但最关键的环节。很多人以为直接把预测框和真实框的IoU拿来当标签就行了但实际上训练初期预测框的质量很差IoU普遍偏低如果直接用这个IoU作为软标签会导致正样本的监督信号太弱模型学不到东西。GFL论文里的做法是用当前预测框和真实框的IoU作为软标签但同时对正样本的选取做了调整。具体来说正样本的选取还是基于中心采样或者ATSS那套逻辑但每个正样本的软标签值不是1而是预测框和真实框的IoU。这个IoU是在训练过程中动态计算的随着训练进行预测框越来越准软标签的值也会逐渐趋近于1。这里有一个细节需要注意软标签的IoU计算是在正样本上进行的负样本的标签还是0。也就是说QFL只改变了正样本的监督信号负样本的处理和Focal Loss一样。这样做的好处是既保留了Focal Loss对负样本的抑制能力又让正样本的监督信号携带了定位质量信息。在实际实现中软标签的生成需要和正样本匹配逻辑配合。以FCOS为例正样本的选取是基于中心度和尺度的每个正样本对应一个真实框。在计算QFL损失时需要先计算预测框和对应真实框的IoU然后用这个IoU作为软标签。如果预测框和真实框的IoU很低说明这个正样本的定位质量很差软标签的值就会很小QFL会降低这个样本的权重让模型把注意力集中在定位质量更好的样本上。2.2 QFL的损失函数推导QFL的损失函数形式是QFL(σ) -|y - σ|^β ((1-y)log(1-σ) y log(σ))其中y是软标签IoUσ是预测的类别概率β是调节因子。这个公式看起来和Focal Loss很像但有几个关键区别。首先Focal Loss的标签是离散的0或1QFL的标签是连续的[0,1]之间的值。其次Focal Loss的调节因子是(1-p)^γQFL的调节因子是|y - σ|^β这个调节因子是根据预测值和标签的差距来动态调整的。当预测值σ接近标签y时|y - σ|^β很小损失被降低这符合Focal Loss降低易分类样本权重的思想。当预测值σ远离标签y时|y - σ|^β很大损失被放大模型会重点关注这些难样本。这个设计比Focal Loss更灵活因为Focal Loss的调节因子只和预测值有关而QFL的调节因子同时考虑了预测值和标签的差距。β的取值需要根据具体任务调整。在GFL论文里β2是一个比较通用的设置。但在实际项目中如果正样本的IoU普遍偏低可以适当降低β让模型不要过度关注那些定位质量很差的样本。我做过一个遥感图像的项目目标尺度差异很大小目标的IoU普遍偏低把β从2降到1.5之后小目标的召回率有明显提升。2.3 正样本匹配的配合调整QFL的效果很大程度上取决于正样本匹配的质量。如果正样本匹配本身就不合理软标签的IoU再准也没用。在GFL的官方实现里正样本匹配用的是ATSSAdaptive Training Sample Selection这个策略的核心思想是根据目标的统计特性自适应地确定正样本的IoU阈值。ATSS的具体做法是对于每个真实框计算所有候选anchor和它的IoU然后计算这些IoU的均值和标准差把均值加标准差作为阈值IoU大于这个阈值的anchor作为正样本。这个策略的好处是对于不同尺度和形状的目标正样本的选取是自适应的不需要手动调IoU阈值。在实际使用中ATSS和QFL的配合需要注意一点ATSS选出来的正样本IoU分布可能比较分散有些正样本的IoU很低。这时候QFL的软标签会把这些低IoU样本的权重降低相当于自动过滤掉了质量差的正样本。这个机制在训练初期特别有用因为训练初期预测框的质量普遍很差如果没有QFL的软标签机制这些低质量正样本会引入大量噪声。3. DFL的分布建模让框回归学会表达不确定性3.1 传统回归的确定性问题传统的框回归是让网络直接预测一个坐标值比如中心点偏移和宽高然后用L1、L2或者IoU Loss来监督。这种做法的假设是每个框的边界是确定的网络只需要学会预测这个确定的值就行了。但实际情况是框的边界往往是不确定的。尤其是小目标边界像素的归属本身就很模糊一个像素的差异可能导致IoU变化很大。另外遮挡、运动模糊、标注误差等因素也会导致框的边界存在不确定性。传统的确定性回归无法表达这种不确定性网络只能学到一个平均的预测值对于模糊边界的目标预测的框往往不够准确。DFL的思路是把框的回归从预测一个值变成预测一个分布。具体来说对于框的每条边网络预测一个长度为reg_max1的离散概率分布然后通过积分得到最终的坐标值。这个分布可以表达边界的不确定性如果分布很尖锐说明网络对边界很确定如果分布很平坦说明网络对边界不确定。3.2 DFL的积分计算与实现细节DFL的积分计算是对于每条边预测的分布是p(i)i从0到reg_max最终的坐标值是sum(i * p(i))。这个计算过程是可微的可以通过反向传播训练。reg_max的取值需要根据数据集的尺度分布来定。在GFL论文里reg_max16是一个比较通用的设置意味着每条边的预测范围是0到16个像素相对于特征图尺度。如果数据集中小目标比较多可以适当减小reg_max让分布更集中在小范围内。如果大目标比较多可以增大reg_max。在实际实现中DFL的损失函数是交叉熵损失监督信号是目标坐标在离散分布上的投影。具体来说对于真实坐标y它落在两个离散值i和i1之间DFL的损失是让网络预测的分布在这两个离散值上的概率尽可能大。这个设计和分类任务里的label smoothing有点像但DFL的监督信号是连续的不是简单的平滑。这里有一个实现上的坑需要注意DFL的积分计算需要保证分布的和为1所以在预测分布之后需要做softmax。另外积分计算时使用的离散值i是整数但真实坐标y是浮点数所以需要做线性插值。在GFL的官方实现里这部分逻辑封装在DistributionFocalLoss类里使用的时候直接调用就行。3.3 DFL在小目标检测中的实际表现小目标检测一直是目标检测的难点DFL在小目标上的表现尤其值得关注。我做过一个对比实验在同一个数据集上分别用传统的L1 Loss和DFL训练其他配置完全一样。结果DFL在小目标上的AP提升了大约3个点在中大目标上的提升不明显。分析原因主要是小目标的边界不确定性更大。对于小目标一个像素的偏移可能导致IoU变化超过10%传统的L1 Loss会让网络学到一个折中的预测值而DFL可以让网络表达这种不确定性预测的分布会更平坦积分后的坐标值更接近真实值的期望。但DFL也不是万能的。如果数据集的标注质量很差框的边界本身就不准DFL学到的分布会非常平坦积分后的坐标值可能偏离真实值。这种情况下需要先清洗标注数据或者用一些标注质量评估的方法过滤掉低质量标注。另外DFL的reg_max设置需要和特征图的尺度匹配。如果reg_max设置得太大分布会过于分散积分后的坐标值精度会下降。如果reg_max设置得太小分布会过于集中无法表达大目标的边界不确定性。在实际项目中我通常会根据数据集中目标尺度的分布用网格搜索的方式确定reg_max的最优值。4. GFL在实际项目中的调参经验4.1 损失权重的平衡策略GFL的损失函数由三部分组成QFL、DFL和GIoU Loss。这三部分的权重需要仔细平衡否则容易出现某个分支主导训练的情况。在GFL的官方配置里QFL的权重是1.0DFL的权重是0.25GIoU的权重是2.0。这个配置在COCO数据集上表现不错但在实际项目中需要根据任务特点调整。如果分类任务比较难比如类别很多、类间差异小可以适当提高QFL的权重让模型更关注分类。如果定位任务比较难比如小目标多、遮挡严重可以适当提高DFL和GIoU的权重。我做过一个工业质检的项目缺陷目标的边界很模糊把DFL的权重从0.25提高到0.5之后定位精度有明显提升。需要注意的是损失权重的调整不是孤立的。提高QFL的权重会间接影响定位分支的训练因为分类得分和定位质量是耦合的。在实际调参时我通常先固定DFL和GIoU的权重调整QFL的权重让分类精度达到一个合理水平然后再调整DFL和GIoU的权重优化定位精度。4.2 学习率和训练周期的配合GFL的训练对学习率比较敏感。因为QFL的软标签是动态变化的训练初期软标签的IoU普遍偏低如果学习率太大模型会过度拟合这些低质量样本。训练后期软标签的IoU逐渐升高如果学习率太小模型收敛速度会很慢。在GFL的官方实现里用的是余弦退火的学习率调度初始学习率0.01最终学习率0.0001。这个配置在COCO上训练36个epoch效果不错。但在实际项目中如果数据集比较小需要适当减小初始学习率避免过拟合。如果数据集比较大可以适当增大初始学习率加快收敛。另外GFL的训练周期需要根据数据集的大小和难度来定。COCO数据集有11.8万张训练图片训练36个epoch是比较合理的。如果数据集只有几千张图片训练36个epoch可能会过拟合通常训练12到24个epoch就够了。我做过一个只有3000张图片的项目训练18个epoch之后验证集精度就开始下降了。4.3 正样本匹配的调优正样本匹配的质量直接影响GFL的训练效果。在GFL的官方实现里用的是ATSS匹配策略这个策略在大多数情况下表现不错但在某些特殊场景下需要调整。如果数据集中小目标比较多ATSS的默认参数可能会导致小目标的正样本太少。这时候可以适当降低ATSS的topk参数让更多的小目标anchor被选为正样本。如果数据集中大目标比较多可以适当提高topk参数避免大目标的正样本过多导致训练不平衡。另外ATSS的候选anchor选取是基于anchor和真实框的IoU如果anchor的尺度设置不合理ATSS的效果会大打折扣。在实际项目中我通常先用k-means聚类分析数据集中目标尺度的分布然后根据聚类结果设置anchor的尺度和长宽比。这个步骤虽然简单但对最终精度的影响很大。5. 踩坑实录GFL训练中常见的异常与排查5.1 损失不收敛的排查链路GFL训练中最常见的问题是损失不收敛表现为QFL或DFL的损失值震荡或者持续上升。遇到这种情况我通常按照以下链路排查。第一步检查软标签的IoU计算是否正确。QFL的软标签是预测框和真实框的IoU如果IoU计算有误比如坐标顺序搞反了软标签的值会完全错误导致QFL的损失异常。排查方法是打印几个正样本的软标签值看是否在合理范围内0到1之间且随着训练进行逐渐增大。第二步检查DFL的积分计算是否正确。DFL的积分是sum(i * p(i))如果softmax的维度搞错了或者积分的范围不对DFL的损失会异常。排查方法是打印几个预测框的分布看分布的和是否为1积分后的坐标值是否在合理范围内。第三步检查损失权重的配置。如果QFL的权重过大分类分支会主导训练DFL和GIoU的损失会被压制导致定位精度上不去。如果DFL的权重过大定位分支会主导训练分类精度会下降。排查方法是分别打印三个损失的值看是否有某个损失明显大于其他两个。第四步检查学习率是否过大。GFL对学习率比较敏感如果学习率过大损失会震荡。排查方法是把学习率降低一个数量级看损失是否变得平稳。5.2 分类得分与IoU相关性差的处理GFL的核心目标是让分类得分和IoU正相关如果训练完之后发现相关性仍然很差说明QFL没有起到应有的作用。这种情况通常有几个原因。第一个原因是软标签的β参数设置不当。如果β太大QFL会过度关注低IoU样本导致分类得分普遍偏低。如果β太小QFL对低IoU样本的抑制不够分类得分和IoU的相关性会变差。排查方法是画一个散点图横轴是分类得分纵轴是IoU看两者的相关性。如果散点图很分散说明β需要调整。第二个原因是正样本匹配的质量太差。如果正样本的IoU普遍很低软标签的值会很小QFL的监督信号会很弱。排查方法是统计正样本的IoU分布如果均值低于0.3说明正样本匹配需要优化。第三个原因是训练周期不够。QFL的软标签是动态变化的需要足够的训练周期才能让分类得分和IoU的相关性建立起来。如果训练周期太短相关性可能还没建立起来就停止训练了。排查方法是延长训练周期看相关性是否提升。5.3 DFL分布坍缩的应对DFL训练中偶尔会出现分布坍缩的问题表现为预测的分布退化成one-hot分布即所有概率集中在一个离散值上。这会导致DFL失去表达不确定性的能力退化成传统的确定性回归。分布坍缩的原因通常是DFL的损失权重过大或者reg_max设置得太小。如果DFL的权重过大网络会过度优化DFL的损失导致分布过于尖锐。如果reg_max太小分布的动态范围不够也容易坍缩。应对方法是适当降低DFL的权重或者增大reg_max。另外可以在DFL的损失里加一个小的熵正则项鼓励分布保持一定的平坦度。这个技巧在GFL的官方实现里没有但在实际项目中很有效。我通常加一个权重为0.01的熵正则项分布坍缩的问题基本不会再出现。6. GFL与其他检测框架的集成实践6.1 在YOLO系列中集成GFLYOLO系列是目前工业界用得最多的检测框架把GFL集成到YOLO里是一个很实际的需求。YOLOv8及之后的版本分类分支用的是BCE Loss回归分支用的是DFLYOLOv8已经内置了DFL所以集成GFL的主要工作是把分类分支的BCE Loss换成QFL。具体做法是在训练时对于每个正样本计算预测框和真实框的IoU用这个IoU作为软标签然后用QFL计算分类损失。负样本的处理和原来一样用BCE Loss。这个改动在YOLOv8的代码里只需要修改损失函数的计算部分不需要改动网络结构。实测下来在YOLOv8上集成QFL之后mAP有大约1到2个点的提升尤其是在密集场景下提升更明显。但需要注意的是YOLOv8的正样本匹配策略和GFL官方实现里的ATSS不完全一样集成QFL时需要确保正样本的IoU计算和匹配逻辑对齐。6.2 在FCOS中集成GFLFCOS是GFL官方实现的基础框架集成GFL相对简单。FCOS的分类分支用的是Focal Loss回归分支用的是GIoU Loss把这两个损失分别换成QFL和DFL就行了。在FCOS中集成GFL需要注意一点FCOS的正样本匹配是基于中心度的每个正样本对应一个真实框。在计算QFL的软标签时需要确保正样本和真实框的对应关系是正确的。另外FCOS的回归分支输出的是距离四个边的偏移量DFL的reg_max需要根据特征图的尺度来设置。实测下来在FCOS上集成GFL之后mAP有大约2到3个点的提升小目标的提升更明显。但训练时间会增加因为DFL的积分计算比传统的回归计算要慢一些。6.3 在DETR类框架中的适配思路DETR类框架和传统的anchor-based框架差异很大GFL的集成需要做一些适配。DETR的分类分支用的是交叉熵损失回归分支用的是L1 Loss而且DETR的匹配是二分图匹配不是基于IoU的。在DETR中集成GFL的思路是在二分图匹配之后对于匹配上的正样本用预测框和真实框的IoU作为软标签替换原来的one-hot标签然后用QFL计算分类损失。回归分支可以保留L1 Loss也可以换成DFL但DFL的积分计算需要适配DETR的回归输出格式。这个适配目前还没有看到成熟的实现主要是因为DETR的训练本身就不太稳定引入QFL的软标签可能会加剧不稳定性。如果要在DETR中尝试GFL建议先用小规模数据集验证确认训练稳定后再扩大规模。7. 一些实战中的零散心得关于GFL的软标签有一个细节值得注意软标签的IoU计算应该用预测框和真实框的IoU而不是用anchor和真实框的IoU。有些实现里为了省事直接用anchor的IoU作为软标签这样会导致软标签和预测框的质量脱节QFL的效果大打折扣。关于DFL的reg_max如果数据集中目标的尺度跨度很大可以考虑用多个reg_max不同尺度的特征图用不同的reg_max。这个技巧在GFL的官方实现里没有但在实际项目中很有效。我通常让浅层特征图用较小的reg_max比如8深层特征图用较大的reg_max比如16这样既能保证小目标的精度又能表达大目标的边界不确定性。关于训练时的数据增强GFL对Mosaic和MixUp这类强增强比较敏感。因为强增强会改变目标的边界导致软标签的IoU计算不准确。在实际项目中我通常会在训练后期关闭Mosaic和MixUp让模型在干净的数据上微调几个epoch这样能提升最终的精度。关于推理时的NMSGFL的分类得分已经携带了定位质量信息所以NMS的阈值可以适当调高。传统的NMS阈值通常是0.5用GFL之后可以调到0.6甚至0.7这样能减少重复框同时不会漏检。这个调整在密集场景下效果特别明显。最后说一个部署时的注意事项GFL的DFL分支在推理时需要做积分计算这个计算在GPU上很快但在一些边缘设备上可能会成为瓶颈。如果部署在算力受限的设备上可以考虑把DFL的积分计算简化比如只取分布的最大值对应的离散值而不是做完整的积分。这样会损失一些精度但推理速度会快很多。
返回列表