
MMSegmentation 中的 CCNet十字交叉注意力语义分割的实现原理、配置解析与训练实践【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation导读CCNetCriss-Cross Network是一种以十字交叉注意力Criss-Cross Attention为核心的语义分割网络它以极低的显存与计算开销获取全图上下文信息是 OpenMMLab 语义分割工具箱 MMSegmentation 中官方收录并长期维护的经典算法之一。本文以 configs/ccnet/README.md 为骨架结合仓库中CCHead的实现源码与configs/ccnet/下的全套训练配置系统讲解 CCNet 的算法原理、MMSegmentation 中的代码实现、配置文件各字段含义以及基于 Cityscapes、ADE20K、Pascal VOC 的复现结果与训练、测试命令帮助你快速上手并在自己的数据集上复现或迁移这一算法。CCNet 算法核心以十字交叉注意力高效建模全图上下文问题动机上下文信息对语义分割至关重要上下文信息Contextual Information在语义分割、目标检测等视觉理解任务中起着决定性作用。一个像素的分类往往不能只看自身局部的颜色与纹理还需要借助其周围乃至全图的语义线索。早期方法中non-local 类模块虽然能建模全图依赖但其注意力图在空间维度上是 O(HW × HW) 的规模显存占用与计算量都随特征图尺寸急剧膨胀难以在分割任务常见的大分辨率输入上使用。CCNet 提出了一种全新的思路不直接计算全图任意两像素之间的两两关系而是先让每个像素只收集其所在十字路径同一行与同一列上的上下文信息再通过一次循环recurrence操作让信息沿十字路径在图中传播最终使每个像素都能捕获到全图范围的依赖关系。方法要点循环十字交叉注意力 类别一致损失从 configs/ccnet/README.md 的 Abstract 可以归纳出 CCNet 的三大核心贡献十字交叉注意力模块Criss-Cross Attention Module对每个像素该模块沿其所在行与列构成的十字路径聚合上下文单次操作的计算规模从全图 O(HW × HW) 降为 O(HW × (HW))显存友好。循环操作Recurrent Operation将十字交叉注意力模块串联执行两次recurrence2信息即可沿十字路径传播到全图每个像素最终捕获完整图像依赖而不需要显式地计算全图两两相似度。类别一致损失Category Consistent Loss进一步约束十字交叉注意力模块产生更具判别性的特征。论文报告了两项关键效率收益见 README Abstract属论文声称数据相比 non-local block循环十字交叉注意力模块的显存占用降低约 11 倍FLOPs 减少约 85%。这正是 CCNet 被广泛用于高分辨率分割任务的核心原因。效率与效果的平衡在 MMSegmentation 收录的配置中CCNet 的解码头直接在 ResNet 主干输出的高分辨率特征如 Cityscapes 的 512×1024、769×769上工作正是因为十字交叉注意力的线性复杂度相对特征图边长使其能够承受大分辨率输入。这一点可以从下方结果表中显存占用612.2 GB与推理速度1.0120.89 fpsV100中直观看出。MMSegmentation 中的源码实现CCHead 与 CrissCrossAttentionCCHead一个继承了 FCNHead 的解码头在 MMSegmentation 中CCNet 的解码头实现在 mmseg/models/decode_heads/cc_head.py并通过MODELS.register_module()注册为CCHead。其类结构要点如下MODELS.register_module() class CCHead(FCNHead): CCNet: Criss-Cross Attention for Semantic Segmentation... def __init__(self, recurrence2, **kwargs): if CrissCrossAttention is None: raise RuntimeError(Please install mmcv-full for CrissCrossAttention ops) super().__init__(num_convs2, **kwargs) self.recurrence recurrence self.cca CrissCrossAttention(self.channels) def forward(self, inputs): x self._transform_inputs(inputs) output self.convs0 for _ in range(self.recurrence): output self.cca(output) output self.convs1 if self.concat_input: output self.conv_cat(torch.cat([x, output], dim1)) output self.cls_seg(output) return output从源码可以确认以下实现事实CCHead 继承自 FCNHead见 mmseg/models/decode_heads/fcn_head.py其内部卷积结构由 FCNHead 以num_convs2构建先通过第一个卷积把主干特征从in_channels如 2048降到channels如 512再在两层卷积之间循环插入recurrence次十字交叉注意力模块最后经cls_seg逐像素分类。核心算子来自 mmcv.opsCrissCrossAttention由mmcv.ops提供from mmcv.ops import CrissCrossAttention并以self.cca CrissCrossAttention(self.channels)实例化。若环境中缺少带 CUDA 算子的 mmcvCCHead 会直接抛出RuntimeError(Please install mmcv-full for CrissCrossAttention ops)这是该模块的硬性安装前提。recurrence是唯一新增参数默认值为 2对应论文中的一次循环即可捕获全图依赖的设计在配置文件中可以直接覆盖。测试验证仓库中的单元测试 tests/test_models/test_heads/test_cc_head.py 验证了 CCHead 的结构与前向过程def test_cc_head(): head CCHead(in_channels16, channels8, num_classes19) assert len(head.convs) 2 assert hasattr(head, cca) if not torch.cuda.is_available(): pytest.skip(CCHead requires CUDA) inputs [torch.randn(1, 16, 23, 23)] head, inputs to_cuda(head, inputs) outputs head(inputs)同时tests/test_models/test_forward.py 中的test_ccnet_forward使用ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py整网前向测试验证配置可加载。注意两个测试都通过pytest.skip(CCNet requires CUDA)跳过无 GPU 环境从侧面印证十字交叉注意力算子是 CUDA 实现训练与推理都需要 GPU 环境。配置解析从基础模型到完整训练方案configs/ccnet/目录共收录 16 个官方训练配置对应 R-50/R-101 主干、Cityscapes/ADE20K/Pascal VOC 数据集与 20k/40k/80k/160k 迭代数全部采用_base_继承机制组合而成。下面以最常用的 Cityscapes 配置为例逐层拆解。顶层训练配置ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py完整文件内容见 configs/ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py_base_ [ ../_base_/models/ccnet_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)它通过四个_base_分别继承模型结构、数据集配置、运行时配置、训练调度四个维度随后仅覆盖crop_size与data_preprocessor.size即可让数据预处理与模型输入尺寸对齐到 512×1024。文件名中各段的含义为r50-d8ResNet-50 主干dilated 策略为 8dilations(1, 1, 2, 4)即 stage3/4 使用膨胀卷积最终输出 stride 为 84xb24 张 GPU、每卡 batch size 2总 batch size 8见 configs/ccnet/metafile.yaml 的Batch Size: 840k训练 40000 次迭代512x1024裁剪尺寸。模型基础配置ccnet_r50-d8.py模型骨架定义在 configs/base/models/ccnet_r50-d8.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, 2, 4), strides(1, 2, 1, 1), norm_cfgnorm_cfg, norm_evalFalse, stylepytorch, contract_dilationTrue), decode_headdict( typeCCHead, in_channels2048, in_index3, channels512, recurrence2, dropout_ratio0.1, num_classes19, norm_cfgnorm_cfg, align_cornersFalse, loss_decodedict( typeCrossEntropyLoss, use_sigmoidFalse, loss_weight1.0)), auxiliary_headdict( typeFCNHead, in_channels1024, in_index2, channels256, num_convs1, concat_inputFalse, dropout_ratio0.1, num_classes19, norm_cfgnorm_cfg, align_cornersFalse, loss_decodedict( typeCrossEntropyLoss, use_sigmoidFalse, loss_weight0.4)), train_cfgdict(), test_cfgdict(modewhole))各关键字段的语义与取值如下配置字段取值含义typeCCHead—使用上面分析的十字交叉注意力解码头in_channels2048—主干 stage4 输出通道数ResNet-50 最后一层in_index3—取主干out_indices的第 3 层stride 8 特征作为解码头输入channels512—注意力模块内部的隐藏通道数也是CrissCrossAttention的输入通道recurrence2默认 2十字交叉注意力循环次数对应论文循环一次即可覆盖全图dropout_ratio0.1—分类层前的 dropout 比例num_classes19Cityscapes 为 19类别数迁移到 ADE20K 时改为 150auxiliary_headFCNHeadloss_weight0.4在主干 stage3in_index21024 通道上挂载辅助 FCN 头辅助损失权重 0.4主损失权重 1.0test_cfgdict(modewhole)—整图推理不切块pretrainedopen-mmlab://resnet50_v1c—使用 ResNetV1c 的 ImageNet 预训练权重值得注意的工程细节数据预处理SegDataPreProcessor采用 ImageNet 均值/方差mean[123.675, 116.28, 103.53]、std[58.395, 57.12, 57.375]做归一化且bgr_to_rgbTrue表示输入按 BGR 读取后转为 RGB这些是 MMSegmentation 1.x 统一的预处理约定。膨胀策略 d8dilations(1, 1, 2, 4)、strides(1, 2, 1, 1)表示 stage3 步长改为 1 并膨胀 2、stage4 膨胀 4使最终特征图保持输入尺寸的 1/8从而保留密集预测所需的空间分辨率。其他数据集的配置差异以 ADE20K 配置 configs/ccnet/ccnet_r50-d8_4xb4-80k_ade20k-512x512.py 为例它与 Cityscapes 配置的差异非常直观_base_ [ ../_base_/models/ccnet_r50-d8.py, ../_base_/datasets/ade20k.py, ../_base_/default_runtime.py, ../_base_/schedules/schedule_80k.py ] crop_size (512, 512) data_preprocessor dict(sizecrop_size) model dict( data_preprocessordata_preprocessor, decode_headdict(num_classes150), auxiliary_headdict(num_classes150))仅需三处修改即可从 Cityscapes 迁移到 ADE20K换用ade20k.py数据集配置与schedule_80k.py调度、裁剪尺寸改为 512×512、num_classes改为 150解码头与辅助头同步修改。这体现了 MMSegmentation 配置继承体系在算法迁移上的低成本优势。训练调度schedule_40k.pyconfigs/base/schedules/schedule_40k.py 定义了 CCNet 在 Cityscapes 上的训练超参优化器SGDlr0.01momentum0.9weight_decay0.0005学习率策略PolyLR多项式衰减power0.9eta_min1e-4按迭代by_epochFalse从 40000 衰减训练循环IterBasedTrainLoopmax_iters40000每 4000 迭代验证一次并保存一次 checkpoint日志钩子每 50 次迭代输出一次日志LoggerHook。官方复现结果与模型configs/ccnet/README.md记录了 CCNet 在三个主流分割基准上的完整复现结果指标由官方训练日志统计测试设备为 V100msflip 表示多尺度 翻转测试。以下结果表中的配置文件链接均已转换为仓库内相对路径权重与训练日志的下载地址收录于 configs/ccnet/metafile.yaml可通过mim search mmsegmentation --model ccnet或模型下载工具按Name字段获取。Cityscapes19 类训练 40000 / 80000 迭代MethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(msflip)configCCNetR-50-D8512x1024400006.03.32V10077.7678.87configCCNetR-101-D8512x1024400009.52.31V10076.3578.19configCCNetR-50-D8769x769400006.81.43V10078.4679.93configCCNetR-101-D8769x7694000010.71.01V10076.9478.62configCCNetR-50-D8512x102480000--V10079.0380.16configCCNetR-101-D8512x102480000--V10078.8779.90configCCNetR-50-D8769x76980000--V10079.2981.08configCCNetR-101-D8769x76980000--V10079.4580.66configADE20K150 类训练 80000 / 160000 迭代MethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(msflip)configCCNetR-50-D8512x512800008.820.89V10041.7842.98configCCNetR-101-D8512x5128000012.214.11V10043.9745.13configCCNetR-50-D8512x512160000--V10042.0843.13configCCNetR-101-D8512x512160000--V10043.7145.04configPascal VOC 2012 Aug21 类训练 20000 / 40000 迭代MethodBackboneCrop SizeLr schdMem (GB)Inf time (fps)DevicemIoUmIoU(msflip)configCCNetR-50-D8512x512200006.020.45V10076.1777.51configCCNetR-101-D8512x512200009.513.64V10077.2779.02configCCNetR-50-D8512x51240000--V10075.9677.04configCCNetR-101-D8512x51240000--V10077.8778.90config从结果可以归纳出两条可复用的工程经验长训练更有利Cityscapes 上 40k → 80k 迭代R-50-D8 在 512×1024 下 mIoU 从 77.76 提升到 79.03R-101-D8 在 769×769 下更达到 79.45msflip 81.08说明 CCNet 在大迭代数下能更充分地发挥循环注意力的建模能力大裁剪尺寸收益明显Cityscapes 上 769×769 普遍优于 512×1024如 R-50-D8 80k 时 79.29 vs 79.03代价是显存与推理时间上升40000 迭代下显存 6.0 → 6.8 GB推理 3.32 → 1.43 fps。训练与测试实操在完成数据准备Cityscapes、ADE20K、Pascal VOC 的目录组织方式参见 docs/zh_cn/user_guides/2_dataset_prepare.md 或英文版 docs/en/user_guides/2_dataset_prepare.md并确保环境安装了包含CrissCrossAttentionCUDA 算子的 mmcv 后即可直接使用仓库提供的脚本训练与评测。单机多卡训练bash tools/dist_train.sh configs/ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py 4单卡训练python tools/train.py configs/ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py测试与精度复现# 单卡测试需将 checkpoint 替换为 metafile.yaml 中对应模型的权重路径 python tools/test.py configs/ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py checkpoint --eval mIoU # 多卡测试 bash tools/dist_test.sh configs/ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py checkpoint 4 --eval mIoU若需要复现表中的mIoU(msflip)可在测试命令中追加--aug-test开启多尺度 翻转测试tools/test.py与tools/train.py均支持--cfg-options xxxyyy覆盖配置字段详见 docs/en/user_guides/1_config.md例如临时修改类别数或学习率无需改动原配置文件。训练入口tools/train.py会按schedule_40k.py中的CheckpointHook每 4000 迭代自动保存权重与日志便于中途接续训练与监控曲线。迁移到自定义数据集基于上述配置继承机制将 CCNet 迁移到自己的数据集只需三步准备数据集按 MMSegmentation 的标准目录结构组织图像与标注参考 docs/zh_cn/user_guides/2_dataset_prepare.md 或直接仿照 configs/base/datasets/cityscapes.py 新建数据集配置修改data_root、metainfo.classes与palette新建模型配置复制 configs/ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py将_base_中的数据集配置替换为自己的数据集并在decode_head、auxiliary_head中把num_classes改为自己的类别数同时调整crop_size与data_preprocessor.size调整训练调度根据数据规模修改_base_/schedules/中的max_iters、val_interval与学习率或在命令行用--cfg-options覆盖。引用若在论文或项目中使用了 CCNet 或本文介绍的复现配置可引用以下文献源自 configs/ccnet/README.md 的 Citation 部分article{huang2018ccnet, title{CCNet: Criss-Cross Attention for Semantic Segmentation}, author{Huang, Zilong and Wang, Xinggang and Huang, Lichao and Huang, Chang and Wei, Yunchao and Liu, Wenyu}, booktitle{ICCV}, year{2019} }小结CCNet 通过十字交叉注意力 循环传播这一精巧设计以接近线性的显存与算力开销逼近全图上下文建模效果是 MMSegmentation 中兼顾效率与精度的高性价比解码头之一。本文从 configs/ccnet/README.md 出发结合 mmseg/models/decode_heads/cc_head.py 的实现、configs/base/models/ccnet_r50-d8.py 的配置细节与官方复现结果完整覆盖了从原理、源码到训练评测的全链路。需要进一步探索时可以继续阅读仓库的模型配置全集 configs/ccnet/、元信息文件 configs/ccnet/metafile.yaml以及单测 tests/test_models/test_heads/test_cc_head.py 验证你对模块行为的理解。【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考