MMSegmentation 中的 BEiT 骨干网络:从权重转换到 ADE20K 语义分割实战
【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation
BEiT(Bidirectional Encoder representation from Image Transformers)是微软提出的基于掩码图像建模的自监督视觉 Transformer 预训练方法。本文以 configs/beit/README.md 为主线,结合 MMSegmentation 仓库中的源码与配置文件,完整讲解如何在当前仓库中使用 BEiT 作为骨干网络进行语义分割:包括预训练权重键名转换、UPerNet 训练配置解读、单尺度与多尺度滑动窗口推理,以及 ADE20K 上的公开基准结果。
BEiT 方法简介
BEiT 论文发表于 ICLR 2022(arXiv:2106.08254),核心思想是将自然语言处理中 BERT 的预训练范式迁移到视觉领域。其预训练流程包含两个视图:
- 图像块(image patches):将图像切分为例如 16×16 像素的块;
- 视觉词元(visual tokens):通过离散 tokenizer 将原始图像"分词"为离散 token。
预训练时随机掩码一部分图像块输入骨干 Transformer,训练目标是从被破坏的图像块中恢复原始视觉 token。预训练完成后,直接在编码器上追加任务层对下游任务进行微调。
论文报告的分类结果表明该方法的竞争力:base 规模的 BEiT 在 ImageNet-1K 上达到 83.2% top-1 准确率,明显优于相同设置下从零训练的 DeiT(81.8%);large 规模仅用 ImageNet-1K 即达到 86.3%,甚至超过在 ImageNet-22K 上监督预训练的 ViT-L(85.2%)。
MMSegmentation 当前仓库在configs/beit/目录下提供了 BEiT-Base 与 BEiT-Large 搭配 UPerNet 的完整语义分割方案,覆盖 ADE20K 数据集的训练与测试配置。
MMSegmentation 中的 BEiT 骨干实现
骨干网络源码结构
BEiT 骨干网络实现在 mmseg/models/backbones/beit.py,共 554 行,包含以下核心模块:
- BEiTAttention:基于窗口的多头自注意力(W-MSA),并带有相对位置偏置。其
bias参数支持qv_bias(仅给 q、v 加可学习偏置)、True(q、k、v 都加)与False(不加)三种模式; - 相对位置编码:
_init_rel_pos_embedding中构建(2*Wh-1)*(2*Ww-1)+3大小的相对位置偏置表,额外 3 项分别对应 cls-to-token、token-to-cls、cls-to-cls 的相对距离; - TransformerEncoderLayer 复用:文件头部
from .vit import TransformerEncoderLayer as VisionTransformerEncoderLayer,说明其编码器层复用了 mmseg/models/backbones/vit.py 中的实现。
从源码结构可以推断,BEiT 在分割场景中与 ViT 共享大量 Transformer 基础组件,差异主要集中在带相对位置偏置的窗口注意力机制上——这正是 BEiT 与普通 ViT 的关键区别。
骨干注册与配置入口
BEiT 骨干以type='BEiT'形式注册在MODELSregistry 中,通过 configs/base/models/upernet_beit.py 提供默认配置:
backbone=dict( type='BEiT', img_size=(640, 640), patch_size=16, in_channels=3, embed_dims=768, num_layers=12, num_heads=12, mlp_ratio=4, out_indices=(3, 5, 7, 11), qv_bias=True, attn_drop_rate=0.0, drop_path_rate=0.1, norm_cfg=dict(type='LN', eps=1e-6), act_cfg=dict(type='GELU'), norm_eval=False, init_values=0.1),各参数含义:
| 参数 | 说明 |
|---|---|
img_size | 输入图像尺寸,语义分割中固定为 (640, 640) |
patch_size | 图像块大小,BEiT 使用 16×16 |
embed_dims | 特征嵌入维度,Base 为 768,Large 为 1024 |
num_layers/num_heads | Transformer 层数与注意力头数(Base 为 12/12,Large 为 24/16) |
mlp_ratio | FFN 隐藏层放大比例,此处为 4 |
out_indices | 输出特征层索引,取第 3、5、7、11(或 Large 的第 7、11、15、23)层作为多尺度特征 |
qv_bias | 仅给 q、v 加可学习偏置(对应论文实现) |
init_values | LayerScale 初始值 |
UPerNet 分割头通过neck=dict(type='Feature2Pyramid', embed_dim=768, rescales=[4, 2, 1, 0.5])将四层同维特征(BEiT 各层输出维度相同,均为embed_dims)通过不同缩放比例重建为金字塔特征,再送入UPerHead解码。
预训练权重转换:beit2mmseg.py
官方 BEiT 预训练权重的键名(key)与 MMSegmentation 风格不一致,直接加载会报错。仓库在 tools/model_converters/beit2mmseg.py 提供了键名转换脚本,其核心逻辑convert_beit完成三类映射:
| 官方键名模式 | 转换后键名 |
|---|---|
patch_embed.proj.* | patch_embed.projection.* |
blocks.*.norm.* | layers.*.ln.* |
blocks.*.mlp.fc1.*/blocks.*.mlp.fc2.* | layers.*.ffn.layers.0.0.*/layers.*.ffn.layers.1.* |
blocks.*(其余子键) | layers.* |
脚本使用mmengine.runner.CheckpointLoader.load_checkpoint加载权重,自动兼容state_dict、model或裸权重三种 checkpoint 格式,转换后经torch.save保存到目标路径。
使用方法:
python tools/model_converters/beit2mmseg.py ${PRETRAIN_PATH} ${STORE_PATH}PRETRAIN_PATH为官方预训练权重路径或 URL,STORE_PATH为转换后权重的保存路径。README 给出的实际示例:
python tools/model_converters/beit2mmseg.py https://conversationhub.blob.core.windows.net/beit-share-public/beit/beit_base_patch16_224_pt22k_ft22k.pth pretrain/beit_base_patch16_224_pt22k_ft22k.pth当前仓库默认设置下使用的两个预训练权重及其来源对应关系如下:
| 转换后权重 | 原始官方权重 |
|---|---|
| BEiT_base.pth | BEiT_base(patch16, 224×224, ImageNet-22K 预训练+微调) |
| BEiT_large.pth | BEiT_large(patch16, 224×224, ImageNet-22K 预训练+微调) |
转换完成后,将权重放置在配置中pretrained字段指定的路径(默认pretrain/目录)即可被训练/测试流程加载。
训练配置详解
BEiT-Base + UPerNet
configs/beit/beit-base_upernet_8xb2-160k_ade20k-640x640.py 是 Base 模型的训练配置,继承自四个基础配置:
../_base_/models/upernet_beit.py:BEiT+UPerNet 模型定义;../_base_/datasets/ade20k_640x640.py:ADE20K 数据集配置;../_base_/default_runtime.py:默认运行环境;../_base_/schedules/schedule_160k.py:160k 迭代训练计划。
关键训练设置:
optim_wrapper = dict( _delete_=True, type='OptimWrapper', optimizer=dict( type='AdamW', lr=3e-5, betas=(0.9, 0.999), weight_decay=0.05), constructor='LayerDecayOptimizerConstructor', paramwise_cfg=dict(num_layers=12, layer_decay_rate=0.9)) param_scheduler = [ dict( type='LinearLR', start_factor=1e-6, by_epoch=False, begin=0, end=1500), dict( type='PolyLR', power=1.0, begin=1500, end=160000, eta_min=0.0, by_epoch=False, ) ]要点解读:
- 采用AdamW 优化器,学习率 3e-5,权重衰减 0.05;
_delete_=True表示覆盖基配置中的默认优化器; LayerDecayOptimizerConstructor分层衰减:layer_decay_rate=0.9,num_layers=12,浅层参数学习率更低、深层更高,这是 Transformer 微调中抑制浅层剧烈更新的常用策略;- 两阶段学习率调度:前 1500 次迭代用
LinearLR(起始因子 1e-6)做 warmup,之后切换为power=1.0的PolyLR直到 160k 迭代结束; - 数据并行:默认 8 张 GPU、每卡 2 张图(
train_dataloader = dict(batch_size=2)),即有效 batch size 为 16;验证与测试每卡 1 张。
BEiT-Large + UPerNet(AMP 训练)
configs/beit/beit-large_upernet_8xb1-amp-160k_ade20k-640x640.py 是 Large 模型配置,与 Base 版本的关键差异:
| 配置项 | BEiT-Base | BEiT-Large |
|---|---|---|
embed_dims | 768 | 1024 |
num_layers | 12 | 24 |
num_heads | 12 | 16 |
drop_path_rate | 0.1 | 0.2 |
out_indices | (3, 5, 7, 11) | (7, 11, 15, 23) |
layer_decay_rate | 0.9 | 0.95 |
| 学习率 | 3e-5 | 2e-5 |
| 优化器包装 | OptimWrapper | AmpOptimWrapper |
| 每卡 batch size | 2 | 1(accumulative_counts=2梯度累积) |
| 训练计划 | schedule_160k | schedule_320k |
Large 配置通过AmpOptimWrapper启用自动混合精度(AMP)训练,配合accumulative_counts=2梯度累积,在每卡仅 1 张图(8 卡有效 batch size 为 8)的条件下模拟更大的 batch。由于模型更深(24 层),drop_path_rate提高到 0.2 以增强正则化,分层衰减率提高到 0.95。
注意:Large 配置中学习率调度器的end为 160000,而继承的计划为 320k 迭代——从配置结构看这属于该文件的既有设定,使用时请以实际迭代计划为准(README 结果表中 Large 记为 320000 迭代)。
ADE20K 数据与预处理
configs/base/datasets/ade20k_640x640.py 定义训练数据流:
- 随机缩放:
RandomResize以(2560, 640)为基准尺度、ratio_range=(0.5, 2.0)随机缩放并保持比例; - 随机裁剪:
RandomCrop裁剪到 640×640,cat_max_ratio=0.75限制裁剪区域内单一类别占比不超过 75%,避免裁剪到大面积同质区域; - 数据增强:
RandomFlip(概率 0.5)与PhotoMetricDistortion(光度扰动); - 类别处理:
LoadAnnotations使用reduce_zero_label=True,ADE20K 索引 0 的背景类被折叠,因此模型输出num_classes=150。
训练数据前缀为images/training与annotations/training,数据根目录默认data/ade/ADEChallengeData2016,需要用户预先按该结构准备数据。
测试与推理
单尺度测试
README 提供的单尺度验证命令(权重文件名为当前仓库发布版对应名称,命令中的旧配置文件名在新版本中已更名为上文所述配置):
sh tools/dist_test.sh \ configs/beit/beit-large_upernet_8xb1-amp-160k_ade20k-640x640.py \ upernet_beit-large_fp16_8x1_640x640_160k_ade20k-8fc0dd5d.pth $GPUS --eval mIoU$GPUS为使用的 GPU 数量,--eval mIoU指定评估指标为 mIoU。
多尺度滑动窗口测试
由于 BEiT 的相对位置编码要求输入的长和宽相等,MMSegmentation 采用**滑动窗口(slide)**策略进行多尺度推理,将最短边固定为 640(min_size=640),因此多尺度推理需要单独执行_ms配置,而不是使用通用的--aug-test参数:
sh tools/dist_test.sh \ configs/beit/beit-large_upernet_8xb1-amp-160k_ade20k-640x640_ms.py \ upernet_beit-large_fp16_8x1_640x640_160k_ade20k-8fc0dd5d.pth $GPUS --eval mIoU对应的多尺度配置 configs/beit/beit-large_upernet_8xb1-amp-160k_ade20k-640x640_ms.py 通过覆盖test_pipeline实现:
test_pipeline = [ dict(type='LoadImageFromFile'), # img_ratios is [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] # original image scale is (2560, 640) dict(type='Resize', scale=(2560, 640), keep_ratio=True), dict(type='LoadAnnotations', reduce_zero_label=True), dict(type='PackSegInputs'), ]推理流程为:将原图按(2560, 640)缩放保持比例,再以test_cfg=dict(mode='slide', crop_size=(640, 640), stride=(426, 426))滑动窗口切块推理并拼接。其中 stride 取 640 的 2/3(426),保证窗口间有重叠,缓解边界伪影。Base 与 Large 配置的test_cfg均为该滑动窗口设置。
ADE20K 基准结果
README 记录了 UPerNet 搭配两种 BEiT 骨干在 ADE20K 验证集上的结果:
| Method | Backbone | Crop Size | pretrain | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) |
|---|---|---|---|---|---|---|---|---|---|---|
| UPerNet | BEiT-B | 640x640 | ImageNet-22K | 16 | 160000 | 15.88 | 2.00 | V100 | 53.08 | 53.84 |
| UPerNet | BEiT-L | 640x640 | ImageNet-22K | 8 | 320000 | 22.64 | 0.96 | V100 | 56.33 | 56.84 |
对应训练配置为 beit-base_upernet_8xb2-160k_ade20k-640x640.py 与 beit-large_upernet_8xb1-amp-160k_ade20k-640x640.py。其中"ms+flip"列对应多尺度+水平翻转融合的结果,即通过_ms配置与滑动窗口推理获得。模型权重与训练日志的下载地址以仓库 configs/beit/metafile.yaml 中登记的信息为准。
总结
BEiT 在 MMSegmentation 中的落地路径清晰完整:通过 beit2mmseg.py 完成官方权重键名转换,复用 beit.py 中带相对位置偏置的窗口注意力骨干,以 UPerNet 为解码头在 ADE20K 上达到 53.08(BEiT-B)与 56.33(BEiT-L)的 mIoU。实操中的两个关键经验是:相对位置编码要求方形输入,多尺度推理必须走滑动窗口配置;Transformer 微调建议使用 LayerDecay 分层衰减与较小的 AdamW 学习率。
引用
若在研究中引用 BEiT,请使用以下 BibTeX:
@inproceedings{beit, title={{BEiT}: {BERT} Pre-Training of Image Transformers}, author={Hangbo Bao and Li Dong and Songhao Piao and Furu Wei}, booktitle={International Conference on Learning Representations}, year={2022}, url={https://openreview.net/forum?id=p-BhZSz59o4} }【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考