
MMSegmentation 中的 Semantic FPN 全解析从 Panoptic FPN 到轻量语义分割头的原理、配置与实战【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation本文以 OpenMMLab MMSegmentation 仓库中configs/sem_fpn目录及FPNHead解码头实现为主体系统讲解 Semantic FPN 这一经典语义分割方案先追溯其源于 Panoptic Feature Pyramid NetworksFPN的算法动机与论文要点再深入 fpn_head.py 源码剖析其金字塔特征多尺度融合 轻量分类头的设计最后结合 Cityscapes 与 ADE20K 上的完整配置与复现指标给出可直接运行的训练、测试与自定义扩展方案。读完本文你将掌握 Semantic FPN 的完整原理、配置文件中每个关键参数的含义以及如何在 MMSegmentation 中快速复现与迁移这一方法。算法背景从 Panoptic FPN 到 Semantic FPNSemantic FPN 源自论文Panoptic Feature Pyramid NetworksKirillov 等CVPR 2019其核心思想是在全景分割任务中实例分割thing 类与语义分割stuff 类通常由两套互不共享计算的网络分别完成该工作希望在架构层面统一二者设计单一网络同时承担两类任务——做法是为 Mask R-CNN 这一流行的实例分割方法增加一个共享 FPN 主干之上的语义分割分支。该论文的原始摘要原文档configs/sem_fpn/README.md中完整保留要点如下全景分割任务的提出重新激发了社区统一实例分割thing 类与语义分割stuff 类的兴趣。然而当时最先进的方法对两类任务使用相互独立且结构不同的网络不进行任何共享计算。该工作旨在架构层面统一这些方法为两个任务设计单一网络以共享 FPN 主干为 Mask R-CNN 赋予语义分割分支。出人意料的是这个简单基线不仅对实例分割依然有效还产出了一个轻量且性能领先的语义分割方法。文中对被称为 Panoptic FPN 的这一 Mask R-CNN 最小扩展版本进行了详细研究证明它是两个任务上稳健且准确的基线。Semantic FPN 正是从中剥离出的语义分割分支部分不再依赖 Mask R-CNN 的检测分支仅保留ResNet 主干 FPN 颈部 轻量 FPN 解码头从而构成一个极简、轻量、可独立用于纯语义分割的模型。在 MMSegmentation 中这一方法由FPNHead解码头实现官方代码入口见 fpn_head.py。架构拆解FPNHead 如何做多尺度语义融合总体结构在 MMSegmentation 中Semantic FPN 由三段式EncoderDecoder模型组成对应 configs/base/models/fpn_r50.pyBackboneResNetV1c输出 4 个阶段的特征图Neck标准FPN将 4 层特征统一投影到 256 通道Decode HeadFPNHead逐尺度上采样融合后直接输出分类 logits。FPNHead 源码级解析FPNHead位于 mmseg/models/decode_heads/fpn_head.py继承自BaseDecodeHead仅有一个核心参数feature_stridesMODELS.register_module() class FPNHead(BaseDecodeHead): def __init__(self, feature_strides, **kwargs): super().__init__(input_transformmultiple_select, **kwargs) assert len(feature_strides) len(self.in_channels) assert min(feature_strides) feature_strides[0] self.feature_strides feature_strides self.scale_heads nn.ModuleList() for i in range(len(feature_strides)): head_length max( 1, int(np.log2(feature_strides[i]) - np.log2(feature_strides[0]))) scale_head [] for k in range(head_length): scale_head.append( ConvModule( self.in_channels[i] if k 0 else self.channels, self.channels, 3, padding1, ...)) if feature_strides[i] ! feature_strides[0]: scale_head.append( Upsample(scale_factor2, modebilinear, ...)) self.scale_heads.append(nn.Sequential(*scale_head))关键设计可以概括为以下几点多输入变换input_transformmultiple_select表明该头接收 backbone/neck 输出的多张特征图默认 4 层。scale_heads 分组处理对每一层特征构建独立的scale_head。head_length由该层 stride 与最小 stride 的对数差决定例如feature_strides[4, 8, 16, 32]时四层分别需要log2(4/4)0、log2(8/4)1、log2(16/4)2、log2(32/4)3次卷积 2 倍上采样从而把各层逐步对齐到最小 stride即最大分辨率的特征尺度max(1, ...)保证 stride 最小层至少有一个 3×3 卷积。逐层卷积的通道设计每层 scale_head 的第一层卷积输入为该层原始通道数in_channels[i]后续卷积输入统一为channels配置中为 128即先降维再逐步精炼。前向逐层累加融合def forward(self, inputs): x self._transform_inputs(inputs) output self.scale_heads0 for i in range(1, len(self.feature_strides)): output output resize( self.scale_headsi, sizeoutput.shape[2:], modebilinear, align_cornersself.align_corners) output self.cls_seg(output) return output以最高分辨率分支为基准其余分支经各自 scale_head 处理后resize到基准尺寸并逐元素相加最后经cls_seg1×1 卷积映射到num_classes个类别。整个融合过程没有复杂注意力或空洞卷积体现了 Semantic FPN简单而有效的设计哲学。配置文件逐字段精讲以 fpn_r50 基础模型为例Semantic FPN 的模型定义集中在 configs/base/models/fpn_r50.py其完整内容如下norm_cfg dict(typeSyncBN, requires_gradTrue) data_preprocessor dict( typeSegDataPreProcessor, mean[123.675, 116.28, 103.53], std[58.395, 57.12, 57.375], bgr_to_rgbTrue, pad_val0, seg_pad_val255) model dict( typeEncoderDecoder, data_preprocessordata_preprocessor, pretrainedopen-mmlab://resnet50_v1c, backbonedict( typeResNetV1c, depth50, num_stages4, out_indices(0, 1, 2, 3), dilations(1, 1, 1, 1), strides(1, 2, 2, 2), norm_cfgnorm_cfg, norm_evalFalse, stylepytorch, contract_dilationTrue), neckdict( typeFPN, in_channels[256, 512, 1024, 2048], out_channels256, num_outs4), decode_headdict( typeFPNHead, in_channels[256, 256, 256, 256], in_index[0, 1, 2, 3], feature_strides[4, 8, 16, 32], channels128, dropout_ratio0.1, num_classes19, norm_cfgnorm_cfg, align_cornersFalse, loss_decodedict( typeCrossEntropyLoss, use_sigmoidFalse, loss_weight1.0)), train_cfgdict(), test_cfgdict(modewhole))各关键参数的作用如下参数值说明backbone.typeResNetV1c使用带 stem 改造首个 7×7 卷积替换为 3×3 堆叠的 ResNet V1c 变体dilations(1,1,1,1)表示不使用空洞卷积扩张backbone.out_indices(0,1,2,3)输出全部 4 个阶段特征供 FPN 使用neck.typeFPN标准特征金字塔in_channels对应 ResNet 4 阶段通道数[256,512,1024,2048]统一投影为out_channels256输出 4 层decode_head.feature_strides[4,8,16,32]4 层特征相对原图的下采样倍数须与in_channels等长且第一个最小是 FPNHead 决定各分支上采样次数的依据decode_head.channels128融合分支的中间通道数decode_head.dropout_ratio0.1分类前 Dropout 概率用于缓解过拟合decode_head.num_classes19数据集类别数Cityscapes 为 19ADE20K 需改为 150loss_decodeCrossEntropyLossuse_sigmoidFalse表示使用 Softmax 交叉熵loss_weight1.0test_cfg.modewhole整图推理不做滑窗切片数据集与训练计划Cityscapes 与 ADE20K 的配置差异configs/sem_fpn下共有 4 个完整实验配置全部通过_base_继承机制组合而成Cityscapes80k 迭代configs/sem_fpn/fpn_r50_4xb2-80k_cityscapes-512x1024.py_base_ [ ../_base_/models/fpn_r50.py, ../_base_/datasets/cityscapes.py, ../_base_/default_runtime.py, ../_base_/schedules/schedule_80k.py ] crop_size (512, 1024) data_preprocessor dict(sizecrop_size) model dict(data_preprocessordata_preprocessor)其依赖的四块基础配置分别负责模型定义上文、Cityscapes 数据集管线含 19 类、训练/验证划分与数据增强、默认运行环境日志、权重、评估等、80k 训练计划。R-101 版本 fpn_r101_4xb2-80k_cityscapes-512x1024.py 仅覆盖两处差异_base_ ./fpn_r50_4xb2-80k_cityscapes-512x1024.py model dict(pretrainedopen-mmlab://resnet101_v1c, backbonedict(depth101))即换用 ImageNet 预训练的 ResNet-101 主干其他一切保持不变。ADE20K160k 迭代configs/sem_fpn/fpn_r50_4xb4-160k_ade20k-512x512.py_base_ [ ../_base_/models/fpn_r50.py, ../_base_/datasets/ade20k.py, ../_base_/default_runtime.py, ../_base_/schedules/schedule_160k.py ] crop_size (512, 512) data_preprocessor dict(sizecrop_size) model dict( data_preprocessordata_preprocessor, decode_headdict(num_classes150))与 Cityscapes 相比差异集中在裁剪尺寸为 512×512正方形、训练迭代 160k、解码头类别数改为 150ADE20K 共 150 个语义类别。R-101 版本 fpn_r101_4xb4-160k_ade20k-512x512.py 同样只替换主干深度。训练计划细节两份 schedule 配置定义了优化器与学习率策略以 schedule_80k.py 为例优化器SGDlr0.01、momentum0.9、weight_decay0.0005调度器PolyLR多项式衰减power0.9eta_min1e-4按迭代by_epochFalse在 080000 间衰减训练循环IterBasedTrainLoopmax_iters80000每 8000 迭代验证一次并保存一次 checkpoint。schedule_160k.py 结构完全相同仅将max_iters与各间隔翻倍至 160k / 16000配合4xb4batch size 16应对 ADE20K 更大规模的训练需求。复现结果Cityscapes 与 ADE20K 官方指标原文档configs/sem_fpn/README.md与 metafile.yaml 记录了如下在 4×V100 GPU 上训练的官方复现结果指标均为 mIoUmsflip 表示多尺度测试加水平翻转CityscapesMethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(msflip)configFPNR-50512x1024800002.813.54V10074.5276.08configFPNR-101512x1024800003.910.29V10075.8077.40configADE20KMethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(msflip)configFPNR-50512x5121600004.955.77V10037.4939.09configFPNR-101512x5121600005.940.58V10039.3540.72config从指标可以看出 Semantic FPN 的轻量高效特征R-50 在 Cityscapes 上推理约 13.5 fpsV100且显存仅约 2.8 GBR-50 在 ADE20K 上更是达到约 55.8 fps。在 ADE20K 这类大规模精细语义数据集上R-101 相比 R-50 约有近 2 个点的 mIoU 提升39.35 vs 37.49说明更强的主干对多尺度融合结果仍有明显增益。训练、测试与推理实战单卡 / 多卡训练在已安装 MMSegmentation 依赖并准备好对应数据集Cityscapes / ADE20K 按仓库数据集文档放置的前提下可直接使用仓库 tools/train.py 启动训练# 单卡训练 python tools/train.py configs/sem_fpn/fpn_r50_4xb2-80k_cityscapes-512x1024.py # 8 卡分布式训练对应 batch size 2×4 的官方配置为 4 卡 bash tools/dist_train.sh configs/sem_fpn/fpn_r50_4xb2-80k_cityscapes-512x1024.py 4训练日志与 checkpoint 默认输出到work_dirs/下以配置文件名命名的目录schedule_80k.py 中的CheckpointHookinterval8000会每 8000 迭代保存一次模型。测试与指标复现使用 tools/test.py 评估可复现上表中的 mIoU# 单卡测试 python tools/test.py configs/sem_fpn/fpn_r50_4xb2-80k_cityscapes-512x1024.py \ /path/to/fpn_r50_512x1024_80k_cityscapes_20200717_021437-94018a0d.pth \ --out results.pkl # 多尺度 翻转msflip评测 python tools/test.py configs/sem_fpn/fpn_r50_4xb2-80k_cityscapes-512x1024.py \ /path/to/checkpoint.pth --tta --out results.pkltest_cfg.modewhole决定了默认的整图推理方式若要获得 mIoU(msflip) 列指标需开启多尺度测试与水平翻转 TTA--tta这正是_base_中default_runtime.py配置的tta_model/tta_pipeline所承载的能力。自定义扩展换主干、换数据集由于所有模型参数集中在decode_head与backbone扩展非常直接换更强主干参照 R-101 配置的写法仅覆盖model.pretrained与backbone.depth例如换成 ResNet-101、ResNeSt 等换数据集将_base_中的数据集模块替换为其他数据集配置仓库configs/_base_/datasets/下已有数十种并同步修改decode_head.num_classes与crop_size、data_preprocessor.size微调解码头容量调整channels如 128→256可增大融合分支容量代价是显存与耗时上升。引用若在学术工作中使用 Semantic FPN原文档configs/sem_fpn/README.md给出的引用条目如下inproceedings{kirillov2019panoptic, title{Panoptic feature pyramid networks}, author{Kirillov, Alexander and Girshick, Ross and He, Kaiming and Doll{\a}r, Piotr}, booktitle{Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition}, pages{6399--6408}, year{2019} }小结Semantic FPN 之所以成为经典在于它以FPN 多尺度特征 逐尺度上采样求和这一极简结构取得了极具竞争力的精度与极低的计算开销。在 MMSegmentation 中这一思想被完整落地为 FPNHead 与configs/sem_fpn下 4 个开箱即用的配置Cityscapes 上 R-50/R-101 分别达到 74.52 / 75.80 mIoUADE20K 上达到 37.49 / 39.35 mIoU且推理显存均不超过 6 GB。无论用于快速验证新想法还是作为轻量语义分割的强基线Semantic FPN 都是值得优先尝试的方案。【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考