- 人工智能
- 深度学习
- NLP
- 计算机视觉
- 强化学习
【免费下载链接】google-research
Google Research
本文是 Bëtum Tool 仓库中 SAM 3(Segment Anything Model 3)模块的完整技术指南。该模块面向 Artemis Workshop 的"植物表型视觉提取"任务,利用 SAM 3 的稠密实例分割能力,以文本提示(Prompt)驱动的概念分割(PCS)方式输出像素级掩码,再通过最小/最大坐标提取将其转换为统一的目标检测格式(COCO 边界框),最终用 COCOEval 以 AP@50 单一指标与其他分组(OWL-ViT、YOLO26、DiffusionDet)横向对比。读完本文,你将掌握:SAM 3 在 Bëtum Tool 中的目录结构与执行流程、mask_to_bbox的源码级实现与单元测试验证、端到端推理 Notebook 的分步用法、共享评估入口evaluate_coco的参数语义,以及提示词工程、置信度阈值扫描等关键实验变量。
1. 模块定位:为什么要用分割基础模型做目标检测
models/sam3/README.md明确了本模块的定位:实现SAM 3的稠密实例分割,并构建一条"掩码 → 边界框"的转换管线,以对齐 Workshop 的目标检测评测目标。其核心任务有两类:
- 重推理(heavy inference):直接利用 SAM 3 的零样本能力,对图像中所有匹配提示概念的实例输出掩码;
- 微调掩码解码器(fine-tune mask decoder):冻结图像编码器,只针对掩码解码器进行下游适配,以提升特定农业概念(如"未成熟腰果")的分割质量。
之所以走"分割→检测"路线,是因为在 Bëtum Tool 的整体设计中(见 betum_tool/README.md),四个小组共享同一评测指标AP@50(COCOEval):
| 分组 | 模型 | 技术路线 |
|---|---|---|
| 1 | OWL-ViT | 开放词汇零样本检测 |
| 2 | YOLO26 | 实时监督检测 |
| 3 | SAM 3 | 可提示分割 → 边界框 |
| 4 | DiffusionDet / InstructPix2Pix | 生成式感知 |
因此 SAM 3 组面临的科学问题是:一个以提示驱动的分割基础模型,能否在定位任务上匹敌专门设计的检测模型?为了回答这个问题,模型输出的像素级掩码必须被转换为标准边界框,纳入统一评测框架。
2. 目录结构与交付物
SAM 3 模块遵循"每组只在自己的models/<name>/目录下工作"的约定,目录结构如下(与 README 中声明一致):
betum_tool/models/sam3/ ├── README.md # 本模块说明文档 ├── notebooks/ │ └── template_inference.ipynb # 推理 Colab 模板(端到端管线) ├── scripts/ │ └── masks_to_bboxes.py # SAM 掩码 → COCO 边界框转换 ├── results/ │ └── ablations.md # 每次实验的 AP@50 记录日志 └── tests/ └── masks_to_bboxes_test.py # 转换工具的单元测试各交付物的职责:
- Notebook:可一键在 Google Colab 中打开,覆盖依赖安装、数据下载、HF 认证、推理、评估、阈值扫描、可视化与结果保存全流程(详见第 4 节);
- 脚本:核心转换工具,同时提供"掩码+分数 → COCO 预测条目"的批量接口;
- 消融日志:以 Markdown 表格记录每次运行的 AP@50、提示词集与后处理参数,供组内汇报与跨组对比。
3. Mask → BBox 转换管线:源码与测试印证
README 给出了管线的核心调用方式:
# Extract bounding box from a binary mask from scripts.masks_to_bboxes import mask_to_bbox bbox = mask_to_bbox(binary_mask) # Returns [x_min, y_min, width, height]对应实现位于 betum_tool/models/sam3/scripts/masks_to_bboxes.py(mask_to_bbox,第 36-56 行)。其原理是对二值掩码做两次逐行/逐列投影,找出非零区域的最小/最大行列坐标:
def mask_to_bbox(mask): """Convert a binary mask to COCO-format [x_min, y_min, width, height].""" rows = np.any(mask, axis=1) cols = np.any(mask, axis=0) if not rows.any(): return None # Empty mask y_min, y_max = np.where(rows)[0][[0, -1]] x_min, x_max = np.where(cols)[0][[0, -1]] return [ int(x_min), int(y_min), int(x_max - x_min + 1), int(y_max - y_min + 1), ]实现要点:
- 输入约定:
mask为形状(height, width)的布尔型 NumPy 数组; - 空掩码处理:若某行都不为真(
rows.any()为假),说明掩码为空,返回None而不是一个退化的框——调用方需要显式跳过空掩码; - 闭区间修正(+1):COCO 的
[x_min, y_min, width, height]约定为像素数量,因此宽度计算为x_max - x_min + 1、高度为y_max - y_min + 1,避免相邻像素被少算一格; - 整型输出:坐标全部转为
int,与 COCO JSON 中 bbox 的整数规范一致。
同一文件还提供了批量接口pcs_output_to_coco_predictions(masks, scores, image_id, category_id)(第 59-82 行),它将一组掩码与其置信度分数打包成标准的 COCO 预测字典列表,空掩码自动跳过:
predictions.append({ "image_id": image_id, "category_id": category_id, "bbox": bbox, "score": float(score), })3.1 单元测试验证
配套测试 betum_tool/models/sam3/tests/masks_to_bboxes_test.py 覆盖了四个关键场景,可作为你自行修改转换逻辑时的回归基准:
| 测试用例 | 输入 | 期望输出 | 验证点 |
|---|---|---|---|
test_mask_to_bbox_empty | 10×10 全 False 掩码 | None | 空掩码返回None |
test_mask_to_bbox_single_pixel | 仅(4,5)为 True | [5, 4, 1, 1] | 单像素框 |
test_mask_to_bbox_rectangle | 行 2-4、列 3-6 为 True | [3, 2, 4, 3] | 矩形区域的坐标与尺寸换算 |
test_pcs_output_to_coco_predictions | 两个掩码 + 分数[0.95, 0.85] | 两条含image_id/category_id/bbox/score的预测 | 批量打包与字段完整性 |
注意测试中的断言bbox = [5, 4, 1, 1]再次印证了[x, y, w, h]的坐标在前、宽高在后的 COCO 约定,且"坐标"指像素格索引而非边界坐标。运行测试的方式遵循仓库约定:在仓库根目录执行python -m betum_tool.models.sam3.tests.masks_to_bboxes_test(仓库使用python -m模块化运行方式,见 betum_tool/README.md 的 "Running Scripts" 一节)。
4. 端到端推理:template_inference.ipynb 分步解析
betum_tool/models/sam3/notebooks/template_inference.ipynb 是 README "Quick Start" 指向的核心执行载体。README 给出的三步快速开始为:
- 在 Google Colab 中打开
notebooks/template_inference.ipynb; - 按单元格顺序下载数据、运行 SAM 3 推理、将掩码转换为边界框;
- 在
results/ablations.md中记录你的结果。
Notebook 内部将上述过程细化为 11 个阶段,其中若干关键阶段值得展开:
4.1 环境与数据准备(Setup)
- 安装依赖:
pip install -q transformers torch torchvision pycocotools Pillow matplotlib numpy gdown——注意transformers需要支持Sam3Model/Sam3Processor的版本; - 稀疏克隆仓库:仅拉取
betum_tool目录(git sparse-checkout set betum_tool),避免下载 2GB+ 的 monorepo 代码; - 下载数据集:从 Mendeley Data(数据集
r46c6bpfpf)下载 Coffee & Cashew Nut 数据集压缩包,并用unrar解压,最终验证Cashew/Cashew-Uganda/images与Coffee/Batch1/images结构; - 格式转换:调用共享工具 betum_tool/common/flatten_coffee.py 摊平 Coffee 批次,再调用 betum_tool/common/yolo_to_coco.py 将 YOLO 标注转换为 COCO JSON(
--class_map betum_tool/common/class_map.json --split_ratio 0.8,生成cashew_val.json/coffee_val.json); - GT 可视化:使用 betum_tool/common/visualize_coco.py 的
visualize()抽查验证集标注质量。
4.2 配置变量(Configuration)
Notebook 用一组 Python 变量集中管理实验配置,直接对应 README 的"Key Parameters to Explore"清单,是零样本实验最值得调整的部分:
NUM_EXAMPLES = 4 # 冒烟测试;设为 None 跑全量数据集 DATASET = "cashew" # ["cashew", "coffee"] MODEL_ID = "facebook/sam3" # HuggingFace 门控模型仓库 CONFIDENCE_THRESHOLD = 0.05 # 零样本起步用低阈值,之后调优 SCORE_THRESHOLDS_TO_SWEEP = [0.01, 0.05, 0.1, 0.15, 0.2] TEXT_QUERIES = { "cashew": ["cashew tree", "cashew flower", "premature cashew nut", "unripe cashew nut", "ripe cashew nut", "spoilt cashew nut"], "coffee": ["unripe coffee berry", "ripening coffee berry", "ripe coffee berry", "spoilt coffee berry", "coffee tree"], }关键说明:
TEXT_QUERIES的列表顺序必须与 COCO JSON 中的category_id顺序一一对应(0, 1, 2, ...)。类别映射定义在 betum_tool/common/class_map.json:cashew 为0=tree, 1=flower, 2=premature, 3=unripe, 4=ripe, 5=spoilt;coffee 为0=unripe, 1=ripening, 2=ripe, 3=spoilt, 4=coffee_tree;- 由于数据集中
unripe(咖啡 96.0%)与spoilt(腰果 29.2%)等类别高度不平衡(详见 betum_tool/TECHNICAL_BRIEFING.md),提示词的选择会显著影响哪些概念被"看见"。
4.3 设备选择与模型加载
- 设备选择按
CUDA → MPS(Apple Silicon)→ CPU的优先级自动降级; - 模型加载使用 Transformers 原生接口:
from transformers import Sam3Model, Sam3Processor processor = Sam3Processor.from_pretrained(MODEL_ID) model = Sam3Model.from_pretrained(MODEL_ID).to(device)由于facebook/sam3是门控(gated)模型仓库,必须先完成 Hugging Face 认证:注册账号 → 在模型页申请访问权限 → 生成 Read 权限的 User Access Token → 在 Notebook 中执行notebook_login()。
4.4 推理主循环:PCS 输出与框坐标换算
Notebook 的核心函数run_sam3_native_pcs展示了 SAM 3 原生 PCS 的完整调用链(对每张图、每个文本提示执行):
inputs = processor(images=image, text=prompt_text, return_tensors="pt").to(device) with torch.no_grad(): outputs = model(**inputs) results = processor.post_process_instance_segmentation( outputs, threshold=0.01, # 低阈值先捕捉候选,之后统一扫描 mask_threshold=0.0, target_sizes=inputs.get("original_sizes").tolist(), )[0]results包含三个关键张量:masks(形状[num_objects, H, W])、boxes(形状[num_objects, 4],xyxy 格式)、scores(形状[num_objects])。随后 Notebook 将模型直接输出的 xyxy 框转换为 COCO 的[x1, y1, w, h](w = x2 - x1),这与masks_to_bboxes.py的闭区间换算(+1)是两套并行实现,二者都服务于同一个目标:生成符合 COCO 规范的预测条目{image_id, category_id, bbox, score}。
4.5 统一评估与阈值扫描
评估阶段调用共享封装 betum_tool/common/evaluate.py:
from common.evaluate import evaluate_coco results = evaluate_coco(gt_json=COCO_VAL_JSON, predictions=all_predictions, score_threshold=CONFIDENCE_THRESHOLD) print(f"AP@50 = {results['AP@50']}")从源码看,evaluate_coco(第 147-250 行)的职责包括:
- 灵活的输入形态:
gt_json与predictions均可传路径、Python 列表或COCO实例;predictions为空文件或空列表会给出显式警告并返回全 0 指标; - 阈值过滤:
score_threshold参数在进入 COCOeval 前先做一次score >= threshold的预过滤; - 多维指标:返回值包含
AP(IoU 0.50:0.95 均值)、AP@50、AP@75与逐类别per_class_ap50; - 逐类 AP@50 计算:通过对 COCOeval 的 5 维 precision 张量(维度
[T, R, K, A, M],见_slice_precision_matrix注释)切片,取 IoU=0.50、maxDets最大索引对应的召回维度均值; - 可读报告:
verbose=True时打印带类别名与 AP@50 的格式化汇总表(_print_summary_report)。
Notebook 还实现了 README 强调的置信度阈值扫描:对SCORE_THRESHOLDS_TO_SWEEP中的每个阈值重复调用run_coco_eval,输出"阈值 vs AP@50"汇总表,用于在精度与召回之间寻找平衡点——低阈值召回更多真实实例,高阈值过滤低置信度误检。
5. 评估约定与消融日志
5.1 统一 COCO JSON 评估
README 明确要求:所有预测必须转换为 COCO JSON 格式后进行统一评估:
from shared.evaluate import evaluate_coco results = evaluate_coco(gt_path="path/to/gt.json", pred_path="path/to/predictions.json")(该模块对应的共享实现即 betum_tool/common/evaluate.py,注意实际参数名为gt_json与predictions,二者均支持文件路径。)Notebook 最后一步会把全部预测写入results/{DATASET}_predictions.json,用于跨模型分析与与其他分组做对比评测。
5.2 消融记录规范
betum_tool/models/sam3/results/ablations.md 是实验日志模板,要求"每次运行一行",包含四类信息:
- Results 主表:
Run | Mode | Dataset | Prompts / Config | Confidence Threshold | AP@50 | Notes,模板预置了 4 行zero-shot PCS实验(Cashew/Coffee × baseline/simple 提示词,阈值 0.05); - 提示词工程笔记:按
baseline(如"cashew tree","premature cashew nut")、simple(如"tree","flower","premature")、domain-specific(如"cashew tree foliage","cashew inflorescence","immature cashew nut")三档记录提示词集及其对 AP@50 的影响; - 后处理 / 推理笔记:跟踪
confidence_threshold(默认 0.05)、min_mask_area_pixels、nms_iou_threshold三个参数的变化与效果。
6. 建议探索的参数空间(Key Parameters)
README 在结尾给出了五个实验维度,结合源码与 Notebook 可以进一步明确每个维度的操作含义:
| 参数维度 | 说明 | 在仓库中的落点 |
|---|---|---|
| 提示类型(point / box / text) | SAM 3 支持点、框、文本三类提示;本模块默认走文本 PCS 路线 | run_sam3_native_pcs中processor(images=..., text=...) |
| 每目标点数(number of points per object) | 点提示模式下每实例的采样点数量,影响掩码细节 | 使用点提示时在processor的input_points中配置 |
| 掩码解码器微调(冻结编码器 vs 全量微调) | 冻结图像编码器只训练掩码解码器可降低算力需求,全量微调则适配更强 | 属于"任务"定义的一部分(README Overview),可在models/sam3/下扩展训练脚本 |
| 后处理 NMS | 对提取出的边界框做非极大值抑制,减少同一实例的重复框 | 对应ablations.md中nms_iou_threshold字段 |
| 置信度阈值 | 低阈值起步(0.05)保证零样本召回,再通过扫描找到最优值 | CONFIDENCE_THRESHOLD/SCORE_THRESHOLDS_TO_SWEEP/evaluate_coco(score_threshold=...) |
7. 总结
SAM 3 模块是 Bëtum Tool 统一 AP@50 评测框架下的"分割路线"代表。其核心价值在于:以最小工程代价(mask_to_bbox数十行代码 + 一个 Colab Notebook)把基础分割模型的像素级输出无缝接入目标检测评测体系,使"分割基础模型 vs 检测专用模型"的横向对比成为可能。无论你是要复现零样本 PCS 基线、开展提示词消融,还是尝试冻结编码器的掩码解码器微调,模板推理 Notebook、转换脚本 及其单元测试构成了一个自洽、可验证的起点;而 消融日志 则保证了每个实验结论都能被追溯、对比与沉淀。
- 人工智能
- 深度学习
- NLP
- 计算机视觉
- 强化学习
【免费下载链接】google-research
Google Research
相关推荐
Transformers 中的 Mask Generation(掩码生成):基于 SAM / SAM 2 的分割推理与微调实战
Transformers 中的 Mask Generation(掩码生成):基于 SAM / SAM 2 的分割推理与微调实战 导读 本文讲解 🤗 Trans
前端UI组件设计系统如何用 Detectron2 COCOEvaluator 在自定义 COCO 格式数据集上评估检测与实例分割 AP
如何用 Detectron2 COCOEvaluator 在自定义 COCO 格式数据集上评估检测与实例分割 AP 假设你手上有一个按 COCO 格式标注的验证
人工智能计算机视觉深度学习机器学习Darknet中的实例分割:Mask YOLO实现与配置指南
Darknet中的实例分割:Mask YOLO实现与配置指南 在计算机视觉领域,目标检测技术已广泛应用于各类场景,但仅能提供目标的边界框信息。而实例分割(Ins
人工智能深度学习计算机视觉机器学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考