GroundingDINO 零样本目标检测实战:不重新训练,用一句话框出图中任意物体
【免费下载链接】GroundingDINO[ECCV 2024] Official implementation of the paper "Grounding DINO: Marrying DINO with Grounded Pre-Training for Open-Set Object Detection"项目地址: https://gitcode.com/GitHub_Trending/gr/GroundingDINO
GroundingDINO 是一个文本引导的零样本目标检测模型(零样本——指不用针对新类别再训练),输入一句描述就能框出图里对应的东西。这篇文章会讲清楚它的原理和实测成绩,并给你一套本地部署的三步流程和常见的调参建议,看完你就能在自己的图片上跑起来。
先看效果
就这张普通的猫狗合照,你不用提供任何训练数据,只要给出 "cat . dog . " 这样的提示词,模型就能把猫和狗分别用边框圈出来。它甚至能理解 "left dog"(左边的狗)、"black cat"(黑猫)这种带修饰的描述。仓库里的demo/目录提供了单图推理、COCO 评测和 Gradio 网页版多种入口,想自己试的话可以直接照着改提示词。
为什么值得试
传统检测器只认训练时见过的类别:
- 想加新类别?重新标数据、重新训练,成本不低
- 封闭集之外基本失灵,换个场景就掉得厉害
- 只能按类别名查询,没法用自然语言指认(比如 "举着奖杯的那个人")
- 文本和图像是两套体系,想对齐得自己想办法
GroundingDINO 把这四件事一次解决:类别由语言定义,理解由模型直接完成,不需要你为某个具体任务再训一次模型。
它是怎么做到的
这张图看着模块多,实际就三步。
第一步,两路特征各走各的。文本走 BERT 编码器变成语义向量,图像走 Swin Transformer 主干提取多尺度视觉特征。到这一步,两边还互不认识。
第二步,双向对齐。特征增强层用交叉注意力让文本和图像互相"看一眼":文本特征去关注图像区域,图像特征也反过来关注描述词。经过这一层,"cat"这个词开始知道猫大概在画面哪里。
第三步,解码出框。跨模态解码器默认产生 900 个候选框,每个框都会和提示词里的每个词算一个匹配分数。推理时你看两个阈值就行:box_threshold(默认 0.35)过滤掉位置没把握的框,text_threshold(默认 0.25)决定哪些词配得上作为标签。想只看某几个词的结果,把另外两个阈值调高即可。
实测数据
先看 COCO 上的成绩(表来自仓库 .asset/COCO.png,数值可直接引用):
| 模型 | 主干 | 零样本 AP | 微调 AP |
|---|---|---|---|
| GLIP-T | Swin-T | 46.7 | 55.1 |
| DINO | Swin-T | 46.2 | 56.9 |
| GroundingDINO-T | Swin-T | 48.4 | 57.2 |
| GroundingDINO-L | Swin-L | 52.5 | 63.0 |
零样本意味着提示词只有物体名,训练也没碰 COCO,52.5 AP 已经超过了用 COCO 完整训练过的一些封闭集检测器;微调后 63.0 AP,在当年是同类工作的最好水平之一。
再看 ODinW——一个覆盖大量不同领域的开放集基准,更能体现"换场景不塌"的能力:
| 设置 | 对比模型 | GroundingDINO 成绩 |
|---|---|---|
| 零样本 | GLIP-T 19.6 / DetCLIP 24.9(平均 AP) | 22.3(T)/ 26.1(L) |
| 少样本 | DINO-Swin-T 41.2 / GLIP-T 38.9 | 46.4(T) |
| 全样本 | DINO-Swin-T 66.7 / GLIP-T 62.6 | 70.7(T) |
点评一句:少样本和全样本两档上 T 版就超过 DINO 和 GLIP,说明它在"见过一点数据"和"完全没见过"之间切换得很平滑,不会一微调就退化成普通检测器。
三步上手
第一步:克隆仓库
git clone https://gitcode.com/GitHub_Trending/gr/GroundingDINO第二步:装依赖、下权重
cd GroundingDINO pip install -e . mkdir weights && cd weights wget -q https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha/groundingdino_swint_ogc.pth cd ..注意:有 GPU 的话先确认echo $CUDA_HOME有输出,装完跑起来如果报NameError: name '_C' is not defined,十有八九是 CUDA 环境没配对,重新走一遍安装即可。纯 CPU 机器可以在推理命令后加--cpu-only。
第三步:跑通第一张图
CUDA_VISIBLE_DEVICES=0 python demo/inference_on_a_image.py \ -c groundingdino/config/GroundingDINO_SwinT_OGC.py \ -p weights/groundingdino_swint_ogc.pth \ -i .asset/cat_dog.jpeg \ -o out \ -t "cat . dog ."跑完在out目录里就能看到带框的图。不想走命令行,也可以用demo/gradio_app.py起一个网页版,直接拖图上传。想在代码里调用的话,核心就是 groundingdino/util/inference.py 里的load_model和predict两个函数,README 里有一整段调用示例可以抄。
避坑与调优速查
| 场景 | 建议 |
|---|---|
| 显存不够(约 8GB 以下) | 选 Swin-T 权重,默认推理已足够;大分辨率输入时优先降尺寸而不是硬扛 |
| 想要更高精度、显存宽裕(约 6GB+) | 换 Swin-B 配置groundingdino/config/GroundingDINO_SwinB_cfg.py |
| 框太多太杂 | 调高box_threshold(0.35 → 0.45);标签不对就调text_threshold |
| 只想要句子里的某个词 | 提示词写成短句,用--token_spans指定词的位置,或代码里按词过滤 |
| 提示词写法 | 多个类别用.分隔,例如 "person . car . traffic light",比写成一句话更稳 |
| 批量推理 | 统一缩放到 800×1333,避免反复 resize 放大;predict内部已有torch.no_grad,别在外面套训练逻辑 |
| CPU 机器 | 加--cpu-only,速度慢但能跑,适合验证流程 |
两个阈值是日常最常动的旋钮:box_threshold管"框稳不稳",text_threshold管"标签准不准",建议从 0.35 / 0.25 起步微调。
一句话选型
- 想快速验证想法、显存 8GB 以内 → Swin-T 权重就够,别折腾
- 离线批量处理、追求召回和精度 → 上 Swin-B
- 你的任务其实是"固定那几类"且量很大 → 直接微调传统检测器更划算,零样本的优势发挥不出来
写在最后
GroundingDINO 把"检测什么"从训练阶段挪到了提示词里,这一点对数据成本敏感的团队价值很大。它的生态也在往外长——接 SAM 做开放集分割、接 Stable Diffusion 做可控图像编辑(demo/里两个 notebook 就是示例),可以作为不少多模态应用的底座。
<输出文章>
【免费下载链接】GroundingDINO[ECCV 2024] Official implementation of the paper "Grounding DINO: Marrying DINO with Grounded Pre-Training for Open-Set Object Detection"项目地址: https://gitcode.com/GitHub_Trending/gr/GroundingDINO
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考