news 2026/9/15 21:26:51

MMSegmentation 中的 ERFNet:高效残差分解卷积实时语义分割实现与配置指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MMSegmentation 中的 ERFNet:高效残差分解卷积实时语义分割实现与配置指南

MMSegmentation 中的 ERFNet:高效残差分解卷积实时语义分割实现与配置指南

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

导读

本文以 MMSegmentation 仓库中 configs/erfnet/README.md 为主线,系统讲解 ERFNet(Efficient Residual Factorized ConvNet)这一面向实时语义分割的高效架构:包括其论文核心思想、在 MMSegmentation 中的源码实现、完整的 Cityscapes 训练配置、实验结果复现要点,以及基于仓库测试用例的验证方法。读完本文,你将掌握如何在 MMSegmentation 中读懂、配置、训练与测试 ERFNet,并理解其"残差连接 + 分解卷积"背后的效率来源。

1. 模型背景:面向智能驾驶的实时语义分割

ERFNet 由 Romera 等人提出,发表于 IEEE Transactions on Intelligent Transportation Systems(2017),核心目标是在嵌入式设备上以实时速度完成高精度像素级语义分割,为智能车辆(Intelligent Vehicles, IVs)的场景理解提供统一方案。

论文摘要指出,当时的 SOTA 分割方法在精度与计算资源之间缺乏良好平衡,难以部署到真实车辆。ERFNet 的核心创新在于提出了一种新型网络层——使用残差连接(residual connections)与分解卷积(factorized convolutions),在保持精度接近 SOTA 的同时将计算量降低数个量级。论文报告在单张 Titan X 上可运行超过 83 FPS,在 Jetson TX1 嵌入式设备上可达 7 FPS。这一效率与精度的权衡使其成为 IV 场景理解的理想方案。

MMSegmentation 将该算法完整实现,包括 backbone(mmseg/models/backbones/erfnet.py)与配套的 Cityscapes 训练配置,模型元数据记录于 configs/erfnet/metafile.yaml。

2. 架构剖析:三大基本模块的源码实现

从 mmseg/models/backbones/erfnet.py 的源码结构看,ERFNet backbone 由三种基本模块组成,对应论文中"分解卷积 + 残差 + 高效下采样/上采样"的设计:

2.1 DownsamplerBlock:下采样块

