实战:从 10 点标注生成到 Mask R-CNN / PointRend 训练与评估)
Detectron2 点级监督实例分割PointSup实战从 10 点标注生成到 Mask R-CNN / PointRend 训练与评估【免费下载链接】detectron2Detectron2 is a platform for object detection, segmentation and other visual recognition tasks.项目地址: https://gitcode.com/GitHub_Trending/de/detectron2本指南以 Detectron2 仓库内 PointSup 项目 为核心系统讲解点级监督实例分割Pointly-Supervised Instance Segmentation的完整落地路径如何把 COCO 密集掩码标注转换为每个实例仅含 10 个点标签的轻量标注、如何在INPUT.POINT_SUP与INPUT.SAMPLE_POINTS两个关键配置下训练带点级监督的 Mask R-CNN 与隐式 PointRend 掩码头、以及如何用标准评估流程验证模型。读完本文你将掌握 PointSup 从数据准备、配置解读、训练评估到源码级原理的完整知识链可直接在本地复现训练。项目背景为什么需要点级监督PointSup 由 Bowen Cheng、Omkar Parkhi、Alexander Kirillov 提出arXiv:2104.06404核心思想是实例分割不再依赖逐像素的稠密掩码标注而只要求每个实例给出少量点标签——每个点要么属于前景物体标签 1要么属于背景标签 0落在物体边界外的点则被忽略标签 -1。相比逐像素标注点标注成本大幅下降同时仍能驱动掩码分割头训练。在当前仓库中PointSup 以独立项目形式实现于 projects/PointSup包含数据准备脚本、数据集注册逻辑、专用 DatasetMapper、两个点监督掩码头以及配套的训练脚本与配置文件。它复用了 PointRend 项目 的point_sample采样算子可见二者在点级操作上的技术渊源。数据准备生成 COCO 的 10 点标注PointSup 的训练数据仍以 COCO 2017 train 为基础但不使用掩码而是为每个实例采样固定数量的点坐标与点标签。第一步准备 COCO 数据集按 Detectron2 官方流程下载并组织 COCO 数据集并通过环境变量DETECTRON2_DATASETS指向数据集根目录。从 register_point_annotations.py 可以看到PointSup 默认从该环境变量未设置时回退到相对目录datasets查找数据_root os.getenv(DETECTRON2_DATASETS, datasets) register_all_coco_train_points(_root)期望的目录结构为$DETECTRON2_DATASETS/ ├── coco/ │ ├── train2017/ # 训练图片 │ └── annotations/ │ ├── instances_train2017.json # 官方 COCO 标注含 segmentation │ └── instances_train2017_n10_v1_without_masks.json # 生成的点标注第二步生成点标注运行仓库自带的转换脚本为每个实例采样 10 个点python tools/prepare_coco_point_annotations_without_masks.py 10该脚本位于 projects/PointSup/tools/prepare_coco_point_annotations_without_masks.py工作流程如下读取$DETECTRON2_DATASETS/coco/annotations/instances_train2017.json对每个实例的segmentation字段可能是多边形列表、未压缩 RLE 或压缩 RLE统一解码为掩码mask在实例 bbox 内均匀随机采样num_points_per_instance个整数坐标点用掩码查询每个点的前景/背景标签得到point_labels移除segmentation写入point_coords与point_labels输出到新 JSON 文件。脚本的生成逻辑见 get_point_annotations会按instances_train2017_n{n}_v{version}_without_masks.json的命名规则输出文件其中n为每实例点数、version为随机种子版本号。命令行支持第二个可选参数repeat用于生成多份不同随机种子的标注内部通过seed_all_rng(12345)固定随机种子保证可复现见 脚本 main 入口# 生成 n10、3 个不同 seed 版本的标注 python tools/prepare_coco_point_annotations_without_masks.py 10 3数据集自动注册生成后无需手动注册导入point_sup包时register_point_annotations.py 会通过register_coco_instances_with_points自动把coco_2017_train_points_n10_v1_without_masks注册进DatasetCatalog与MetadataCatalog。该注册函数的关键在于第 33 行——用load_coco_json加载 JSON 时显式声明额外字段DatasetCatalog.register( name, lambda: load_coco_json(json_file, image_root, name, [point_coords, point_labels]) )预定义的数据集划分见 _PREDEFINED_SPLITS_COCO默认只注册训练集coco_2017_train_points_n10_v1_without_masks测试仍用标准 COCO 2017 val 的掩码标注进行评测。配置文件解读两个新增开关PointSup 的全部行为由两个配置项控制它们在 point_sup/config.py 中通过add_point_sup_config注入到 cfg配置项默认值含义INPUT.POINT_SUPFalse是否启用点级监督。为True时训练 DataLoader 使用PointSupDatasetMapper掩码头切换为点监督版本INPUT.SAMPLE_POINTS0每轮迭代从每个实例的点集中随机采样的点数。0表示使用该实例全部可用点配置入口位于 train_net.py 的 setup 函数先get_cfg()再依次add_pointrend_config(cfg)为了复用 PointRend 的采样算子与add_point_sup_config(cfg)随后merge_from_file合并用户配置文件。基线配置Mask R-CNN 点监督configs/mask_rcnn_R_50_FPN_3x_point_sup_coco.yaml 基于 Base-RCNN-FPN.yaml关键改动如下_BASE_: ../../../configs/Base-RCNN-FPN.yaml MODEL: WEIGHTS: detectron2://ImageNetPretrained/MSRA/R-50.pkl # ImageNet 预训练权重 MASK_ON: True RESNETS: DEPTH: 50 ROI_MASK_HEAD: NAME: MaskRCNNConvUpsamplePointSupHead # 关键替换点监督掩码头 INPUT: POINT_SUP: True DATASETS: TRAIN: (coco_2017_train_points_n10_v1_without_masks,) # 点标注训练集 SOLVER: STEPS: (210000, 250000) # 3x 学习率衰减节点 MAX_ITER: 270000需要注意MODEL.ROI_MASK_HEAD.NAME从基线的MaskRCNNConvUpsampleHead改为MaskRCNNConvUpsamplePointSupHead这是训练损失从稠密掩码切换到点级交叉熵的开关。点增强变体Point Augmentationconfigs/mask_rcnn_R_50_FPN_3x_point_sup_point_aug_coco.yaml 在基线之上仅增加一行_BASE_: mask_rcnn_R_50_FPN_3x_point_sup_coco.yaml INPUT: SAMPLE_POINTS: 5 # 每轮每实例随机采样 5 个点参与损失计算这就是点增强point augmentation训练时从每个实例的全部点中随机抽取 5 个点等效于对点监督做子采样增强缓解过拟合并提升点使用效率。进阶变体隐式 PointRend 点监督头若希望用更强的 PointRend 掩码头可使用 configs/implicit_pointrend_R_50_FPN_3x_point_sup_point_aug_coco.yaml它继承 PointRend 的 implicit_pointrend_R_50_FPN_3x_coco.yaml并将MODEL.ROI_MASK_HEAD.NAME替换为ImplicitPointRendPointSupHead同时开启POINT_SUP: True与SAMPLE_POINTS: 5。训练一条命令启动按 README 所述使用 8 块 GPU 训练 Mask R-CNN 点增强配置python train_net.py --config-file configs/mask_rcnn_R_50_FPN_3x_point_sup_point_aug_coco.yaml --num-gpus 8命令中的train_net.py即 projects/PointSup/train_net.py它在标准DefaultTrainer基础上只重写了两个钩子build_train_loader当cfg.INPUT.POINT_SUP为真时使用PointSupDatasetMapper(cfg, is_trainTrue)构造 mapper否则回退到默认 mapper见 build_train_loaderbuild_evaluator按MetadataCatalog中的evaluator_type选择COCOEvaluator评估仍然基于 COCO 的标准掩码指标见 build_evaluator。这意味着训练用的是点标注评估用的仍是 COCO 官方掩码标注与标准 mAP 指标指标具有可比性。PointSupDatasetMapper点坐标如何随增强同步变换训练数据管线由 PointSupDatasetMapper 接管它在标准 mapper 之外增加了两点处理像素坐标 → 连续坐标将整数点坐标整体加0.5把离散像素坐标映射到连续坐标空间Heckbert 1990 的像素坐标约定见 dataset_mapper.py点随增强同步变换对每个实例调用transform_instance_annotations其中点坐标通过transforms.apply_coords(point_coords)与图像同步做翻转/缩放等变换变换后落在图像边界外的点其标签被置为-1忽略见 detection_utils.py。此外from_config中明确禁止在点监督下启用裁剪增强CROP.ENABLED会直接抛ValueError见 dataset_mapper.py因为裁剪会破坏点与物体的对应关系。掩码头实现点级损失如何替代稠密掩码损失MaskRCNNConvUpsamplePointSupHeadpoint_sup/mask_head.py 中的MaskRCNNConvUpsamplePointSupHead继承标准MaskRCNNConvUpsampleHead4 层卷积 上采样 1x1 卷积见 configs/Base-RCNN-FPN.yaml 中的POOLER_RESOLUTION: 14差异集中在forward的训练分支# 训练时不再计算稠密掩码损失而是 point_coords, point_labels get_point_coords_from_point_annotation(instances) mask_logits point_sample(x, point_coords, align_cornersFalse) return {loss_mask: roi_mask_point_loss(mask_logits, instances, point_labels)}即先取出每个 proposal 的点坐标与标签用 PointRend 的point_sample在掩码特征图上按坐标采样得到 logits再与点标签计算交叉熵损失。推理分支则与标准头一致直接调用mask_rcnn_inference输出稠密掩码——训练时只见点推理时仍输出完整掩码。ImplicitPointRendPointSupHeadImplicitPointRendPointSupHead继承 PointRend 的ImplicitPointRendMaskHead只覆写了_uniform_sample_train_points它不再从gt_masks采样训练点而是直接返回get_point_coords_from_point_annotation(instances)得到的点与标签见 mask_head.py从而把 PointRend 的自适应点采样替换为使用人工点标注。点坐标的标签语义与框内归一化point_sup/point_utils.py 中的get_point_coords_from_point_annotation完成两项关键转换标签三态0背景、1前景、-1训练时忽略坐标归一化把图像级绝对坐标转换为以 proposal 框为参考的[0,1]×[0,1]归一化坐标凡是落在预测框之外的点其标签一律置为-1忽略见 get_point_coords_from_point_annotation保证损失只受框内点约束。评估加载权重跑 COCO 指标按 README评估与训练共用同一配置文件仅需追加--eval-only并指定权重路径python train_net.py --config-file configs/mask_rcnn_R_50_FPN_3x_point_sup_point_aug_coco.yaml --eval-only MODEL.WEIGHTS /path/to/model_checkpoint评估流程见 train_net.py main会先DetectionCheckpointer.resume_or_load加载权重再调用Trainer.test在 COCO 2017 val 上输出 box 与 mask 的标准 AP 指标若配置了TEST.AUG.ENABLED还会额外叠加 TTA 评估结果。扩展如何接入自有点标注数据要在自定义数据集上使用 PointSup可参照 register_coco_instances_with_points 注册 COCO 格式的点标注 JSON。其约定为每个实例标注包含point_coords形状(P, 2)的整数坐标列表与point_labels长度P的0/1标签列表不需要segmentation字段注册时通过load_coco_json(..., [point_coords, point_labels])声明额外字段之后即可被PointSupDatasetMapper消费。引用规范若在研究中使用了 PointSup请引用原始论文BibTeX 条目见 projects/PointSup/README.mdarticle{cheng2021pointly, title{Pointly-Supervised Instance Segmentation}, author{Bowen Cheng and Omkar Parkhi and Alexander Kirillov}, journal{arXiv}, year{2021} }小结与延伸阅读PointSup 用每实例 N 个点替代稠密掩码通过三个关键组件落地prepare_coco_point_annotations_without_masks.py标注生成、PointSupDatasetMapper点数据管线、MaskRCNNConvUpsamplePointSupHead/ImplicitPointRendPointSupHead点级损失。从仓库实现看训练与推理解耦——训练仅消耗点标签推理仍输出完整掩码且评估全程使用 COCO 标准指标。如需进一步深入建议阅读PointSup 项目目录完整源码PointRend 项目point_sample与隐式掩码头实现configs/Base-RCNN-FPN.yamlPointSup 继承的基线网络结构detectron2/data/dataset_mapper.py标准数据管线对照【免费下载链接】detectron2Detectron2 is a platform for object detection, segmentation and other visual recognition tasks.项目地址: https://gitcode.com/GitHub_Trending/de/detectron2创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考