MMSegmentation 中的 HRNet 语义分割实践:高分辨率并行骨干网络的原理、配置与模型基准
【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation
导读
本文以 MMSegmentation 仓库中 configs/hrnet/README.md 为骨架,系统讲解 HRNet(High-Resolution Network)这一以"全程保持高分辨率表示"为核心思想的骨干网络:从论文提出的并行多分辨率结构与跨分辨率信息交换原理,到其在 mmseg/models/backbones/hrnet.py 中的完整实现细节,再到仓库内置的 FCN + HRNetV2p 全量配置与跨数据集基准结果,最后给出基于本仓库的实际训练与测试命令。读完本文,你将能够理解 HRNet 与 ResNet 等串行下采样骨干的本质差异,读懂extra四阶段配置的结构化含义,并直接在 MMSegmentation 中复现 Cityscapes、ADE20K 等数据集上的 HRNet 语义分割实验。
HRNet 的设计动机:从"先下采样再恢复"到"全程保持高分辨率"
对于语义分割这类位置敏感(position-sensitive)的视觉任务,高分辨率表示至关重要。传统 SOTA 框架(如 ResNet、VGGNet)的处理方式是:通过一条"高分辨率 → 低分辨率"串行连接的子网络对输入图像编码,得到低分辨率表示,再从编码后的低分辨率表示中恢复高分辨率输出。这一"先降后升"的路径不可避免地会造成空间细节损失。
HRNet 提出了截然不同的思路——在整个处理过程中始终维持高分辨率表示。原文档 Abstract 概括了它的两个关键特性:
- 并行连接:将"高 → 低分辨率"的卷积流以并行方式组织(connect the high-to-low resolution convolution streamsin parallel),而不是串行堆叠;
- 反复交换信息:在不同分辨率分支之间重复进行信息交换(repeatedly exchange the information across resolutions),使各分辨率分支相互增益。
由此得到的特征表示在语义上更丰富(semantically richer)、在空间上更精确(spatially more precise),这也是 HRNet 在人体姿态估计、语义分割、目标检测等任务上都能作为更强骨干的原因。
源码级解析:MMSegmentation 中的 HRNet 实现
HRNet 骨干在仓库中注册为HRNet(见 mmseg/models/backbones/hrnet.py#L217-L218),其核心构件包括 stem 网络、四个 stage、transition 层与HRModule。
模块划分:HRModule 与分支结构
HRModule(hrnet.py#L14-L19)是 HRNet 的基本组成单元:每个分支包含 4 个 BasicBlock/Bottleneck,且融合/交换(Fusion/Exchange)发生在本模块内部。它由两部分构成:
branches(_make_branches,hrnet.py#L115-L123):按num_branches构建并行分支,每个分支用num_blocks[i]个 block 处理num_channels[i]通道的特征;fuse_layers(_make_fuse_layers,hrnet.py#L125-L189):实现跨分辨率信息交换,具体规则为:- 从低分辨率分支
j向高分辨率分支i融合时(j > i),使用 1×1 卷积对齐通道数,再做scale_factor=2**(j-i)的双线性上采样(align_corners=False,这是 HRNet 的约定设置); - 同一分辨率分支(
j == i)直接相加; - 从高分辨率向低分辨率融合时(
j < i),使用若干个 3×3 stride=2 卷积逐级下采样对齐。
- 从低分辨率分支
前向过程(forward,hrnet.py#L191-L214)先让每个分支独立计算,再将各分支特征经 fuse_layers 融合后接 ReLU,输出num_out_branches个尺度的特征。
整体结构:四阶段并行扩展
HRNet.__init__(hrnet.py#L299-L422)严格校验extra必须包含stage1~stage4四个阶段,且每个阶段的num_blocks、num_channels长度必须等于num_branches,否则直接抛出断言错误(仓库测试 tests/test_models/test_backbones/test_hrnet.py 中即验证了"仅 3 个 stage 会报错""分支数与 block 数不匹配会报错"这两个约束)。整体前向流程(hrnet.py#L596-L631)为:
- stem:两个 stride=2 的 3×3 卷积(conv1、conv2)+ BN + ReLU,将输入从 3 通道变换为 64 通道,分辨率降为 1/4;
- stage1:单个分支的
layer1(默认 Bottleneck,输出 64 通道); - transition1:把 stage1 的输出扩展为 2 条分支,进入 stage2(2 分支);
- transition2:扩展为 3 条分支,进入 stage3(3 分支);
- transition3:扩展为 4 条分支,进入 stage4(4 分支),最终输出 4 个不同分辨率的特征层级。
每个 stage 由_make_stage(hrnet.py#L529-L568)串行堆叠num_modules个 HRModule。值得注意的细节是:multiscale_output=False时,仅在 stage 的最后一个 module 关闭多尺度输出,使模型只输出最高分辨率分支的特征,供只需单尺度特征的下游头使用(该行为在 test_hrnet.py 的test_hrmodule与test_hrnet_backbone中均有断言验证)。
训练期细节:冻结阶段与 BN 统计
frozen_stages(默认 -1,即不冻结任何参数)控制阶段冻结;norm_eval开启时,在train()中会将所有 BatchNorm 强制置为 eval 模式,冻结其 running stats(hrnet.py#L633-L642)。with_cp可开启梯度检查点(checkpoint)以省显存换速度。这些参数均在配置文件中直接可调。
配置实战:从 FCN+HRNetV2p 配置文件看懂extra结构
仓库 configs/hrnet 目录下共 45 个训练配置文件,全部采用FCN 解码头 + HRNetV2p 骨干的组合,覆盖 W18-Small、W18、W48 三种宽度规格与 Cityscapes、ADE20K、Pascal VOC 2012 + Aug、Pascal Context、Pascal Context 59、LoveDA、Potsdam、Vaihingen、iSAID 九大数据集。
基础模型配置:_base_/models/fcn_hr18.py
W18 规格的完整模型定义位于 configs/base/models/fcn_hr18.py,其extra结构清晰展示了四阶段配置的五个键(num_modules、num_branches、block、num_blocks、num_channels):
model = dict( type='EncoderDecoder', pretrained='open-mmlab://msra/hrnetv2_w18', backbone=dict( type='HRNet', norm_cfg=norm_cfg, # dict(type='SyncBN', requires_grad=True) norm_eval=False, extra=dict( stage1=dict(num_modules=1, num_branches=1, block='BOTTLENECK', num_blocks=(4,), num_channels=(64,)), stage2=dict(num_modules=1, num_branches=2, block='BASIC', num_blocks=(4, 4), num_channels=(18, 36)), stage3=dict(num_modules=4, num_branches=3, block='BASIC', num_blocks=(4, 4, 4), num_channels=(18, 36, 72)), stage4=dict(num_modules=3, num_branches=4, block='BASIC', num_blocks=(4, 4, 4, 4), num_channels=(18, 36, 72, 144)))), decode_head=dict( type='FCNHead', in_channels=[18, 36, 72, 144], # 对应 4 个分支输出通道 in_index=(0, 1, 2, 3), channels=sum([18, 36, 72, 144]), # 270,四分支拼接后的通道数 input_transform='resize_concat', # 上采样到同一尺度后拼接 kernel_size=1, num_convs=1, dropout_ratio=-1, num_classes=19, # Cityscapes 默认 19 类 loss_decode=dict(type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), train_cfg=dict(), test_cfg=dict(mode='whole'))几个关键点的源码对应关系:
input_transform='resize_concat'正是为 HRNet 这类多分支骨干设计的特征聚合方式——四路特征先各自上采样到最大分辨率,再沿通道拼接后送入 1×1 卷积分类,这是 FCN 解码头能消费 HRNet 多尺度输出的前提;- 各 stage 的
num_channels即该阶段各分支的宽度,W18 / W48 只是把num_channels整体放大,见下文。
数据集配置与训练计划
Cityscapes 数据集配置位于 configs/base/datasets/cityscapes.py,其中crop_size = (512, 1024),训练管线包含RandomResize(scale=(2048, 1024),ratio_range=(0.5, 2.0))、RandomCrop(cat_max_ratio=0.75)、RandomFlip、PhotoMetricDistortion;测试管线采用TestTimeAug多尺度(img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75])+ 水平翻转 TTA。训练计划位于 configs/base/schedules/schedule_80k.py(80k 迭代版本)。
完整训练配置示例
以 configs/hrnet/fcn_hr18_4xb2-80k_cityscapes-512x1024.py 为例,它通过_base_继承四个基础文件,仅需补齐crop_size与data_preprocessor:
_base_ = [ '../_base_/models/fcn_hr18.py', '../_base_/datasets/cityscapes.py', '../_base_/default_runtime.py', '../_base_/schedules/schedule_80k.py' ] crop_size = (512, 1024) data_preprocessor = dict(size=crop_size) model = dict(data_preprocessor=data_preprocessor)从 W18 升级到 W48:只改四个数
W48 版本的配置文件 configs/hrnet/fcn_hr48_4xb2-80k_cityscapes-512x1024.py 展示了如何在保持结构不变的情况下扩大网络宽度——只需覆写 stage2~stage4 的num_channels,并把预训练权重切换为hrnetv2_w48,同时同步更新解码头的in_channels:
_base_ = './fcn_hr18_4xb2-80k_cityscapes-512x1024.py' model = dict( pretrained='open-mmlab://msra/hrnetv2_w48', backbone=dict( extra=dict( stage2=dict(num_channels=(48, 96)), stage3=dict(num_channels=(48, 96, 192)), stage4=dict(num_channels=(48, 96, 192, 384)))), decode_head=dict( in_channels=[48, 96, 192, 384], channels=sum([48, 96, 192, 384])))而 W18-Small 规格(如 configs/hrnet/fcn_hr18s_4xb2-80k_cityscapes-512x1024.py)则将各 stage 的num_channels与解码头in_channels按 (18→16, 36→32, 72→64, 144→128) 的规律缩减,同时pretrained指向hrnetv2_w18_small。三种规格的区别完全由配置文件驱动,模型实现本身无需改动。
遥感与航空数据集的两个特例
- iSAID:所有 iSAID 配置(如 configs/hrnet/fcn_hr18s_4xb4-80k_isaid-896x896.py)的 Crop Size 均为896x896。原文档注明这是遵循 PointFlow(Flowing Semantics Through Points for Aerial Image Segmentation)实现的选择,并非 HRNet 本身的限制;
- LoveDA / Potsdam / Vaihingen:这三个遥感数据集均采用 512x512 裁剪、80k 迭代、4 卡 batch size 4 的标准配置,用于评测 HRNet 在高分辨率遥感影像上的表现。
结果与模型基准
以下所有基准均来自原文档(configs/hrnet/README.md),在 4×V100 GPU 上训练获得;每张表格的 config 列可直接点击进入仓库内配置文件,模型权重与训练日志(.pth / .log.json)的完整下载地址收录在 configs/hrnet/metafile.yaml 中。
Cityscapes(crop 512x1024)
| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config |
|---|---|---|---|---|---|---|---|---|---|
| FCN | HRNetV2p-W18-Small | 512x1024 | 40000 | 1.7 | 23.74 | V100 | 73.86 | 75.91 | config |
| FCN | HRNetV2p-W18 | 512x1024 | 40000 | 2.9 | 12.97 | V100 | 77.19 | 78.92 | config |
| FCN | HRNetV2p-W48 | 512x1024 | 40000 | 6.2 | 6.42 | V100 | 78.48 | 79.69 | config |
| FCN | HRNetV2p-W18-Small | 512x1024 | 80000 | - | - | V100 | 75.31 | 77.48 | config |
| FCN | HRNetV2p-W18 | 512x1024 | 80000 | - | - | V100 | 78.65 | 80.35 | config |
| FCN | HRNetV2p-W48 | 512x1024 | 80000 | - | - | V100 | 79.93 | 80.72 | config |
| FCN | HRNetV2p-W18-Small | 512x1024 | 160000 | - | - | V100 | 76.31 | 78.31 | config |
| FCN | HRNetV2p-W18 | 512x1024 | 160000 | - | - | V100 | 78.80 | 80.74 | config |
| FCN | HRNetV2p-W48 | 512x1024 | 160000 | - | - | V100 | 80.65 | 81.92 | config |
ADE20K(crop 512x512)
| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config |
|---|---|---|---|---|---|---|---|---|---|
| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 3.8 | 38.66 | V100 | 31.38 | 32.45 | config |
| FCN | HRNetV2p-W18 | 512x512 | 80000 | 4.9 | 22.57 | V100 | 36.27 | 37.28 | config |
| FCN | HRNetV2p-W48 | 512x512 | 80000 | 8.2 | 21.23 | V100 | 41.90 | 43.27 | config |
| FCN | HRNetV2p-W18-Small | 512x512 | 160000 | - | - | V100 | 33.07 | 34.56 | config |
| FCN | HRNetV2p-W18 | 512x512 | 160000 | - | - | V100 | 36.79 | 38.58 | config |
| FCN | HRNetV2p-W48 | 512x512 | 160000 | - | - | V100 | 42.02 | 43.86 | config |
Pascal VOC 2012 + Aug(crop 512x512)
| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config |
|---|---|---|---|---|---|---|---|---|---|
| FCN | HRNetV2p-W18-Small | 512x512 | 20000 | 1.8 | 43.36 | V100 | 65.5 | 68.89 | config |
| FCN | HRNetV2p-W18 | 512x512 | 20000 | 2.9 | 23.48 | V100 | 72.30 | 74.71 | config |
| FCN | HRNetV2p-W48 | 512x512 | 20000 | 6.2 | 22.05 | V100 | 75.87 | 78.58 | config |
| FCN | HRNetV2p-W18-Small | 512x512 | 40000 | - | - | V100 | 66.61 | 70.00 | config |
| FCN | HRNetV2p-W18 | 512x512 | 40000 | - | - | V100 | 72.90 | 75.59 | config |
| FCN | HRNetV2p-W48 | 512x512 | 40000 | - | - | V100 | 76.24 | 78.49 | config |
Pascal Context(crop 480x480)
| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config |
|---|---|---|---|---|---|---|---|---|---|
| FCN | HRNetV2p-W48 | 480x480 | 40000 | 6.1 | 8.86 | V100 | 45.14 | 47.42 | config |
| FCN | HRNetV2p-W48 | 480x480 | 80000 | - | - | V100 | 45.84 | 47.84 | config |
Pascal Context 59(crop 480x480)
| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config |
|---|---|---|---|---|---|---|---|---|---|
| FCN | HRNetV2p-W48 | 480x480 | 40000 | - | - | V100 | 50.33 | 52.83 | config |
| FCN | HRNetV2p-W48 | 480x480 | 80000 | - | - | V100 | 51.12 | 53.56 | config |
LoveDA(crop 512x512)
| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config |
|---|---|---|---|---|---|---|---|---|---|
| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 1.59 | 24.87 | V100 | 49.28 | 49.42 | config |
| FCN | HRNetV2p-W18 | 512x512 | 80000 | 2.76 | 12.92 | V100 | 50.81 | 50.95 | config |
| FCN | HRNetV2p-W48 | 512x512 | 80000 | 6.20 | 9.61 | V100 | 51.42 | 51.64 | config |
Potsdam(crop 512x512)
| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config |
|---|---|---|---|---|---|---|---|---|---|
| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 1.58 | 36.00 | V100 | 77.64 | 78.8 | config |
| FCN | HRNetV2p-W18 | 512x512 | 80000 | 2.76 | 19.25 | V100 | 78.26 | 79.24 | config |
| FCN | HRNetV2p-W48 | 512x512 | 80000 | 6.20 | 16.42 | V100 | 78.39 | 79.34 | config |
Vaihingen(crop 512x512)
| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config |
|---|---|---|---|---|---|---|---|---|---|
| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 1.58 | 38.11 | V100 | 71.81 | 73.1 | config |
| FCN | HRNetV2p-W18 | 512x512 | 80000 | 2.76 | 19.55 | V100 | 72.57 | 74.09 | config |
| FCN | HRNetV2p-W48 | 512x512 | 80000 | 6.20 | 17.25 | V100 | 72.50 | 73.52 | config |
iSAID(crop 896x896)
| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config |
|---|---|---|---|---|---|---|---|---|---|
| FCN | HRNetV2p-W18-Small | 896x896 | 80000 | 4.95 | 13.84 | V100 | 62.30 | 62.97 | config |
| FCN | HRNetV2p-W18 | 896x896 | 80000 | 8.30 | 7.71 | V100 | 65.06 | 65.60 | config |
| FCN | HRNetV2p-W48 | 896x896 | 80000 | 16.89 | 7.34 | V100 | 67.80 | 68.53 | config |
注:896x896是 iSAID 数据集的 Crop Size,遵循 PointFlow(Flowing Semantics Through Points for Aerial Image Segmentation)实现中的设置。
从结果可观察出清晰的规律:同等迭代数下,模型宽度(W18-Small → W18 → W48)与训练时长(40k → 80k → 160k)均能带来稳定的 mIoU 提升,而ms+flip多尺度翻转测试普遍比单尺度评估高 1~2 个点,其中 Cityscapes 上 HRNetV2p-W48 在 160k 迭代时取得 80.65 / 81.92 的领先成绩。
训练与测试:在 MMSegmentation 中复现 HRNet 实验
本仓库的完整训练/测试指南见 docs/zh_cn/user_guides/4_train_test.md,单卡训练命令格式为:
python tools/train.py ${配置文件} [可选参数]例如基于 Cityscapes 训练 FCN + HRNetV2p-W18(80k 迭代):
python tools/train.py configs/hrnet/fcn_hr18_4xb2-80k_cityscapes-512x1024.py若训练中断需从检查点恢复,或要用预训练权重初始化,可使用--resume与--cfg-options load_from=:
python tools/train.py ${配置文件} --resume --cfg-options load_from=${检查点}多卡分布式训练则使用仓库自带的tools/dist_train.sh:
bash tools/dist_train.sh configs/hrnet/fcn_hr18_4xb2-80k_cityscapes-512x1024.py ${GPU_NUM}测试命令格式为:
python tools/test.py ${配置文件} ${模型权重文件} [可选参数]例如:
python tools/test.py configs/hrnet/fcn_hr48_4xb2-80k_cityscapes-512x1024.py ${权重路径}如需启用 ms+flip 多尺度翻转测试以复现表格中的mIoU(ms+flip)指标,可传入测试参数开启 TestTimeAug(数据集配置中已内置tta_pipeline)。权重文件可从 configs/hrnet/metafile.yaml 中按模型名(如fcn_hr48_4xb2-80k_cityscapes-512x1024)检索对应的 .pth 与 .log.json 下载地址,其中 .log.json 记录了完整训练曲线,便于核对基准。
小结
HRNet 通过"并行多分辨率分支 + 跨分辨率反复信息交换"两条设计原则,在语义分割任务中证明了"全程保持高分辨率"路线的有效性。在 MMSegmentation 中,其实现集中在 mmseg/models/backbones/hrnet.py,配置模板集中在 configs/base/models/fcn_hr18.py,规模化实验配置与跨 9 大数据集的完整基准则收录在 configs/hrnet 目录下。无论是理解其源码结构、快速更换 W18/W48 规格,还是复现 Cityscapes、ADE20K 等基准结果,都可以完全基于本仓库开箱即用。
引用
原文档(configs/hrnet/README.md)中给出的论文引用信息:
@inproceedings{SunXLW19, title={Deep High-Resolution Representation Learning for Human Pose Estimation}, author={Ke Sun and Bin Xiao and Dong Liu and Jingdong Wang}, booktitle={CVPR}, year={2019} }【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考