资讯详情

MMsegmentation 中的 EncNet 实现解析:Context Encoding Module 与 SE-loss 的完整指南

📅 2026/9/15 21:34:17 | 华诺云谱 👁 阅读
MMsegmentation 中的 EncNet 实现解析:Context Encoding Module 与 SE-loss 的完整指南
MMsegmentation 中的 EncNet 实现解析Context Encoding Module 与 SE-loss 的完整指南【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation本文以 OpenMMLab 语义分割工具箱 MMSegmentation 中 EncNet 的官方实现为主线系统讲解 Context Encoding Module 的算法原理、EncHead解码头的源码结构、SE-loss 训练技巧、配置文件逐项拆解并给出 Cityscapes 与 ADE20K 上全部可复现的模型结果表与训练/测试命令。读完本文你将能够读懂并改造 EncNet 配置、独立复现论文中的 mIoU 指标并理解编码层 语义编码损失这一上下文建模范式在解码头中的落地方式。一、算法背景为什么要引入全局上下文编码EncNetContext Encoding for Semantic Segmentation发表于 CVPR 2018论文原文其出发点非常明确基于全卷积网络FCN框架的逐像素标注方法通常依赖空洞卷积Dilated/Atrous Convolution、多尺度特征与边界细化来提升空间分辨率表现但对场景级全局上下文信息的利用并不充分。论文提出的Context Encoding Module上下文编码模块专门用来解决这一问题它先编码出场景的语义上下文例如整张图是室内还是街道、包含哪些大类目标再据此有选择性地突出与当前类别相关的特征图从而帮助分类决策。该模块带来的额外计算量相对于 FCN 主干几乎可以忽略不计却能显著提升分割精度。论文报告的关键实验数据源自 README 的 Abstract 部分作为论文声明的事实如下PASCAL-Context 上达到 51.7% mIoUPASCAL VOC 2012 上达到 85.9% mIoU单模型在 ADE20K 测试集上获得 0.5567 的最终得分超越 COCO-Place Challenge 2017 的冠军方案在 CIFAR-10 图像分类任务上仅 14 层的网络达到 3.45% 错误率与层数多 10 倍以上的 SOTA 方法相当。需要说明的是以上精度数据来自论文本身与官方 README 的转述而 MMSegmentation 仓库内各数据集上可复现的官方评测结果见本文第六节表格两者是不同来源使用时请加以区分。二、核心模块拆解Encoding 层与 EncModule在 MMSegmentation 中EncNet 的实现分为两层底层是可复用的Encoding 层learnable residual encoder上层是组合了编码、归一化、缩放门控的EncModule。2.1 Encoding 层可学习的残差编码器Encoding模块定义在 mmseg/models/utils/encoding.py输入形状为(batch_size, channels, height, width)输出形状为(batch_size, num_codes, channels)。它包含两组可学习参数codewords形状[num_codes, channels]即一组码字code words相当于对特征空间进行聚类的聚类中心初始化为均匀分布(-std, std)其中std 1 / sqrt(num_codes * channels)scale形状[num_codes]每个码字的平滑因子初始化为(-1, 0)区间的均匀分布。前向计算分为两步对应源码中的两个静态方法scaled_l2把特征x展平为(batch, h*w, channels)后与每个码字计算带缩放因子的 L2 距离scaled_l2_norm scale * (x - codewords)^2得到每个像素对每个码字的相似度度量aggregate对距离做softmax(dim2)得到软分配权重assignment_weights再按权重对像素特征与码字之差加权求和得到编码后的特征encoded_feat。本质上这是把整张特征图压缩成num_codes个与码字相关的残差统计量即场景级上下文的紧凑表示。2.2 EncModule编码 门控重标定EncModule定义在 mmseg/models/decode_heads/enc_head.py结构如下class EncModule(nn.Module): def __init__(self, in_channels, num_codes, conv_cfg, norm_cfg, act_cfg): # 1) 1x1 卷积投影 self.encoding_project ConvModule(in_channels, in_channels, 1, ...) # 2) 编码层 一维归一化 ReLU self.encoding nn.Sequential( Encoding(channelsin_channels, num_codesnum_codes), build_norm_layer(encoding_norm_cfg, num_codes)[1], nn.ReLU(inplaceTrue)) # 3) 全连接 Sigmoid 生成门控因子 gamma self.fc nn.Sequential( nn.Linear(in_channels, in_channels), nn.Sigmoid())前向过程forward依次为encoding_project(x)用 1x1 卷积把输入特征投影到编码空间encoding(...)经过Encoding层得到(batch, num_codes, channels)的编码特征取mean(dim1)得到每个样本的上下文描述子fc(encoding_feat)经全连接与 Sigmoid 生成逐通道门控因子gamma输出F.relu_(x x * gamma)将原始特征与原始特征 × 门控因子相加后过 ReLU实现对类别相关特征图的选择性突出。值得一提的是编码特征本身还会作为旁路输出供EncHead计算语义编码损失见下一节。另外encoding_norm_cfg会做一次降维处理当归一化层是BN/IN时自动追加1d后缀BN1d/IN1d其他 2D 类型则替换为 1D 版本以匹配编码输出的一维形状——源码注释# TODO: resolve this hack也说明这一处理属于过渡性设计。三、EncHead 解码头从特征到分割与 SE-lossEncHead注册于MODELS注册表MODELS.register_module()继承自BaseDecodeHead核心实现在 mmseg/models/decode_heads/enc_head.py。3.1 构造参数与默认值参数默认值作用num_codes32码字数量决定场景上下文表示的容量use_se_lossTrue是否使用语义编码损失SE-loss正则化训练add_lateralFalse是否使用侧边连接lateral connection融合多层级特征loss_se_decodedict(typeCrossEntropyLoss, use_sigmoidTrue, loss_weight0.2)SE-loss 的损失配置EncHead通过input_transformmultiple_select接收主干的多层输出并包含以下子模块bottleneck3x3 卷积padding1把主干最后一层输出降到channels维lateral_convs fusion可选当add_lateralTrue时对除最后一层外的各层分别做 1x1 卷积并上采样到与主干特征相同尺寸拼接后经 3x3 融合卷积输出enc_module上文所述的EncModulese_layeruse_se_lossTrue时nn.Linear(channels, num_classes)把上下文描述子映射到类别维用于预测该类别是否出现在当前图像中。3.2 SE-loss语义编码损失SE-loss 是 EncNet 的训练技巧不仅要求解码头输出正确的逐像素分割还要求从上下文描述子能判别出图像中出现了哪些类别多标签分类。其实现集中在loss_by_feat与_convert_to_onehot_labels两个方法_convert_to_onehot_labels对每张图的 GT 分割标签统计直方图histc将出现过的类别转为 one-hot 向量形状(batch, num_classes)loss_by_feat把EncHead.forward返回的(output, se_output)拆开分割损失走BaseDecodeHead.loss_by_feat正常计算SE-loss 则由loss_se_decode默认CrossEntropyLoss, use_sigmoidTrue, loss_weight0.2在se_output与 one-hot 标签之间计算并以键名loss_se汇入总损失。前向与推理的差异也在源码中明确体现forward在use_se_lossTrue时返回二元组(seg_logits, se_output)而predict测试/推理入口只取分割 logits、丢弃 SE 分支避免引入额外的推理开销。四、配置文件逐项拆解以 R-50-D8 为例EncNet 的全部 17 个配置位于 configs/encnet均以_base_继承机制组合而成。以 encnet_r50-d8_4xb2-40k_cityscapes-512x1024.py 为例_base_ [ ../_base_/models/encnet_r50-d8.py, ../_base_/datasets/cityscapes.py, ../_base_/default_runtime.py, ../_base_/schedules/schedule_40k.py ] crop_size (512, 1024) data_preprocessor dict(sizecrop_size) model dict(data_preprocessordata_preprocessor)它由四部分拼装而成模型结构encnet_r50-d8.py、数据集Cityscapes、默认运行时日志/检查点/随机种子等与 40k 迭代训练计划学习率与val/save间隔。顶层只需覆盖裁剪尺寸并在data_preprocessor中同步size。4.1 模型基础配置模型骨架定义在 configs/base/models/encnet_r50-d8.py包含三个关键部分主干backboneResNetV1cdepth50输出out_indices(0,1,2,3)共 4 个层级采用空洞卷积策略dilations(1,1,2,4)、strides(1,2,1,1)即 D8 结构总下采样 8 倍预训练权重为open-mmlab://resnet50_v1c。解码头decode_headtypeEncHead关键参数如下——decode_headdict( typeEncHead, in_channels[512, 1024, 2048], # 取主干第 1/2/3 层输出 in_index(1, 2, 3), channels512, # 瓶颈与编码模块的通道数 num_codes32, # 码字数量 use_se_lossTrue, # 开启语义编码损失 add_lateralFalse, # 不启用侧边特征融合 dropout_ratio0.1, num_classes19, # Cityscapes 19 类 align_cornersFalse, loss_decodedict(typeCrossEntropyLoss, use_sigmoidFalse, loss_weight1.0), loss_se_decodedict(typeCrossEntropyLoss, use_sigmoidTrue, loss_weight0.2))其中loss_decode为主分割损失权重 1.0loss_se_decode为 SE-losssigmoid 多标签、权重 0.2。该结构在EncHead.__init__中的对应关系为in_channels[-1]2048经 bottleneck 降到 512 后进入EncModulese_layer输出通道等于num_classes。辅助头auxiliary_headFCNHead输入in_channels1024主干第 2 层、in_index2channels256num_convs1loss_weight0.4用于深层监督加速收敛。最后train_cfgdict()与test_cfgdict(modewhole)指定整图推理模式。4.2 不同数据集的覆盖写法ADE20K150 类encnet_r50-d8_4xb4-160k_ade20k-512x512.py 通过decode_headdict(num_classes150)与auxiliary_headdict(num_classes150)覆盖类别数crop_size(512,512)训练计划切换为 160k769x769 高分辨率encnet_r50-d8_4xb2-80k_cityscapes-769x769.py 使用cityscapes_769x769数据集配置且由于放大倍数更大align_cornersTrue同时test_cfgdict(modeslide, crop_size(769,769), stride(513,513))切换为滑窗推理窗口 769、步长 513约 2/3 重叠以缓解整图推理的内存压力轻量主干变体encnet_r50s-d8_4xb4-80k_ade20k-512x512.py 通过backbonedict(stem_channels128)得到 ResNet50sstem 通道减半PASCAL VOC 12 aug21 类encnet_r101-d8_4xb4-20k_voc12aug-512x512.py 等配置以 r50 版为基底仅覆盖pretrainedopen-mmlab://resnet101_v1c与backbonedict(depth101)即可完成主干替换体现了_base_继承机制的高复用性。五、模型结果与复现5.1 Cityscapes 官方结果以下数据来自 configs/encnet/README.md 与 configs/encnet/metafile.yaml评测环境为 4× V100 GPU、PyTorch 框架mIoU(msflip) 表示多尺度测试加水平翻转MethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(msflip)configEncNetR-50-D8512x1024400008.64.58V10075.6777.08configEncNetR-101-D8512x10244000012.12.66V10075.8177.21configEncNetR-50-D8769x769400009.81.82V10076.2477.85configEncNetR-101-D8769x7694000013.71.26V10074.2576.25configEncNetR-50-D8512x102480000--V10077.9479.13configEncNetR-101-D8512x102480000--V10078.5579.47configEncNetR-50-D8769x76980000--V10077.4478.72configEncNetR-101-D8769x76980000--V10076.1076.97config从表中可以看出规律80k 迭代比 40k 普遍高约 2 个点R-50 在 769 分辨率下反而超过 R-101属于特定配置下的实测现象直接复现即可验证。5.2 ADE20K 官方结果MethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(msflip)configEncNetR-50-D8512x5128000010.122.81V10039.5341.17configEncNetR-101-D8512x5128000013.614.87V10042.1143.61configEncNetR-50-D8512x512160000--V10040.1041.71configEncNetR-101-D8512x512160000--V10042.6144.01configmetafile.yaml中的元数据进一步说明Cityscapes 系列配置批量为 84 卡 × 2 样本/卡ADE20K 系列批量为 164 卡 × 4 样本/卡训练资源均为 4× V100且每个模型条目都附带了权重与训练日志的下载地址可直接用于结果核验。六、训练与测试命令在安装好 MMSegmentation 及其依赖见 docs/zh_cn/get_started.md并准备好对应数据集后即可用仓库自带的 tools/train.py 与 tools/test.py 复现# 单机多卡训练例如 4 卡训练 R-50-D8 40k Cityscapes bash tools/dist_train.sh configs/encnet/encnet_r50-d8_4xb2-40k_cityscapes-512x1024.py 4 # 单卡训练 python tools/train.py configs/encnet/encnet_r50-d8_4xb2-40k_cityscapes-512x1024.py # 测试加载训练好的权重并输出 mIoU python tools/test.py configs/encnet/encnet_r50-d8_4xb2-40k_cityscapes-512x1024.py \ /path/to/encnet_r50-d8_512x1024_40k_cityscapes_20200621_220958-68638a47.pthtools/test.py默认会走EncHead.predict路径即忽略 SE 分支、仅使用分割 logits并依据配置中的test_cfg.modewhole整图或slide滑窗执行推理——这正与第三节源码分析中predict的实现一一对应。七、小结EncNet 在 MMSegmentation 中的落地非常清晰Encoding层mmseg/models/utils/encoding.py负责用可学习码字压缩场景上下文EncModule用 Sigmoid 门控对特征图做类别相关重标定EncHeadmmseg/models/decode_heads/enc_head.py则通过loss_se_decode引入语义编码损失让上下文描述子同时承担辅助分类职责。整条链路只增加少量参数与计算量即可为 FCN 框架补充全局上下文建模能力这也是它作为经典基线长期保留在官方算法库中的原因。引用如需在论文或技术报告中引用 EncNet官方 README 给出的 BibTeX 如下InProceedings{Zhang_2018_CVPR, author {Zhang, Hang and Dana, Kristin and Shi, Jianping and Zhang, Zhongyue and Wang, Xiaogang and Tyagi, Ambrish and Agrawal, Amit}, title {Context Encoding for Semantic Segmentation}, booktitle {The IEEE Conference on Computer Vision and Pattern Recognition (CVPR)}, month {June}, year {2018} }【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。