D-FINE--基于Transformer架构的实时目标检测模型
D-FINE
D-FINE 是一个强大的实时目标检测器,将 DETR 中的边界框回归任务重新定义为了细粒度的分布优化(FDR),并引入全局最优的定位自蒸馏(GO-LSD),在不增加额外推理和训练成本的情况下,实现了卓越的性能。
D-FINE:实时目标检测的“速度与激情”,精准又高效! - 知乎
训练
数据集准备
准备数据集
1 | import json |
创建自定义配置文件
1 | # 单目标 volleyball 实验配置:S 模型 + Objects365 预训练迁移 |
训练
参考51hhh/D-FINE_train: D-FINE 自定义配置训练
-r (resume) 和 -t (tuning)
| -r (resume) | 恢复全部状态:模型权重 + 优化器 + last_epoch + lr_scheduler |
|---|---|
| -t (tuning) | 只加载模型权重,epoch 从 0 开始,优化器全新 |
| -r (resume) | -t (tuning) | |
|---|---|---|
| 模型权重 | 加载 | 加载 |
| 优化器状态 | 恢复 | 全新 |
| last_epoch | 恢复 (=58) | 从 -1 开始 |
| lr_scheduler | 恢复旧状态 | 全新 |
| EMA 状态 | 恢复 | 全新 |
load_tuning_state() line 249-274 的逻辑:
1 | def load_tuning_state(self, path): |
关键:_adjust_head_parameters 只在 num_classes 不同时才调整/丢弃检测头。
注意按照机器核心调整num_workers,以便达到最佳性能。

开始训练
1 | cd D-FINE |
分析和评估
分析
对于单目标排球训练,使用900张少量数据集迁移。
- exp_s_transfer:obj365预训练模型迁移
- exp_s_transfer_obj_aug:obj预训练模型+数据增强
- exp_s_transfer_obj2coco_aug:obj2coco预训练模型+数据增强
1 | `Test/coco_eval_bbox_0`(Precision:AP50:95-all) |

收敛:蓝色曲线的 AP(coco_eval_bbox_0)在大约 60 个 Epoch 前迅速上升,随后进入平台期
红色曲线 exp_s_transfer_obj_aug 前期训练loss抖动,而且AP/AR无法快速上升(后续没啥问题,都能用),疑似数据集过小问题,停止训练。obj 数据集里确实有“排球”这个类别(Class 240),但是COCO 的标注更为精准,且包含大量小目标。obj2coco数据集的质量和多样性更好。(官方说Objects365 预训练模型泛化性最好,其实差不多,感觉Objects365+COCO更好)
无法收敛:橙黄色曲线 exp_s_transferobj365预训练模型,在训练了120Epoch后依旧无法收敛,表明900+数据集过小。
小目标缺失: coco_eval_bbox_3/9(代表 Small 尺寸的 AP/AR)。表示数据集中没有配置好小目标。

Loss 曲线在现代优化器(如 AdamW + Cosine Annealing)的加持下,通常都会表现良好,一般数据集没有问题,不会出现问题。主要查看AP/AR曲线即可。
数据集标注错误问题
标注数据集没有紧密贴合物体,模型无法正确收敛。

预训练模型迁移和从零开始对比
exp_s_transfer_objtococo_aug_2000为在obj2coco模型迁移微调,exp_s_transfer_aug_2000为从零开始训练,收敛需要更长时间。


查询过激活
| 术语 | 含义 |
|---|---|
| Query Over-Activation(查询过激活) | DETR 系列中,预训练的 learned queries 在微调后仍保留对非目标物体的定位能力,导致错误激活 |
| False Activation(假激活) | D-FINE Issue #277 中使用的原词,指模型对非目标物体产生高置信度检测 |
| Objectness-Classification Conflation | 目标性与分类的混淆——单类分类头退化为"是否有物体"而非"是否是目标类别" |
| Class Collapse(类别坍缩) | 多类预训练模型微调为单类后,分类维度坍缩,丧失类别区分能力 |
DETR 系列架构(D-FINE / RT-DETR)
D-FINE 基于 RT-DETR 改进,属于 DETR(DEtection TRansformer)家族。核心架构:
1 | 输入图像 |
- D-FINE 使用 300 个可学习的查询向量(query embeddings)
- 每个 query 在训练过程中"专攻"检测特定位置和类型的物体
- 在 COCO 预训练中,这 300 个 query 学会了定位 80 类物体(人、车、椅子、球…)
- 推理时,每个 query 通过 cross-attention 与图像特征交互,输出一个检测结果
D-FINE输出层(单类)
1 | P(class_i | query_j) = softmax([logit_volleyball, logit_no_object]) |
解决方法:
- 方案 A:空标注图片加入训练Issue #277必须打 Issue #247 补丁防止死锁
- 方案 B:训练策略调整
| 参数 | 当前值 | 建议值 | 说明 |
|---|---|---|---|
| 预训练权重 | Obj365+COCO | 无 / 仅 Objects365 | 单类简单场景从头训更好 |
eos_coefficient |
0.1(默认) | 0.3-0.5 | 增大 no-object 损失权重,抑制假激活 |
num_queries |
300 | 50-100 | 减少 query 数量,降低过激活概率 |
| 学习率 | - | transformer 1e-4, backbone 1e-5 | 过高导致训练崩溃 |
auxiliary_loss |
- | True |
每层 decoder 都加监督,学会正确的目标数量 |
- 方案 C:Denoising 区域负样本
原理:利用 D-FINE 已有的 contrastive denoising 机制,在非目标区域注入负样本,强制 query 学会抑制。不需要额外数据,但需要修改 src/zoo/dfine/denoising.py。
空标注微调
添加空标注图片样本作为负样本。


