基于LIBERO数据集微调GD
测试GroundingDINO等各模型在LIBERO数据集上的表现
本文仅用于提供思路,代码由ai生成,且某些文字部分由ai生成,可能会有不真实的评价,请看官自行分辨理解
文章中的代码和环境在:wamingmo/libero at master
1 | conda env:libero,libero_new,gd_finetune,gd_eval |
一些指标
- mAP@50:IoU ≥ 0.5 时的平均精度均值(主指标)
- mAP@50:95:多 IoU 阈值综合评价(更严格)
- Per-class AP:每类物体的检测精度,发现薄弱类别
- Recall@100:召回率,评估漏检率
- IoU (交并比) ≥ 0.5 的意思是:你画的预测框和真实的物体框,重叠面积超过了一半(50%)。只要达到这个门槛,模型就被认为是“检测成功”了
一些超参数
max_epochs
- 总共训练多少轮(完整遍历训练集的次数)。
- 太小可能欠拟合,太大可能过拟合。
lr(学习率)
- 每次参数更新步长大小。
- 太大:震荡、发散;太小:收敛慢、可能卡住。
batch_size
- 每次迭代喂多少张图。
- 主要受显存限制;越大梯度更平滑,越小噪声更大。
AMP(混合精度)
- 用 FP16/BF16 + FP32 混合训练。
- 优点:省显存、提速;少数情况下数值不稳定。
checkpoint interval
- 每多少个 epoch 存一次模型。
- 间隔小:更安全但占空间;间隔大:省空间但恢复点少。
save_best='coco/bbox_mAP'
- 按验证集
bbox_mAP自动保留最好权重。 - 通常这是最终部署首选。
val_interval
- 每多少个 epoch 做一次验证。
- 更频繁可更早发现过拟合,但会增加时间开销。
将libero的数据集投影到2d生成测试GT–可行
严格说是两者一起用,但“标注哪些物体”更偏向 BDDL/环境对象定义,不是直接从 HDF5 里读现成 2D 框。
具体流程是:
1.从 HDF5 取这一帧的 state 和 image
states、obs来自 HDF5。
2.用 bddl_file + model_xml 重建环境,再把该帧 state 回放进去
- 解析并加载 BDDL。
3.遍历环境中的对象集合来决定“有哪些物体要标注”
env.objects_dict和env.fixtures_dict。
4.再根据该帧状态计算点/框
- 点:3D->2D 投影
- 框:优先分割掩码,失败则点框 fallback。
所以结论:
- “标哪些物体”来源:环境对象定义(由 BDDL/任务环境决定)。
- “这一帧的位置和可见框”来源:HDF5 帧状态回放后的几何/分割结果。
Grounding DINO
之前搜索发现grounding dino有Tiny、Base和Large三种模型,本来准备使用Large模型进行微调,后改为测试任务。
Swin-T/B 是纯粹的“视觉骨干网络”(Backbone),而 Grounding DINO Tiny/Base 是以这些骨干网络为基础构建的“开集目标检测器”。
| 属性 | Swin-T (Tiny) | Swin-B (Base) |
|---|---|---|
| 通道数 (C) | 96 | 128 |
| 层数 (Depths) | [2, 2, 6, 2] | [2, 2, 18, 2] |
| 参数量 (Params) | ~28M | ~88M |
| FLOPs (计算量) | 4.5G | 15.4G |
| 定位 | 移动端/推理速度优先 | 性能优先,适合作为大型检测器的底座 |
| 模型版本 | 视觉骨干网络 (Backbone) | 全模型参数量 (Params) | 权重文件大小 (Disk) | 推理显存占用 (VRAM) | COCO 零样本精度 (AP) |
|---|---|---|---|---|---|
| Grounding DINO Tiny | Swin-T (~28M) | 约 172M | ~660 MB | 约 3GB - 4GB | 48.4 |
| Grounding DINO Base | Swin-B (~88M) | 约 230M - 250M | ~900 MB | 约 6GB - 8GB | 52.5 |
进一步搜索发现官方并没有公布Large模型的pth(模型权重文件),同时发现了GroundingDINO出了1.5和1.6版本,搜索后发现依旧无果(官方没有给出pth文件)可恶的AI,告诉我有新的模型,但是没有说清官方没有公布,我蠢死了,应该早点去官网查看的。。。这告诉我们不能太依赖AI
SAM
SAM 是 Meta (Facebook) 在 2023 年发布的里程碑式模型,全称 Segment Anything Model。
功能:
- 零样本分割: 它不需要针对特定物体(比如专门训练分猫、分车)进行训练。只要你给它一个点(Point)、一个框(Box)或一段文字,它就能把对应的物体从背景中完美地“抠”出来。
- 万物皆可割: 无论是在显微镜下的细胞,还是航拍图里的建筑,它都能识别出边缘。
| 模型版本 | 参数量 (Parameters) | 文件大小 (Checkpoint) | 适用场景 |
|---|---|---|---|
| SAM-B (Base) | 约 94M | ~375 MB | 速度较快,平衡性好 |
| SAM-L (Large) | 约 308M | ~1.2 GB | 精度更高,处理细节更好 |
| SAM-H (Huge) | 约 636M | ~2.4 GB | 性能最强,但计算开销最大 |
| 模型版本 | 参数量 (Parameters) | 速度 (FPS) | 特点 |
|---|---|---|---|
| SAM 2 Tiny | 约 38.9M | ~91 FPS | 极速,适用于移动端或嵌入式 |
| SAM 2 Small | 约 46M | ~85 FPS | 轻量级,性能优于 Tiny |
| SAM 2 Base+ | 约 80.8M | ~64 FPS | 主流选择,兼顾速度与精度 |
| SAM 2 Large | 约 224.4M | ~40 FPS | 视频追踪精度最高,支持复杂背景 |
思路尝试:GD+SAM吐槽之,AI真会说话
| 步骤 | 操作 | 产出的标注格式 |
|---|---|---|
| 第一步 | 输入文字指令(如:”person”, “car”) | - |
| 第二步 | Grounding DINO 扫描全图,画出方框 | VOC / YOLO 格式 (Rectangles) |
| 第三步 | 将方框传给 SAM,提取边缘轮廓 | COCO 格式 / Polygon (Masks) |
如果你只需要画方框(Detection),Grounding DINO 确实够了;但如果你需要的是像素级精度(Segmentation)或者高质量的训练集,SAM 就是不可或缺的。
1.为什么说 Grounding DINO “不够”?
Grounding DINO 只能输出 Bounding Box(边界框)。在自动标注的语境下,它存在两个致命局限:
- 精度粗糙: 边界框是一个矩形,它会包含大量“背景杂质”。比如你标注一只猫,方框里除了猫,还有地板、沙发角。如果你拿这种带杂质的数据去训练高要求的模型,效果会打折扣。
- 无法处理旋转/不规则物体: 如果你要标注一根倾斜的木棒,方框会变得非常大且空旷,完全无法体现物体的真实形状。
2. SAM 的核心作用:从“框”到“形”
SAM 的作用不仅仅是“抠图”,它是将模糊的语义定位转化为精准的几何边界。
- 自动生成 Mask(掩码): SAM 能识别物体的边缘。它可以告诉你哪些像素点属于“猫”,哪些属于“背景”。
- 生成多边形标注(Polygon): 现在的很多高级自动驾驶或工业缺陷检测,需要的不是 x,y,w,h(方框),而是 (x1,y1,x2,y2,…) 这样的一串坐标点。SAM 可以完美生成这种数据。
3. 为什么建立“全套”自动标注系统需要它们结合?
我们可以把这个过程看作**“大脑”与“手术刀”**的配合:
第一步:Grounding DINO (大脑)
- 任务: 读懂你的指令。
- 表现: “主人,我在坐标 [10, 20, 100, 200] 发现了一个红色杯子。”
- 产出: 一个粗略的范围。
第二步:SAM (手术刀)
- 任务: 精细化范围。
- 表现: “收到坐标。我顺着这个范围内的像素边缘切了一圈,发现这个杯子的真实轮廓是下面这 500 个像素点。”
- 产出: 一个完美的抠图(Mask)。
| 如果你的目标是… | 你只需要 Grounding DINO | 你必须结合 SAM |
|---|---|---|
| 训练 YOLO (目标检测) | ✅ 足够了 | ⚠️ 可选(用于提高框的准确度) |
| 训练 Mask R-CNN (实例分割) | ❌ 不行 | ✅ 必须 |
| 抠图/换背景 (AIGC) | ❌ 不行 | ✅ 必须 |
| 制作高精度科研数据集 | ⚠️ 勉强 | ✅ 强烈推荐 |
一句话总结: Grounding DINO 解决了**“在哪儿”的问题,而 SAM 解决了“长什么样”**的问题。
Florence-2
另一个模型
Florence-2 借鉴了大规模语言模型(LLM)的思路:
- 统一表示: 将所有视觉任务(分类、检测、分割、描述等)都统一转化为文本生成任务。
- 输入: 图像 + 文本任务描述(如
<OD>表示目标检测)。 - 输出: 统一的文本流。例如检测任务会输出坐标字符串
[x1, y1, x2, y2],描述任务则输出句子。 - 架构设计: 采用经典的 Transformer 编码器-解码器结构,将视觉特征和文本特征融合后进行推理。
| 版本 | 参数量 (Parameters) | 权重大小 | 适用设备 |
|---|---|---|---|
| Florence-2-base | 0.23B (2.3亿) | ~500 MB | 手机、嵌入式设备、普通 CPU |
| Florence-2-large | 0.77B (7.7亿) | ~1.5 GB | 消费级显卡、高性能实时监控 |
problem
不知道为什么florence-2-large在图中只有一个框,导致无法评估空间理解能力。
仍旧没有解决
Florence-2 在 LIBERO 评测中的方法总报告(中文)
范围:汇总本轮对 Florence-2 物体识别与空间理解评测中使用过的全部方法、参数调整、排障过程与结果。
1.任务目标
- 验证 Florence-2 在 LIBERO 场景下的:
- 物体识别与定位能力(Object + Localization)
- 空间关系理解能力(Spatial relations)
- 判定低分主要来自:模型能力不足,还是提示词/评测流程设置问题。
2. 方法总览(按阶段)
阶段 A:基础 OVD 评测(relaxed / splitmatch / spatialloc)
特点:
- 任务提示为
<OPEN_VOCABULARY_DETECTION>。 - 每图从 GT 构建开放词表。
- 对标签匹配使用 relaxed/canonical 策略(减少命名差异影响)。
观察:
- splitmatch/spatialloc 都表现为每图预测框接近 1,导致空间对数
pair_count=0。
阶段 B:可视化排障(pred_vis_demo)
问题定位:
- 可视化图里框很多,但 JSON 显示
num_pred很少。 - 原因是图里叠加了 GT(绿框)+预测(红框),视觉上“多框”并不等于“多预测”。
阶段 C:提示词消融实验(30 样本)
对比策略:
- OVD raw+canonical 混合词表(不分块)
- OVD canonical-only(不分块)
- OVD canonical-only(
--ovd-chunk-size 4分块)
结论:
- 提示词设计影响非常大。
- raw+canonical 混合词表显著劣化。
- canonical-only 明显提升。
- 分块可提升每图预测框数量,使空间评估从“完全不可评估”向“可评估”迈进。
阶段 D:提示词修正迭代(90 样本)
迭代过程:
- 失败版:在 OVD 提示里加入自然语言指令后缀,导致指令文本泄漏进预测标签,性能下降。
- 最终版:采用结构化简洁词表格式,不附加长自然语言指令。
当前脚本中的最终提示词构造:
- 每图词表拼接方式改为
|分隔(而非冗长自然语言句子)
3. 综合诊断
3.1 哪些是“提示词/流程问题”
- OVD 提示词过长、混入自然语言指令时,模型容易把整段文本污染进标签。
- raw+canonical 同时喂入会增加混淆,导致召回与标签质量下降。
- 可视化若叠加 GT 与预测,容易误判“模型预测很多框”。
3.2 哪些是“模型能力瓶颈”
- 即使提示词优化后,召回仍不高(90 样本最终
R=0.1262)。 - 多实例稳定检出仍不足,导致空间关系可评估样本数非常少(
pair_count仅从 0 提升到 1)。
结论:
- 低分并非单一原因。
- 提示词与流程是“可修复的大头”;修完后模型明显变好。
- 但若目标是“稳定空间推理”,当前 Florence-2 管线仍受多实例召回限制。
4. 后续建议
- 若主要目标是空间理解评测:优先换高召回检测器(或先做检测器蒸馏/微调),再在检测框上做关系计算。
- 若继续使用 Florence-2:
- 保持结构化短提示词(
|词表) - 禁用 raw 词并保留 canonical
- 继续尝试 chunk size(3/4/5)和 merge IoU(0.5/0.6/0.7)网格搜索
测试GT生成
| 功能 | 说明 |
|---|---|
| 采样 HDF5 数据 | 从 LIBERO 数据集中随机抽取视频帧 |
| 重建仿真状态 | 用 MuJoCo 恢复每一帧的 3D 场景状态 |
| 3D→2D 投影 | 将物体中心点从世界坐标投影到图像平面 |
| 生成 BBox 标注 | 支持分割图(instance mask)或点投影两种方式 |
| 输出 COCO 格式 | 生成标准的目标检测数据集格式 |
1 | conda acitvate libero_new |
这个命令是在做一套“LIBERO 图像多物体GT 生成流程”。逐项解释如下:
1 | python3 scripts/sample_libero_objects_gt.py |
- 运行你现在这份脚本。
- 脚本会从 HDF5 抽帧、恢复仿真状态、生成每帧多物体2D标注。
1 | --dataset-root /home/whl/libero/LIBERO/datasets |
- 指定 LIBERO 原始 HDF5 数据根目录。
1 | --dataset-names libero_goal,libero_object,libero_spatial,libero_10 |
- 指定要从哪几个子数据集采样。
- 这里是四个都用上了。
1 | --num-samples 500 |
- 在所有候选帧中随机抽 500 帧(全局随机,不是每个任务固定500)。
- 实际输出可能少于500(例如被 [–require-visible](vscode-file://vscode-app/d:/Microsoft VS Code/0870c2a0c7/resources/app/out/vs/code/electron-browser/workbench/workbench.html) 过滤)。
1 | --bbox-mode segmentation |
- 优先用实例分割掩码生成真实2D外接框(不是点附近小框)。
- 这是你现在想要的“真实bbox”模式。
1 | --fallback-to-point-bbox |
- 当某个物体拿不到有效分割框时,回退到“3D点投影+小框”。
- 回退样本会在标注里标记
bbox_source=point_fallback。
1 | --require-visible |
[–require-visible](vscode-file://vscode-app/d:/Microsoft VS Code/0870c2a0c7/resources/app/out/vs/code/electron-browser/workbench/workbench.html)
- 只保留有可见有效标注的样本。
- 看不到/投影不在图内的不会输出到最终数据集。
1 | --save-vis |
[–save-vis](vscode-file://vscode-app/d:/Microsoft VS Code/0870c2a0c7/resources/app/out/vs/code/electron-browser/workbench/workbench.html)
- 额外保存可视化图(画出框和标签)到
vis/目录,便于人工检查质量。
1 | --output-root /home/whl/libero/finetune_data/florence2_objects_eval |
- 输出目录。
- 主要会生成:
images/:抽样帧图片samples.jsonl:每张图的详细标注(含3D点、2D框、来源等)- [gt_coco.json](vscode-file://vscode-app/d:/Microsoft VS Code/0870c2a0c7/resources/app/out/vs/code/electron-browser/workbench/workbench.html):COCO格式标注
vis/:可视化图(因为你开了 [–save-vis](vscode-file://vscode-app/d:/Microsoft VS Code/0870c2a0c7/resources/app/out/vs/code/electron-browser/workbench/workbench.html))
GD-problem
数据集缺失
1 | 源池里先天缺 5 类,从 balance_report.json 看,缺失的是: |
MUJOCO log问题-配置libero仿真环境
下面只是列一下问题,没有任何价值哈哈哈哈
环境配置问题,去看他们的Readme
去官网看Readme解决了
Lifelong-Robot-Learning/LIBERO: Benchmarking Knowledge Transfer in Lifelong Robot Learning
mit-han-lab/vlash: Real-Time VLAs via Future-state-aware Asynchronous Inference.
1 | Tue Mar 24 16:56:42 2026 |
A.step
1、随机抽取图像帧
1 | conda acitvate libero_new |
2、从中抽取最后的对比测试集(用于base和best的对比)
1 | conda avtivate gd_eval |
3、还原出train集
因为上一步只是生成了train_samples.jsonl文件,并没有抽出相应的img到新的文件夹中,而后面准备训练集的时候需要一个文件夹
1 | conda activate gd_eval |
4、准备训练集
生成训练数据索引,你已有 gt_coco.json 和 images 后,执行:
1 | conda activate gd_finetune |
5、对比测试
6、指标分析
1 | conda activate gd_eval |
7、模型转换
1 | conda activate gd_finetune |
附1.可视化
B.TRAIN
完整微调流程(从 0 到评估)
1.准备环境
创建并激活环境。
运行安装脚本安装
PyTorch、MMDetection、依赖和权重:bash scripts/mmdet_setup.sh如需指定环境和数据目录:
1
GD_ENV=gd_finetune DATASET_DIR=/home/whl/libero/finetune_data/test_obj1 bash scripts/mmdet_setup.sh
2.生成训练数据索引
你已有 gt_coco.json 和 images 后,执行:
python3 scripts/prepare_gdino_finetune_data.py --dataset-dir /home/whl/libero/finetune_data/test_obj1 --train-ratio 0.9 --seed 421
2
3
4
5
6
7
8
9
10
11
12
- 会产出:
`train_annotations.json`
`val_annotations.json`
`dataset_config.json`
3.启动微调
- 用训练脚本:
- ```bash
python3 scripts/train_mmdet_gdino.py --dataset-config /home/whl/libero/finetune_data/pool3_train/mmdet_data/dataset_config.json --work-dir /home/whl/libero/work_dirs/gdino_train_3当前脚本已切到 Swin-B,并使用 MMDetection 的 Swin-B 预训练权重。
4.训练中看什么
终端重点看:
coco/bbox_mAP coco/bbox_mAP_50 coco/bbox_mAP_751
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
- 训练日志和模型输出都在你指定的 work-dir 下。
5.训练产物在哪里
- 在 `work-dir` 下通常会有:
`train_config.py`
`epoch_*.pth`
`best_coco_bbox_mAP_epoch_*.pth(或同义 best 命名)`
`日志文件(含每次验证指标)`
6.怎么判断效果好不好
- 先看 best 的 coco/bbox_mAP 是否高于基线。
- 再看 mAP_50 与 mAP_75 是否同步提升(只升 mAP_50 往往说明定位精度还不够)。
- 最后用 best 权重在验证集或独立测试集跑一次完整评测,确认不是偶然波动。
## C.TEST
使用`mmdet`后端(可以使用`groundingdino`后端):
`best`
```bash
conda run -n gd_eval env PYTHONPATH=/home/whl/libero/scripts
python scripts/eval_gdino_libero.py \
--inference-backend mmdet \
--samples-jsonl /home/whl/libero/finetune_data/pool3_test_base_best/samples.jsonl \
--images-root /home/whl/libero/finetune_data/pool3_test_base_best \
--config-file /home/whl/libero/work_dirs/gdino_train_3/train_config.py \
--checkpoint-path /home/whl/libero/work_dirs/gdino_train_3/best_coco_bbox_mAP_epoch_140.pth \
--box-threshold 0.05 \
--output-json /home/whl/libero/finetune_data/pool3_test_base_best/compare_2-3vs3/gdino_train_3_mmdet_backend.json
base
1 | conda run -n gd_eval env PYTHONPATH=/home/whl/libero/scripts |
--inference-backend mmdet:使用 MMDetection 推理路径(适配你这类微调 checkpoint)。--samples-jsonl:待评测样本清单(每行一个样本,含图像与目标信息)。--images-root:图像根目录,与samples.jsonl里的相对路径拼接。--config-file:模型结构和推理配置文件。这里用微调时配置 [train_config.py](vscode-file://vscode-app/d:/Microsoft VS Code/ce099c1ed2/resources/app/out/vs/code/electron-browser/workbench/workbench.html) 做公平对比。--checkpoint-path:权重文件路径。你分别放 base 与 best90。--box-threshold:框置信度阈值,越低召回越高但误检也可能更多。你设0.05偏召回导向。--output-json:评估结果输出文件。
去重:(挑出train集和test集)
1 | python scripts/build_holdout_from_samples.py \ |
python build_holdout_from_samples.py
运行你新建的脚本:build_holdout_from_samples.py--source-samples finetune_data/holdout_pool/samples.jsonl
输入来源的样本清单(从哪里抽)。
这里是从finetune_data/holdout_pool/samples.jsonl里抽。--num-samples 200
最终抽多少张图。--seed 42
随机种子,保证可复现。相同输入+相同 seed,抽样结果一致。--dedup-mode none
不和训练/验证做排重。
注意:脚本默认仍会避免“输出内部同一帧重复”,除非你再加--allow-duplicate-within-output。--output-root finetune_data/holdout_200_nodedup
输出目录。会生成images、samples.jsonl、gt_coco.json。--exclude-samples是“排除名单”的输入参数。
- 你把一个或多个
samples.jsonl传给它。- 脚本会读取这些文件里的每条样本键:
(hdf5_path, demo_key, frame_idx)。
- 脚本会读取这些文件里的每条样本键:
- 当
--dedup-mode frame时,凡是命中这些键的候选样本都会被跳过。- 结果就是“尽量不和这些已知集合重叠”。
D.tmux+ssh
基础操作流程
- SSH 登录远程服务器
1 | ssh username@remote-server-ip |
- 创建 tmux 会话
1 | # 创建新会话(建议用训练任务命名) |
- 在 tmux 会话中运行训练
1 | # 激活环境(如需要) |
- 分离会话(后台运行)
按 Ctrl + b,然后按 d(detach)
此时你可以安全关闭 SSH 连接,训练继续运行。
- 重新连接查看进度
1 | # 重新 SSH 登录后,重新附加会话 |
E.env save and rebuild
1 | scripts/gd_eval_env_conda.yml |
1.只导包列表(最小化)
1 | # 仅列出conda安装的包 |
重建:
1 | conda create --name new_env --file spec-file.txt |
2.导出 pip 专用格式
1 | # 如果主要用pip管理包 |
重建:
1 | pip install -r requirements.txt |
3.使用 env export(最通用)
1 | # 导出(跨平台兼容) |
F.visualization
单日志,自动选指标:
1 | python scripts/plot_training_curves.py --log-file /home/whl/libero/work_dirs/gdino_train_2_2/20260318_082145/20260318_082145.log |
单日志,只画指定指标:
1 | python scripts/plot_training_curves.py \ |
单日志,排除部分指标:
1 | python scripts/plot_training_curves.py \ |
多日志对比:
1 | python scripts/plot_training_curves.py --compare \ |
J.平衡各个类别的频率
1 | python scripts/rebalance_samples_by_category.py \ |
