news 2026/9/15 13:36:55

MMDetection 生态下的动态多尺度语义分割:MMSegmentation 中 DMNet 原理与实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MMDetection 生态下的动态多尺度语义分割:MMSegmentation 中 DMNet 原理与实战指南

MMDetection 生态下的动态多尺度语义分割:MMSegmentation 中 DMNet 原理与实战指南

【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation

DMNet(Dynamic Multi-scale Network)是 ICCV 2019 提出的一种基于动态多尺度卷积的语义分割算法,其核心思想是用"由输入图像内容动态生成的卷积核"取代传统固定的多尺度滤波器,从而在不显著增加参数量的前提下自适应捕获不同尺度的上下文信息。本文以 MMSegmentation 仓库中 DMNet 官方文档 为主体,结合 DMHead 源码、基础配置文件 与 单元测试,完整讲解 DMNet 的算法原理、代码实现、配置解析与训练推理方法,帮助读者在 MMSegmentation 中快速复现与二次开发 DMNet。

一、算法背景与核心思想

1.1 多尺度表征的困境

在语义分割任务中,同一张图片里的物体与"stuff"类别往往存在显著的尺度差异(例如近处的人与远处的建筑),因此多尺度表征是提升分割精度的关键手段。传统方法构建多尺度表征通常有以下几种路线:

  • 使用不同尺寸的卷积滤波器,但参数量与计算量成倍增长;
  • 使用膨胀卷积(dilated convolution)扩大感受野,但滤波器尺寸/膨胀率一旦训练完成即固定;
  • 使用不同尺度的池化网格(pooling grids),同样面临参数固定、推理时无法适应输入内容的问题。

这些方法的共同缺陷是:滤波器的参数在训练结束后完全固定,推理时对输入图像的内容不具备自适应性,且往往伴随较高的计算开销或参数量。

1.2 DMNet 的解决思路

DMNet 提出用动态卷积解决上述问题:网络由多个并行排列的DCM(Dynamic Convolutional Module,动态卷积模块)组成,每个 DCM 负责估计某一特定尺度的语义表征。关键在于,DCM 中使用的卷积核并非训练后固定的参数,而是根据输入特征图内容实时生成的 context-aware filters(上下文感知滤波器)。多个 DCM 的输出经过融合后得到最终的分割结果。

原论文在 PASCAL VOC 2012、Pascal-Context 与 ADE20K 三个数据集上进行了验证:在不使用 MS COCO 预训练和后处理的情况下,DMNet 在 PASCAL VOC 2012 test 集上取得了 84.4% mIoU,并在 Pascal-Context 与 ADE20K 上取得了当时领先的结果(该数据来自论文摘要,可作为算法背景参考;当前仓库则提供了 Cityscapes 与 ADE20K 上的可复现基准,见后文"模型库"一节)。

二、核心实现剖析:DCM 与 DMHead

MMSegmentation 在 mmseg/models/decode_heads/dm_head.py 中完整实现了 DMNet 的解码头,包含两个关键组件:DCM(第 11-89 行)与DMHead(第 92-141 行),并通过@MODELS.register_module()注册到模型注册表,配置文件中以type='DMHead'即可直接引用。

2.1 DCM:动态卷积模块