从左上,右上,左下,右下依次为:
exp_s_finetune_neg_aug exp_s_finetune_neg_objtococo_aug
exp_s_transfer_aug_2000 exp_s_transfer_objtococo_aug_2000

1 | ┌────────────────────────────┬──────────┬────────────┬───────────┬───────────┬───────────┬────────┬────────────┐ |
| FPPI @阈值(False Positives Per Image) | 在置信度阈值下,平均每张背景图的误检数量 |
|---|---|
| Max FP(最大误检置信度) | 所有背景图中,最严重误检的置信度值 |
| Clean @阈值(干净图片比例) | 在置信度阈值下,完全没有任何误检的背景图占比 |
1 | obj365 路线 obj2coco 路线 |
负样本微调有效,效果有限,原因是负样本只有101张,对于2000+数据集太少。
负样本微调让更多 query 的分数集中到 0.3-0.5区间,低置信度误检反而变多了,但高置信度误检减少了
DN随机负样本
在
denoising.py中,在与图片原有目标没有交集的区域随机生成框,将其标签视为背景类参与分类损失
原理:利用 D-FINE 已有的 contrastive denoising 机制,在非目标区域注入负样本,强制 query 学会抑制。不需要额外数据,但需要修改 src/zoo/dfine/denoising.py。
参考51hhh/D-FINE_train at a285f6a7ab2cfa11bb381f0161289e0b4e83f876
- 每张图随机生成有限数量(如 50 个)的框
- 过滤掉与 GT 框重叠的(IoU > 0.3)
- 剩余框标记为 background 类(
class_id = num_classes,即 padding index) - 这些框只参与分类 loss(推向 no-object),不参与回归 loss
- 通过 DN 机制注入训练,无需额外数据


上图为exp_s_obj2coco_neg_d,下图为exp_s_obj2coco_neg_d_q100

1 | ┌───────────────────┬──────────┬──────────┬────────────────┬──────────┬──────────┬────────────────┐ |
neg_d 最优的:
- [email protected] = 0.040(相比基准 1.109 下降 96.4%)
- Clean Image [email protected] = 96%(几乎没有误检)
- Max Confidence = 0.417(远低于其他模型的 0.9+)
- [email protected] = 0.0(零高置信度误检)
边界框质量
D-FINE 将边界框回归重新定义为概率分布的精细化过程,而非直接回归坐标:
传统 DETR:query → [x, y, w, h](4个确定值)
D-FINE: query → [P(x), P(y), P(w), P(h)](4个概率分布)
每个分布有 N 个离散 bin
这使得 D-FINE 的边界框质量更高
评估
主要查看COCO 评估指标能够准确判断模型情况。
D-FINE默认提供了模型在不同 IoU 阈值 和 目标尺寸 下的精度(Precision)和召回率(Recall)等参数。
- IoU (Intersection over Union): 预测框与真实框的重叠度
- AP (Average Precision): 精确率曲线下的面积。
- AR (Average Recall): 召回率,即模型找全目标的能力。
| 术语 | 全称 | 含义 | 预测情况 |
|---|---|---|---|
| TP | True Positive | 真正例 | 模型说是正类,实际也是正类 |
| TN | True Negative | 真负例 | 模型说是负类,实际也是负类 |
| FP | False Positive | 假正例 | 模型说是正类,实际却是负类 |
| FN | False Negative | 假负例 | 模型说是负类,实际却是正类 |
精确率 (Precision)
定义: 在模型所有预测为正类的样本中,真正是对的占比
$$Precision = \frac{TP}{TP + FP}$$
高精确率 (High Precision)表示模型检测到10个目标,有9个是正确的,检测精准正确。可能在很有把握才识别,容易漏识别,即低Recall
召回率 (Recall)
定义: 在所有实际为正类的样本中,模型成功找出的占比
$$Recall = \frac{TP}{TP + FN}$$
高召回率 (High Recall)表示模型在10个真正目标中,检测到9个,很少漏检,可能过于自信,检测到假目标,即低Precision
精确率和召回率往往是此消彼长的(Trade-off),可以使用F1-Score 来平衡这两者
主要查看指标
AP @[ IoU=0.50:0.95 ] :单个类别的平均精度,这是最重要的综合指标。它计算了 IoU 从 0.5 到 0.95(步长 0.05)的平均值:0.5:0.05:0.95
mAP @[ IoU=0.50:0.95 ] :多个类别平均精度的平均值,模型检测各个class的AP的平均。
AP @[ IoU=50/75]:IoU 阈值为 X 时的 AP,预测框和真实框的 IoU > 0.5,就认为它是 TP,较为宽容,而75则更为严格,要求模型的预测框必须与真实框高度重合。
area=small/medium/large 测试集中目标大小得分
可视化
使用 fiftyone可视化。
1 | import json |

手工标注的数据集与实际目标边缘存在较大误差,实测模型识别得更为精准。可以更新数据集,再次训练使得AP继续上升。

可以将图片添加为负样本继续微调。
负样本微调
咕咕咕。。。
部署
咕咕咕。。。







