MMSegmentation 中的 PointRend:基于点渲染的高效语义分割实现与配置实战指南
发布时间:2026/9/15 20:50:45来源:尧图网络
MMSegmentation 中的 PointRend基于点渲染的高效语义分割实现与配置实战指南【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentationPointRendPoint-based Rendering把图像分割类比为计算机图形学中的渲染过程只在最难判断的边界点位置进行精细预测从而在几乎不增加计算量的前提下显著提升分割边界的锐利度。本文以 MMSegmentation 仓库中 configs/point_rend 目录下的官方实现为主线深入讲解 PointRend 的核心算法原理、PointHead源码实现、完整配置文件解读、训练与测试方法并给出 Cityscapes 与 ADE20K 上的官方基准结果。读完本文你将能够读懂并复现 PointRend 语义分割模型并能在此基础上针对自己的数据集调整参数。PointRend 算法核心把分割当成渲染PointRend 论文《PointRend: Image Segmentation as Rendering》CVPR 2020的核心洞察是语义分割中的逐像素分类与计算机图形学中的渲染存在相似的过采样/欠采样问题——大部分平坦区域的类别是显而易见的真正的难点集中在物体边缘这类高频区域。传统方法为了不丢失边缘细节只能对整个高分辨率特征图做全量计算代价高昂PointRend 则借鉴渲染中的自适应细分adaptive subdivision思想只在少数关键点point上做精细预测这些点由不确定性驱动地自适应选取粗预测coarse prediction负责整体结构点级精细预测负责修正边界通过**迭代细分iterative subdivision**逐步逼近高分辨率输出在保持效率的同时输出锐利的物体边界。因此 PointRend 可以作为一种通用模块叠加在现有 SOTA 分割模型之上同时适用于实例分割与语义分割任务。在 MMSegmentation 中PointRend 的实现采用粗分割头 点精化头的级联cascade结构代码实现集中在 mmseg/models/decode_heads/point_head.py 与 mmseg/models/segmentors/cascade_encoder_decoder.py。整体架构CascadeEncoderDecoder 与双解码头设计PointRend 在 MMSegmentation 中的整体模型结构由基础模型配置 configs/base/models/pointrend_r50.py 定义属于CascadeEncoderDecoder类型配置了num_stages2即两级解码头级联model dict( typeCascadeEncoderDecoder, num_stages2, pretrainedopen-mmlab://resnet50_v1c, backbonedict(typeResNetV1c, depth50, ...), neckdict(typeFPN, in_channels[256, 512, 1024, 2048], out_channels256, num_outs4), decode_head[ dict(typeFPNHead, ...), # 第一级粗分割头 dict(typePointHead, ...) # 第二级点精化头 ], train_cfgdict(num_points2048, oversample_ratio3, importance_sample_ratio0.75), test_cfgdict(modewhole, subdivision_steps2, subdivision_num_points8196, scale_factor2))各组件职责如下组件类型作用backboneResNetV1cR-50/R-101提取多尺度特征输出 4 个 stage 的特征图neckFPN将 4 个尺度特征统一到 256 通道供两个解码头共享decode_head[0]FPNHead粗分割头先输出一个全分辨率或低分辨率的粗 logitsdecode_head[1]PointHead点精化头基于粗预测在不确定点处做精细化分类从 cascade_encoder_decoder.py 的源码可以看到CascadeEncoderDecoder要求decode_head必须是一个长度等于num_stages的 list并在初始化时逐个构建最终以最后一级头的align_corners、num_classes作为整个模型的统一属性。前向与训练流程推理前向encode_decodecascade_encoder_decoder.pyhead[0].forward(x)产出粗 logits随后第 1 级到倒数第 2 级逐个forward(x, out)传递最后由最后一级predict(x, out, img_metas, test_cfg)输出精化结果。训练流程_decode_head_forward_traincascade_encoder_decoder.py每一级解码头都计算自己的损失decode_0、decode_1前缀粗头提供全图监督点头的损失只在被采样到的点位置计算。PointHead 源码解析不确定性、点采样与迭代细分PointHead继承自BaseCascadeDecodeHeadcascade_decode_head.py其关键设计在 mmseg/models/decode_heads/point_head.py 中实现包含四个核心环节。1. 不确定性度量计算每个位置有多难def calculate_uncertainty(seg_logits): top2_scores torch.topk(seg_logits, k2, dim1)[0] return (top2_scores[:, 1] - top2_scores[:, 0]).unsqueeze(1)不确定性被定义为最高类得分与第二高类得分之差point_head.py。差值越小说明该位置在多个类别之间摇摆不定越需要精细预测——这正好对应物体边缘区域。2. 训练时点采样过采样 重要性采样训练时点选择实现在get_points_trainpoint_head.py受train_cfg三个参数控制num_points2048每张图最终用于计算损失的点数oversample_ratio3先随机采样num_points * oversample_ratio个候选点从中选出不确定性最高的部分importance_sample_ratio0.75num_points中 75% 来自不确定性最高的点剩余 25% 为均匀随机点保证边界点与背景点都有覆盖。源码中特别强调见 point_head.py 的注释必须先对候选点处的 logits 采样再计算这些采样点的不确定性如果在粗预测图上先算不确定性再采样会得到错误的结果。训练时loss流程point_head.py为在torch.no_grad()下采样点 → 用point_sample在细粒度特征与粗 logits 上分别采样 → 拼接后经 MLP 预测点 logits → 与 GT 在对应点处的标签计算交叉熵损失并额外记录acc_point点级精度。3. 点级 MLP 分类器细粒度特征 粗特征拼接PointHead用共享的 1D 卷积等价于 MLP对采样点做分类。其forwardpoint_head.py将细粒度点特征point_sample从 FPN 特征中采样与粗预测点特征从上一级 FPNHead 输出中采样沿通道拼接依次通过num_fcs3个全连接层且默认coarse_pred_each_layerTrue即每一层之后都再次拼回粗特征防止细粒度分支的信息在多层传播中被稀释最后经fc_seg1x1 Conv1d输出各类别 logits。4. 测试时迭代细分逐步细化边界测试阶段predictpoint_head.py执行细分-重预测循环受test_cfg控制subdivision_steps2细分迭代次数scale_factor2每次迭代将 logits 上采样 2 倍subdivision_num_points8196每次迭代选取的最不确定点数。流程是将粗 logits 按 2 倍上采样 → 用get_points_test选出该分辨率下不确定性最高的min(height*width, 8196)个点 → 在这批点处用细粒度特征与原始粗特征做精细预测 → 通过scatter_把新预测值写回 logits 对应位置。经过 2 次迭代边界区域的预测被逐步精化而平坦区域保持粗预测结果从而以远低于全分辨率推理的成本获得锐利边界。配置文件逐项解读从 Cityscapes 到 ADE20K基础模型配置configs/base/models/pointrend_r50.py数据预处理器SegDataPreProcessor使用 ImageNet 统计的均值/标准差mean[123.675, 116.28, 103.53]std[58.395, 57.12, 57.375]bgr_to_rgbTrue处理 OpenCV 读图通道顺序pad_val0、seg_pad_val255分别指定图像与分割标签的 padding 值。backboneResNetV1c输出 4 个 stageout_indices(0, 1, 2, 3)contract_dilationTrue配合 FPN 使用。FPN neck输入[256, 512, 1024, 2048]四尺度特征统一输出 256 通道的 4 层金字塔。FPNHead粗头feature_strides[4, 8, 16, 32]对应 FPN 各层相对于原图的下采样倍数channels128dropout_ratio-1表示不使用 dropoutnum_classes随数据集变化Cityscapes 为 19ADE20K 为 150损失为CrossEntropyLossuse_sigmoidFalse即多类 softmax 交叉熵。PointHead精化头in_channels[256]、in_index[0]表示只取 FPN 第 0 层stride4分辨率最高、细节最丰富作为细粒度特征来源num_fcs3、coarse_pred_each_layerTrue如前所述。Cityscapes 训练配置80k 迭代pointrend_r50_4xb2-80k_cityscapes-512x1024.py 继承四份基础配置_base_ [ ../_base_/models/pointrend_r50.py, ../_base_/datasets/cityscapes.py, ../_base_/default_runtime.py, ../_base_/schedules/schedule_80k.py ] crop_size (512, 1024) data_preprocessor dict(sizecrop_size)crop_size(512, 1024)Cityscapes 图像裁剪尺寸同步传给data_preprocessor用于训练时归一化尺寸对齐。学习率调度param_scheduler采用两段式前 200 次迭代用LinearLR以start_factor0.1做 warmup之后用PolyLRpower0.9、eta_min1e-4衰减至 80000 次迭代结束by_epochFalse表示按迭代而非 epoch 调度。基础调度 schedule_80k.py 定义了 SGD 优化器lr0.01, momentum0.9, weight_decay0.0005、IterBasedTrainLoopmax_iters80000, val_interval8000以及每 8000 次迭代保存 checkpoint 的CheckpointHook。R-101 版本 pointrend_r101_4xb2-80k_cityscapes-512x1024.py 只通过继承改写两个字段pretrainedopen-mmlab://resnet101_v1c与backbonedict(depth101)体现了 MMSegmentation 配置继承体系的简洁性。ADE20K 训练配置160k 迭代pointrend_r50_4xb4-160k_ade20k-512x512.py 针对 ADE20K 做了三处关键调整数据集与调度替换为 ade20k.py 与 schedule_160k.pycrop_size(512, 512)num_classes从 19 改为 150ADE20K 类别数两个解码头都要同步修改PolyLR的end从 80000 改为 160000。训练、测试与推理命令在安装好 MMSegmentation 及其依赖requirements/runtime.txt之后可直接使用仓库自带的训练/测试脚本# 单卡训练 Cityscapes 80k 迭代 python tools/train.py configs/point_rend/pointrend_r50_4xb2-80k_cityscapes-512x1024.py # 多卡分布式训练4 GPU bash tools/dist_train.sh configs/point_rend/pointrend_r50_4xb2-80k_cityscapes-512x1024.py 4 # 测试并输出 mIoU python tools/test.py configs/point_rend/pointrend_r50_4xb2-80k_cityscapes-512x1024.py /path/to/checkpoint.pth # 单张图片推理 python demo/image_demo.py demo/demo.png \ configs/point_rend/pointrend_r50_4xb2-80k_cityscapes-512x1024.py \ /path/to/checkpoint.pth注意PointHead依赖 mmcv 的point_sample算子若缺失会在初始化时抛出 Please install mmcv-full for point_sample ops 的运行时错误见 point_head.py因此请确保安装了包含该算子的 mmcv 版本。模型的完整元信息权重下载地址、训练日志、批量大小、训练资源等可在 configs/point_rend/metafile.yaml 中查到包括每个模型对应的 Weights 与 Training log 链接tests/test_config.py中的test_config_build_segmentor会自动遍历各配置目录并验证build_segmentor能否成功构建模型可用于校验改动后的配置。官方基准结果以下结果来自仓库 configs/point_rend/README.md 与 configs/point_rend/metafile.yaml均以 4 张 V100 GPU 训练得到。其中 mIoU(msflip) 表示多尺度multi-scale推理并叠加水平翻转flip后的指标。Cityscapes19 类MethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(msflip)configPointRendR-50512x1024800003.18.48V10076.4778.13configPointRendR-101512x1024800004.27.00V10078.3079.97configADE20K150 类MethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(msflip)configPointRendR-50512x5121600005.117.31V10037.6439.17configPointRendR-101512x5121600006.115.50V10040.0241.60config从表中可以看到R-101 相比 R-50 在两个数据集上均带来稳定的 mIoU 提升Cityscapes 1.83、ADE20K 2.38而显存与推理时间的代价也同步增加。值得注意的是Cityscapes 配置下 PointRend 的显存占用仅 3.1 GBR-50这正体现了只在关键点上精细计算带来的效率优势。如何基于 PointRend 定制自己的模型基于上述配置继承机制可以非常方便地适配新数据集复制 pointrend_r50_4xb2-80k_cityscapes-512x1024.py 为自定义配置文件将_base_中的数据集配置替换为你自己的数据集参考 configs/base/datasets 下的模板同步修改 FPNHead 与 PointHead 的num_classes按显存情况调整crop_size、train_cfg.num_points采样点数与test_cfg.subdivision_steps细分次数——点数与细分次数是精度与速度之间的直接权衡旋钮若换用其他骨干仅需修改pretrained与backbone字段R-101 的做法即为此例。引用如果你在研究中使用了 PointRend 或本仓库实现可参考如下 BibTeXinproceedings{kirillov2020pointrend, title{Pointrend: Image segmentation as rendering}, author{Kirillov, Alexander and Wu, Yuxin and He, Kaiming and Girshick, Ross}, booktitle{Proceedings of the IEEE/CVF conference on computer vision and pattern recognition}, pages{9799--9808}, year{2020} }【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网