DCM的核心逻辑在forward中(dm_head.py#L61-L89),其前向流程可以拆解为四步:

  1. 生成动态卷积核:对输入xF.adaptive_avg_pool2d(x, self.filter_size)自适应平均池化,将特征压缩为filter_size × filter_size的空间尺寸,再经filter_gen_conv(1×1 卷积)生成与通道数对应的滤波器。这里的filter_size即 DCM 负责的尺度。
  2. 输入通道压缩input_redu_conv用 1×1 卷积把输入通道数统一到channels
  3. 动态卷积执行:将特征变形为[1, b*c, h, w]、滤波器变形为[b*c, 1, filter_size, filter_size],随后以groups=b*c的深度可分离方式调用F.conv2d,即每个通道使用各自的动态卷积核完成卷积,再经 padding 保持空间尺寸不变。
  4. 归一化与激活:依次经过 norm 层(若配置了norm_cfg)与激活层,若开启fusion则再追加一个 1×1 的fusion_conv融合本模块输出。

从源码可以看出,DCM 的动态性来源于"池化-生成-卷积"这一路径:卷积核由当前输入的内容决定,因此同一套网络参数可以在推理时对不同图像生成不同滤波器,实现对输入的自适应。

2.2 DMHead:多尺度并联与融合

DMHead继承自BaseDecodeHead(mmseg/models/decode_heads/decode_head.py),构造函数中(dm_head.py#L107-L130)根据filter_sizes元组(默认(1, 3, 5, 7))创建一组并行的DCM实例,存入nn.ModuleList

前向过程(dm_head.py#L132-L141):

def forward(self, inputs): x = self._transform_inputs(inputs) dcm_outs = [x] for dcm_module in self.dcm_modules: dcm_outs.append(dcm_module(x)) dcm_outs = torch.cat(dcm_outs, dim=1) output = self.bottleneck(dcm_outs) output = self.cls_seg(output) return output

即:原始特征x与每个 DCM 的输出沿通道维拼接(通道数变为in_channels + len(filter_sizes) * channels),再经bottleneck(3×3 卷积)融合,最后交给cls_seg得到逐像素分类 logits。每个 DCM 只对输入做一次池化/卷积,各尺度并行计算,避免了传统多尺度方法的参数量膨胀。

2.3 参数说明与单元测试验证

DMHead的构造参数如下:

参数类型默认值说明
filter_sizestuple/list(1, 3, 5, 7)各 DCM 动态卷积核的尺寸,必须是列表或元组
fusionboolFalse是否在每个 DCM 输出后追加融合卷积
in_channels/channelsint输入通道数 / 模块中间通道数
conv_cfg/norm_cfg/act_cfgdict卷积、归一化、激活层配置

单元测试 对这些行为做了明确约束,可作为二次开发时的回归依据:

  • filter_sizes传入标量(如1)会触发AssertionError(测试第 11-13 行),源码第 109 行assert isinstance(filter_sizes, (list, tuple))与之对应;
  • 未配置norm_cfg时,网络中的卷积模块不含归一化层;配置SyncBN后包含(第 15-25 行);
  • fusion=Truehead.fusion为 True,且dcm_modules中各模块的filter_size与传入元组一一对应(第 38-40 行);
  • 输入[1, 8, 23, 23]的特征图,输出形状为(1, num_classes, 23, 23),空间尺寸保持不变(第 42、58 行)。

三、配置文件逐项解析

3.1 解码头基础配置

DMNet 的模型骨架在 configs/base/models/dmnet_r50-d8.py 中定义,其decode_head段落是理解 DMNet 在 MMSegmentation 中落地方式的关键:

decode_head=dict( type='DMHead', in_channels=2048, in_index=3, channels=512, filter_sizes=(1, 3, 5, 7), dropout_ratio=0.1, num_classes=19, norm_cfg=dict(type='SyncBN', requires_grad=True), align_corners=False, loss_decode=dict( type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)),

各字段含义:

  • type='DMHead':对应注册表中的DMHead类,即上文源码解析的解码头;
  • in_channels=2048:取自 ResNet 最后一个 stage(in_index=3)的输出通道数;
  • channels=512:DCM 内部特征与最终融合前的通道数;
  • filter_sizes=(1, 3, 5, 7):四个并行 DCM 的动态卷积核尺寸,这也是 DMNet 捕获"多尺度"的直接体现;
  • dropout_ratio=0.1:分类层前 Dropout 比例;
  • loss_decode:主损失为CrossEntropyLoss,权重 1.0。

同时该骨架还配置了一个FCNHead辅助头(loss_weight=0.4),与主解码头共同参与训练,帮助浅层特征学习;推理阶段辅助头不参与输出。

3.2 数据集与训练调度

以 Cityscapes 为例,dmnet_r50-d8_4xb2-40k_cityscapes-512x512.py(实际文件名为 512x1024)通过_base_继承四份基础配置:

_base_ = [ '../_base_/models/dmnet_r50-d8.py', '../_base_/datasets/cityscapes.py', '../_base_/default_runtime.py', '../_base_/schedules/schedule_40k.py' ] crop_size = (512, 1024) data_preprocessor = dict(size=crop_size) model = dict(data_preprocessor=data_preprocessor)

其中:

  • configs/base/datasets/cityscapes.py 定义了 Cityscapes 数据管线:训练时RandomResize(缩放范围 0.5~2.0)、RandomCrop(512×1024,cat_max_ratio=0.75防止裁剪块类别失衡)、RandomFlipPhotoMetricDistortion等增强;验证/测试时按(2048, 1024)等比 resize;评估器为IoUMetric,指标mIoU
  • configs/base/schedules/schedule_40k.py 提供 40k 迭代的优化器与学习率策略;
  • 最后的data_preprocessor覆写为匹配裁剪尺寸(512, 1024)

ADE20K 的配置(如 dmnet_r50-d8_4xb4-160k_ade20k-512x512.py)结构相同,差异在于:数据集切换为ade20k.py、调度为schedule_160k.pycrop_size=(512, 512),并将主/辅助头的num_classes从 19 改为 150(ADE20K 的类别数)。

四、模型库与官方复现结果

configs/dmnet/目录共提供 12 个训练配置(R-50/R-101 × Cityscapes/ADE20K × 不同调度与分辨率),所有条目均登记在 configs/dmnet/metafile.yaml 中,可通过 MIM 或tools/train.py直接调用。以下结果表格继承自 官方 README(其中 mIoU 为官方在 V100 上复现的指标,Inf time 为单卡推理帧率;"ms+flip" 表示多尺度 + 水平翻转测试增强)。

4.1 Cityscapes(19 类)

MethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(ms+flip)config
DMNetR-50-D8512x1024400007.03.66V10077.7879.14config
DMNetR-101-D8512x10244000010.62.54V10078.3779.72config
DMNetR-50-D8769x769400007.91.57V10078.4980.27config
DMNetR-101-D8769x7694000012.01.01V10077.6278.94config
DMNetR-50-D8512x102480000--V10079.0780.22config
DMNetR-101-D8512x102480000--V10079.6480.67config
DMNetR-50-D8769x76980000--V10079.2280.55config
DMNetR-101-D8769x76980000--V10079.1980.65config

4.2 ADE20K(150 类)

MethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(ms+flip)config
DMNetR-50-D8512x512800009.420.95V10042.3743.62config
DMNetR-101-D8512x5128000013.013.88V10045.3446.13config
DMNetR-50-D8512x512160000--V10043.1544.17config
DMNetR-101-D8512x512160000--V10045.4246.76config

阅读上述表格可以发现两个工程要点:

  • 分辨率影响显著:Cityscapes 上 769×769 裁剪通常优于 512×1024(如 40k 的 R-50 从 77.78 提升到 78.49),但推理帧率也从 3.66 fps 降至 1.57 fps,属于典型的精度-速度权衡;
  • 更长的训练调度带来稳定增益:80k 迭代相对 40k 在 Cityscapes 各配置上普遍提升约 1 个点,ms+flip测试增强额外带来约 1 个点收益;ADE20K 上 160k 相对 80k 亦有提升(R-101 从 45.34 到 45.42)。

五、训练、测试与推理实战

5.1 训练

单机单卡(或单机多卡)训练一个 DMNet 模型,使用仓库提供的 tools/train.py:

# 单卡训练 python tools/train.py configs/dmnet/dmnet_r50-d8_4xb2-40k_cityscapes-512x1024.py # 8 卡分布式训练(与 4xb2 等配置的 batch size 含义对应:4 GPU × batch 2) bash tools/dist_train.sh configs/dmnet/dmnet_r50-d8_4xb2-40k_cityscapes-512x1024.py 8

dist_train.sh 为多卡启动脚本;Slurm 集群环境可参考 slurm_train.sh。训练前需按 configs/base/datasets/cityscapes.py 中data_root = 'data/cityscapes/'的约定放置数据集(leftImg8bit/gtFine/目录结构)。

5.2 测试与评估

使用 tools/test.py 在验证集上评测:

python tools/test.py configs/dmnet/dmnet_r50-d8_4xb2-40k_cityscapes-512x1024.py \ /path/to/checkpoint.pth --eval mIoU

配置文件中的val_evaluator已默认采用IoUMetric+mIoU。若需复现表格中的ms+flip指标,可利用 cityscapes.py 中预置的tta_pipeline(6 个缩放比例 × 水平翻转的TestTimeAug),在测试时开启 TTA 即可。

5.3 单图推理

推理脚本 demo/image_demo.py 支持对单张图片进行可视化推理:

python demo/image_demo.py demo/demo.png \ configs/dmnet/dmnet_r50-d8_4xb2-40k_cityscapes-512x1024.py \ /path/to/checkpoint.pth --device cuda

输出将直接叠加显示分割结果;如需批量推理或接入推理管线,可参考基于MMSegInferencer的 demo/image_demo_with_inferencer.py。

六、引用

若在学术工作中使用或复现 DMNet,请引用原论文(bibtex 来自 configs/dmnet/README.md):

@InProceedings{He_2019_ICCV, author = {He, Junjun and Deng, Zhongying and Qiao, Yu}, title = {Dynamic Multi-Scale Filters for Semantic Segmentation}, booktitle = {Proceedings of the IEEE/CVF International Conference on Computer Vision (ICCV)}, month = {October}, year = {2019} }

七、小结

DMNet 的价值在于把"多尺度"从静态结构升级为动态行为:通过DCM依据输入内容即时生成多组不同尺寸的卷积核,在并行分支中捕获多尺度上下文后融合,兼顾了精度与参数效率。在 MMSegmentation 仓库中,读者可以直接基于 dm_head.py 研究其实现,通过 configs/dmnet/ 下的 12 个配置复现 Cityscapes 与 ADE20K 上的全部基准,并借助filter_sizesfusionchannels等参数快速开展自己的实验——例如增减 DCM 数量(修改filter_sizes)、开关fusion融合、或替换 backbone 观察动态卷积在不同特征层次上的表现。

【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 13:35:59

基于FME的三调图斑尖锐角与小缝隙自动化处理全攻略

早几年做三调内业,最让人头疼的不是图斑分错地类,而是“图上干净”这四个字。外业跑断腿拿回来的成果,进入内业建库阶段,质检软件一跑,尖锐角、小缝隙、狭长条这些问题哗啦啦涌出来,动辄几千上万个。用ArcG…

作者头像 李华
网站建设 2026/9/15 13:34:45

AI辅助排查内存占用过高:从94%到64%的实测优化指南

手里这台老本子跟了我整整五年,8GB内存放在当年还能打,放到今天就真有点勉强了。平时也就是开微信、看网页、写写文档,结果内存占用动不动就飙到94%,风扇呼呼转,切换程序要等两三秒,打开任务管理器都要转半…

作者头像 李华
网站建设 2026/9/15 13:34:01

用Python实现基于NDDF的Malmquist-Luenberger指数分解

用 Python 做 DEA 效率评价的同行,应该都有过这种体会:CCR、BCC 这类径向模型处理常规的投入产出数据还算顺手,一旦数据里出现二氧化碳排放、废水、不良贷款这类非期望产出,径向模型就特别别扭。这几年能源经济、绿色金融、产业效…

作者头像 李华
网站建设 2026/9/15 13:33:51

(四)Unity3d-ROS联合仿真:turtlebot在Unity3d中仿真

运行环境Ubuntu20.04Unity3d 1.下载运行 (1)项目下载地址: Robotics-Nav2-SLAM-Example 最好执行下面命令能将子模块也下载 git clone --recurse-submodule gitgithub.com:Unity-Technologies/Robotics-Nav2-SLAM-Example.gitgit submodu…

作者头像 李华
网站建设 2026/9/15 13:33:02

微信分享JSSDK签名验证PHP实现:从原理到完整代码

简介:微信网页开发中,后端签名验证是不少开发者绕不开的环节。这套代码把常见签名流程封装为一个PHP文件,面向需要快速接入微信自定义分享能力的初、中级开发者,适用于企业公众号、服务号及各类移动网页活动页,下载后仅…

作者头像 李华