DownsamplerBlock(erfnet.py#L11-L65)与常规 ConvModule 不同:它将一个 stride=2 的 3×3 卷积与一个 stride=2 的 MaxPool 的输出拼接(concatenate)后再过 BatchNorm 与 ReLU

关键实现点:

  • 卷积输出通道为out_channels - in_channels,池化保留in_channels通道,拼接后恰好为out_channels
  • 池化结果通过resize(..., mode='bilinear')与卷积输出对齐尺寸。

测试用例 tests/test_models/test_backbones/test_erfnet.py#L120-L127 验证了DownsamplerBlock(16, 64)的 conv 输出为 48 通道(64-16)、BN 参数长度为 64、池化核与步长为 2。

2.2 NonBottleneck1d:非瓶颈一维分解卷积块

NonBottleneck1d(erfnet.py#L68-L145)是 ERFNet 效率的核心:它将标准 3×3 卷积分解为3×1 与 1×3 两个一维卷积,显著减少参数量与计算量,并通过残差连接output = self.act(output + input)保持梯度流通。

实现细节:

  • 每个 block 默认包含num_conv_layer=2组(3×1 → 1×3)卷积对;
  • 第二组卷积可设置空洞率dilation(默认 1),用于在不增加参数的情况下扩大感受野;
  • 第一组后接激活,第二组后接nn.Dropout(p=drop_rate)drop_rate默认 0),实现随机深度式的正则化效果。

2.3 UpsamplerBlock:上采样块

UpsamplerBlock(erfnet.py#L148-L191)使用nn.ConvTranspose2d(转置卷积,kernel=3, stride=2, output_padding=1)将特征图尺寸翻倍,随后接 BN 与 ReLU,测试用例验证了其通道变化(如 64→16)。

2.4 ERFNet 主网络:编码器-解码器组装逻辑

ERFNet类(erfnet.py#L194-L329)通过nn.ModuleList组装编码器与解码器:

  • 编码器:1 个 DownsamplerBlock(3→16 通道)+ 5 个 NonBottleneck1d(64 通道)+ 1 个 DownsamplerBlock(64→128 通道)+ 8 个**带不同空洞率(2, 4, 8, 16,循环两组)**的 NonBottleneck1d(128 通道);
  • 解码器:2 个 UpsamplerBlock(128→64→16 通道),每个上采样后接 2 个 NonBottleneck1d;
  • 输出:forward 返回[x],最终特征图为 16 通道,供后续解码头使用。

构造时有多条assert一致性校验(erfnet.py#L246-L269),例如编码器下采样块数量必须等于解码器上采样块数量 +1、编码器 Non-bottleneck 块数量必须能被空洞率个数整除等。测试用例 tests/test_models/test_backbones/test_erfnet.py#L38-L117 专门构造了 6 种非法参数组合验证这些断言会被触发,保障了配置的正确性。

3. 官方配置全解:erfnet_fcn_4xb4-160k_cityscapes-512x1024

3.1 实验配置总览

仓库提供的唯一官方模型配置为 configs/erfnet/erfnet_fcn_4xb4-160k_cityscapes-512x1024.py,其内容精简,通过继承_base_组装而成:

_base_ = [ '../_base_/models/erfnet_fcn.py', '../_base_/datasets/cityscapes.py', '../_base_/default_runtime.py', '../_base_/schedules/schedule_160k.py' ] crop_size = (512, 1024) data_preprocessor = dict(size=crop_size) model = dict(data_preprocessor=data_preprocessor) train_dataloader = dict(batch_size=4, num_workers=4) val_dataloader = dict(batch_size=1, num_workers=4) test_dataloader = val_dataloader

四个基础文件分别定义了模型结构、数据集、运行时与训练计划:

基础配置作用
configs/base/models/erfnet_fcn.py定义 backbone(ERFNet)与解码头(FCNHead)
configs/base/datasets/cityscapes.pyCityscapes 数据集路径、pipeline 与评估指标
configs/base/default_runtime.py日志、可视化、checkpoint 钩子等运行时设置
configs/base/schedules/schedule_160k.pySGD 优化器与 Poly 学习率策略

3.2 模型结构配置详解

configs/base/models/erfnet_fcn.py 中 backbone 各参数与源码构造一一对应:

backbone=dict( type='ERFNet', in_channels=3, # 输入图像通道数(RGB) enc_downsample_channels=(16, 64, 128),# 编码器各级下采样输出通道 enc_stage_non_bottlenecks=(5, 8), # 编码器各级 NonBottleneck1d 数量 enc_non_bottleneck_dilations=(2, 4, 8, 16), # 末级空洞率序列 enc_non_bottleneck_channels=(64, 128),# 编码器各级 NonBottleneck1d 通道数 dec_upsample_channels=(64, 16), # 解码器各级上采样输出通道 dec_stages_non_bottleneck=(2, 2), # 解码器各级 NonBottleneck1d 数量 dec_non_bottleneck_channels=(64, 16), # 解码器各级 NonBottleneck1d 通道数 dropout_ratio=0.1, # NonBottleneck1d 中 Dropout 概率 init_cfg=None)

解码头(Decoder Head)的重要设计:README 明确指出,原论文中的最后一个反卷积层被替换为朴素的FCNHead解码头 + 双线性上采样层,实验发现该替换更有效且更高效。对应的 FCNHead 配置为:

decode_head=dict( type='FCNHead', in_channels=16, # 与 backbone 输出的 16 通道特征图匹配 channels=128, num_convs=1, concat_input=False, dropout_ratio=0.1, num_classes=19, # Cityscapes 的 19 类语义类别 norm_cfg=norm_cfg, # SyncBN align_corners=False, loss_decode=dict( type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0))

整体模型类型为EncoderDecoder,数据预处理器使用SegDataPreProcessor(ImageNet 均值/方差、BGR→RGB),train_cfg=dict()test_cfg=dict(mode='whole')表示整图推理模式。

3.3 训练计划与数据增强配置

configs/base/schedules/schedule_160k.py 定义了 160k 迭代训练计划:

optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) optim_wrapper = dict(type='OptimWrapper', optimizer=optimizer, clip_grad=None) param_scheduler = [ dict(type='PolyLR', eta_min=1e-4, power=0.9, begin=0, end=160000, by_epoch=False) ] train_cfg = dict(type='IterBasedTrainLoop', max_iters=160000, val_interval=16000)
  • 优化器:SGD(lr=0.01,momentum=0.9,weight_decay=0.0005);
  • 学习率:PolyLR 多项式衰减(power=0.9,最低 1e-4),按迭代而非 epoch 调度;
  • 每 16000 次迭代验证一次,每 16000 次迭代保存 checkpoint。

数据集侧(configs/base/datasets/cityscapes.py):训练 pipeline 包含RandomResize(scale=(2048,1024),ratio_range=(0.5,2.0))、RandomCrop(crop_size=(512,1024),cat_max_ratio=0.75)、RandomFlip(prob=0.5)与PhotoMetricDistortion;评估使用IoUMetricmIoU指标。最终配置将训练 batch_size 设为 4(4 卡 × 4 = 16,与 metafile 中 Batch Size: 16 一致),验证/测试 batch_size 为 1。

4. 实验结果与复现要点

4.1 Cityscapes 官方结果

README 的 Results 表格记录了在 Cityscapes 上的完整结果:

MethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(ms+flip)
ERFNetERFNet512x10241600006.0415.26V10072.574.75
  • 训练资源:4× V100 GPU(见 configs/erfnet/metafile.yaml);
  • 模型权重与训练日志可从 metafile 中的 Weights / Training log 字段获取;
  • 测试时多尺度 + 水平翻转(ms+flip)可将 mIoU 从 72.5 提升至 74.75。

4.2 三条复现注意点(README 原文要点)

  1. 模型从零训练(trained from scratch)pretrained=Noneinit_cfg=None,不使用任何 ImageNet 预训练权重;
  2. 解码器替换:原论文最后一个反卷积层被FCNHead+ 双线性上采样替代(原因见 3.2 节);
  3. 对随机种子敏感:README 特别强调,模型性能对 seed 值敏感,如需精确复现表格结果,请参考官方日志文件中记录的 seed 设置;更换 seed 可能导致结果与表格不一致。

5. 训练、测试与推理实践

5.1 单机多卡训练

使用仓库提供的 tools/dist_train.sh 启动 4 卡训练:

bash tools/dist_train.sh configs/erfnet/erfnet_fcn_4xb4-160k_cityscapes-512x1024.py 4

单卡训练可使用 tools/train.py:

python tools/train.py configs/erfnet/erfnet_fcn_4xb4-160k_cityscapes-512x1024.py

训练前需按 Cityscapes 数据集约定将数据放置于data/cityscapes/下(leftImg8bit/gtFine/目录结构见 configs/base/datasets/cityscapes.py 的data_prefix设置)。

5.2 测试与指标复现

# 多卡测试 bash tools/dist_test.sh configs/erfnet/erfnet_fcn_4xb4-160k_cityscapes-512x1024.py \ /path/to/erfnet_fcn_4x4_512x1024_160k_cityscapes_20220704_162145-dc90157a.pth 4 # 单卡测试 python tools/test.py configs/erfnet/erfnet_fcn_4xb4-160k_cityscapes-512x1024.py \ /path/to/checkpoint.pth

测试 pipeline 对图片 Resize 到 (2048, 1024) 后整图推理(test_cfg.mode='whole')。

5.3 单图推理

仓库提供 demo/image_demo.py 进行可视化推理:

python demo/image_demo.py demo/demo.png \ configs/erfnet/erfnet_fcn_4xb4-160k_cityscapes-512x1024.py \ /path/to/checkpoint.pth --out-file result.png

6. 源码验证:单元测试如何保障实现正确性

仓库通过 tests/test_models/test_backbones/test_erfnet.py 对 ERFNet 实现进行了系统性验证:

  • 标准前向测试:以(2, 3, 256, 512)输入,断言 backbone 输出形状为(2, 16, 128, 256)——即 16 通道、空间尺寸缩小 4 倍,与解码头in_channels=16严格匹配;同时测试非规整输入尺寸(2, 3, 527, 279)也能正常前向;
  • 模块级测试:逐一验证 DownsamplerBlock 的卷积/池化通道数、NonBottleneck1d 的四组分解卷积通道与 dropout 概率、UpsamplerBlock 的转置卷积通道;
  • 非法参数断言测试:覆盖编码器/解码器通道数、block 数量、空洞率整除性等 6 类不一致配置,确保构造期即能发现配置错误。

这些测试共同构成了"配置参数 → 网络结构 → 输出形状"的闭环证据链:任何对通道元组或 block 数量的误配,要么在构造阶段被 assert 拦截,要么在前向阶段输出形状与解码头失配而报错。

7. 结语

ERFNet 展示了"残差连接 + 分解卷积 + 高效上采样"这一组合在实时语义分割上的巨大潜力。在 MMSegmentation 中,其实现被组织为可插拔的 backbone(mmseg/models/backbones/erfnet.py)与模块化配置(configs/erfnet/),配合完整的测试用例与 Cityscapes 基准结果,既便于研究者复现论文结论,也便于在自定义数据集上调整通道数、空洞率、Dropout 等超参快速验证想法。对于嵌入式与自动驾驶场景的落地需求,ERFNet 是一个兼具精度与速度的可靠基线。

参考文献

@article{romera2017erfnet, title={Erfnet: Efficient residual factorized convnet for real-time semantic segmentation}, author={Romera, Eduardo and Alvarez, Jos{\'e} M and Bergasa, Luis M and Arroyo, Roberto}, journal={IEEE Transactions on Intelligent Transportation Systems}, volume={19}, number={1}, pages={263--272}, year={2017}, publisher={IEEE} }

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

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

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

UNIHIKER M10嵌入式音频 recorder 设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 21:24:12

OpenClaw Windows 安装指南:智能体网关部署与配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

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

DB2联邦实战:跨库查询架构、配置与优化指南

很多DBA第一次接触DB2联邦(Federation)这个功能时,第一反应是“这不就是分布式数据库吗”,第二反应是“那我直接连源库查不就行了”。这两个反应我都经历过,实际在银行、制造业的项目里摸爬滚打之后,才真正…

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

SAP Fiori扩展字段发布后不可见的排查指南

1. 问题现象与背景分析作为一名长期从事SAP Fiori开发的顾问,我经常遇到客户提出这样的疑问:"明明在Custom Fields and Logic里发布了扩展字段,为什么在Available Fields列表里却找不到?"这个看似简单的问题背后&#x…

作者头像 李华
网站建设 2026/9/15 21:22:03

ASP.NET预约洗车系统源码解析:数据建模、状态机与并发事务实战

简介:这是一份面向ASP.NET学习者与毕业设计选题学生的预约洗车系统完整源码,采用C#语言开发,基于ASP.NET的Web Forms框架构建。系统按业务功能划分清晰,包含前台用户模块与后台管理模块,适合需要快速搭建可用项目或参考…

作者头像 李华