
简介面向计算机视觉语义分割方向的开发者、研究生和竞赛选手这份资源集合了 Swin Transformer 在语义分割任务上的开源实现与配套数据。压缩包共含 2000 个文件其中 1362 张 jpg 图片对应 ADE20K 等常见分割数据集的训练样本570 个 py 脚本覆盖模型结构定义、训练循环、测试与评估46 个 md 文档用于说明配置与使用流程另有 11 个 txt、6 个 xml、4 个 sh 和 1 个 yaml 配置文件辅助环境部署与参数调整整体约 833.83MB。目前已有 65 人浏览学习。借助这份资源可深入理解 Swin Transformer 窗口自注意力与移位窗口机制如何应用于像素级分类任务掌握从数据加载、图像预处理、损失计算、优化器选择到模型测试与评估指标计算的完整链路。同时压缩包内附原始分割数据集图片可直接用于 CityScapes、ADE20K 等基准的模型训练与结果验证减少前期数据收集整理时间适合作为该方向实验对比和课题研究的基础参考。1. 拿到 Swin-Transformer 语义分割项目权重单独放一个 zip 里到底该怎么接第一次从压缩包里解出Swin-Transformer-Semantic-Segmentation权重在另外那里.zip这种命名时我是有点懵的。代码里pretrained路径指向的权重文件一个都不在全被单独塞进了另一个 zip模型初始化一跑就报FileNotFoundError。很多入门的人在这一步直接放弃以为是包坏了其实不是只是这个项目的作者习惯把权重和代码分开存放——权重体积大动不动几百 MB单独打 zip 方便传输代价就是使用者必须自己把权重放回代码预期的路径。这个资源解决的就是这件事它是一整套 Swin Transformer 做语义分割的源码包配好了配置文件、训练脚本和推理入口唯一要动手的是把权重 zip 解压后放到正确位置。适合刚接触 Swin-Transformer、想跑通语义分割模型又不想从头搭环境的人也适合想改 backbone 做对比实验的熟手。我的建议很直接先别急着训练先把权重路径理顺这一步理顺了后面全是顺的。2. 为什么要单独放权重Swim Transformer 的预训练机制与项目结构2.1 Swin Transformer 做分割为什么离不开 ImageNet 预训练权重Swin Transformer 全称是 Shifted Window Transformer核心思路是把自注意力限制在不重叠的窗口内再通过移位窗口跨窗口交互。相比 ViT 的全局注意力它的计算复杂度从输入尺寸的平方降到线性这让它特别适合密集预测任务也就是语义分割。用它做分割的典型做法是当 backbone后面接 FPN 或 UPerHead 这类解码头项目里用的就是 UPerHead。但 Swin Transformer 从零开始训练收敛非常慢尤其在小数据集上几十个 epoch 下去 mIoU 可能还是个位数。所以几乎所有公开实现都要加载 ImageNet-22K 或 ImageNet-1K 预训练权重。这份资源的代码仓库里配置文件写死了pretrained字段指向某个权重路径但权重被作者单独打包了这就是「权重在另外那里」的含义。2.2 项目目录里应该有哪些东西解压后按正常情况你会看到这样的核心目录结构Swin-Transformer-Semantic-Segmentation/ ├── configs/ │ ├── swin/ │ │ ├── swin_tiny_patch4_window7_224.yaml │ │ └── swin_base_patch4_window7_224.yaml ├── mmseg/ │ ├── models/ │ │ ├── backbones/ │ │ └── segmentors/ ├── tools/ │ ├── train.py │ └── test.py ├── weights/ # 这个目录在压缩包里经常是空的 └── README.md注意看weights/目录如果解压后发现它是空的或者干脆不存在说明权重的确被单独打包了。这些 yaml 是 mmsegmentation 风格的配置文件里面会写明 backbone 类型、预训练权重地址、训练轮数和学习率策略。你需要把权重 zip 解压后放进weights/目录或者修改配置文件里的路径指向你实际存放的位置。常见做法是把权重放在项目根目录下的weights/里然后统一用相对路径引用。这样项目整体迁移时不用改配置这是我比较推荐的整理方式。如果你把权重放在别处比如自定义目录那就必须同步修改所有配置文件里的pretrained字段否则训练脚本会在加载第一步就挂掉。3. 权重的正确接法从解压到训练脚本能识别3.1 第一步先把压缩包解开并验证完整性拿到 zip 第一件事不是解压是看一眼大小。Swin-Tiny 的 ImageNet-1K 预训练权重大约 100MB 出头Swin-Base 的 22K 权重在 400MB 以上。如果 zip 解压出来文件只有几 MB基本可以断定权重不完整后面怎么配置都白搭。# 解压权重 zip 到项目 weights 目录 unzip swin_tiny_patch4_window7_224.pth.zip -d weights/ # 验证文件类型 file weights/swin_tiny_patch4_window7_224.pth # 验证是否为有效 PyTorch 权重文件 python -c import torch ckpt torch.load(weights/swin_tiny_patch4_window7_224.pth, map_locationcpu) print(type(ckpt)) if isinstance(ckpt, dict): print(ckpt.keys()) torch.load加载后如果是 dict通常会包含state_dict或model这类键。直接打印出来核对能确认权重文件没有损坏。如果文件本身完整但加载报错极可能是 PyTorch 版本不一致导致的序列化兼容问题这个在避坑章节详细说。3.2 修改配置让训练脚本找到权重解压完成后打开configs/swin/swin_tiny_patch4_window7_224.yaml找到模型初始化部分model: type: EncoderDecoder backbone: type: SwinTransformer embed_dim: 96 depths: [2, 2, 6, 2] num_heads: [3, 6, 12, 24] window_size: 7 ape: False drop_path_rate: 0.1 patch_norm: True pretrained: ../../weights/swin_tiny_patch4_window7_224.pth重点看pretrained这一行。这个路径是相对configs/swin/目录来算的../../weights/就是从configs/swin/往上跳两级回到项目根目录再进入weights/。如果你的权重 zip 没有解压到weights/或者文件名不对这里就会报错。我一般会做的操作是先把pretrained改成绝对路径跑一次确认权重本身能被加载再把路径改回相对路径做最终配置。原因是绝对路径能排除路径计算错误这个变量如果绝对路径能跑通但相对路径报错那就是../../的层级算错了。3.3 训练脚本启动参数与常见传参方式mmsegmentation 风格的训练脚本支持命令行覆盖配置项这意味着你不一定非要改 yaml 文件python tools/train.py configs/swin/swin_tiny_patch4_window7_224.yaml \ --work-dir work_dirs/swin_tiny \ --options model.backbone.pretrainedweights/swin_tiny_patch4_window7_224.pth--options后面跟的是配置覆盖项点号分隔的是配置层级。model.backbone.pretrained对应的就是 yaml 里那个pretrained字段。路径相对命令行执行目录来解析这里就是相对项目根目录。这个做法的好处是配置文件和权重路径解耦尤其适合多台机器交替训练的场景。比如我在服务器 A 上权重放在/data/weights/在服务器 B 上放在/home/user/weights/yaml 文件完全不用动只靠命令行参数切换即可。4. 权重加载背后的事key 匹配规则与严格加载模式4.1 权重文件里的 key 和模型 state_dict 的对应关系很多人以为把权重文件路径配好就万事大吉实际上报了Missing key(s) in state_dict或Unexpected key(s)才是常态。原因在于 Swin Transformer 权重的训练方式和你的模型定义之间存在差异。import torch from mmseg.models.backbones import SwinTransformer model SwinTransformer( embed_dim96, depths[2, 2, 6, 2], num_heads[3, 6, 12, 24], window_size7, ) ckpt torch.load(weights/swin_tiny_patch4_window7_224.pth, map_locationcpu) state_dict ckpt.get(state_dict, ckpt) missing, unexpected model.load_state_dict(state_dict, strictFalse) print(missing keys:, len(missing)) print(unexpected keys:, len(unexpected))strictFalse是调试阶段的关键参数。它会告诉你哪些 key 在模型里但没有在权重文件里哪些 key 在权重文件里但模型用不上。前者通常出现在你改了模型的层结构时后者常见于权重文件里带着分类头或norm层的参数而分割模型只需要 backbone 部分。常见情况是unexpected keys里有一堆head.*或者norm.*的 key这不是错误因为预训练权重是为分类任务训练的它最后的分类层参数对分割任务没有意义。真正要警惕的是missing keys里出现backbone.*相关项那说明权重文件和模型结构对不上十有八九是下错了权重版本。4.2 mmseg 里的加载逻辑是怎样的mmsegmentation 在加载预训练权重时会先读取配置里的pretrained路径然后做一层兼容处理如果权重文件是完整的 dict含state_dict键就取state_dict来加载如果直接是权重字典就原样加载。还会自动过滤掉分类头相关的层只保留 backbone 能用的部分。# mmseg 内部加载预训练权重的实际过滤逻辑 checkpoint torch.load(pretrained_path, map_locationcpu) if state_dict in checkpoint: state_dict checkpoint[state_dict] else: state_dict checkpoint # 过滤掉非 backbone 层的 key for k in list(state_dict.keys()): if not k.startswith(backbone.): state_dict.pop(k)这段过滤逻辑保证了分类预训练权重能干净地迁移到分割模型上。如果你自己写权重加载也应保留这一步否则head层的维度不匹配会直接报错。这也是为什么很多人直接拿torch.load()加载后塞给模型会翻车而 mmseg 能稳定工作的原因。5. 权重接入避坑路径、版本和数据格式的四个常见问题5.1 现象FileNotFoundError权重路径打不开原因权重 zip 解压到了错误目录或者pretrained路径写的是绝对路径换机器后失效。解决先确认文件实际位置用ls weights/查看。然后用绝对路径测试能跑通后改成相对路径。注意相对路径的基准点是配置文件所在目录不是命令行执行目录这是最容易混淆的地方。5.2 现象KeyError: state_dict加载权重时报错原因权重文件本身是纯 state_dict 字典没有state_dict外层包装直接索引就会报错。解决ckpt torch.load(weights/swin_tiny_patch4_window7_224.pth, map_locationcpu) if state_dict in ckpt: state_dict ckpt[state_dict] elif model in ckpt: state_dict ckpt[model] else: state_dict ckpt这个兼容写法几乎是必须的因为不同来源的权重文件包装方式完全不同。有的来自 mmseg 官方有的来自 Swin Transformer 原仓库有的来自第三方训练好的分割模型每个的嵌套结构都不一样。5.3 现象size mismatch for backbone.patch_embed.proj.weight维度对不上原因你拿 Swin-Base 的权重去加载 Swin-Tiny 的模型embed_dim 一个是 128 一个是 96patch_embed的卷积核通道数不同。解决严格匹配配置文件里的embed_dim和depths下载对应尺寸的权重。Swin-Tiny 用的是embed_dim96Swin-Base 用embed_dim128Swin-Large 是embed_dim192。权重文件里patch_embed.proj.weight的形状会直接暴露尺寸加载前先打印检查一遍。5.4 现象AttributeError: NoneType object has no attribute shape加载后训练崩原因pretrained字段被显式设置成了None或者配置文件里这个字段被漏掉了导致模型拿到了空权重还在继续跑。解决检查配置文件里pretrained是否被意外覆盖特别是用了--options命令行传参时。我踩过一次忘记把pretrained传进去配置文件里默认是None结果模型跑了一个 epoch 才发现所有指标都是噪声白白浪费半天算力。5.5 现象zip 解压报CRC failed权重文件不完整原因传输过程中 zip 损坏或者网盘下载限速导致文件被截断。解决重新下载前先对比文件大小确认和发布者标注的一致。解压时加-t参数测试完整性unzip -t weights.zip如果输出里没有No errors detected就说明文件坏了直接重新下载别浪费时间想着修复。6. 验证权重真的接上了一次推理测试搞定所有疑虑权重路径配好之后别急着跑训练先用推理模式验证一遍。项目自带的tools/test.py支持单图测试加载权重后输出分割掩膜能跑通就说明整个链路是通的。python tools/test.py configs/swin/swin_tiny_patch4_window7_224.yaml \ work_dirs/swin_tiny/epoch_100.pth \ --eval mIoU训练完成后这个命令会输出各类别的 IoU 和平均 mIoU。第一次跑的话我更建议用--show参数把结果图存下来直接看分割效果比只看数字直观得多。预期 Swin-Tiny 在 ADE20K 上能达到 44% 左右的 mIoU如果差距超过 5 个百分点且你的数据集不是小规模微调那就要回头看配置和权重是否匹配。有一点值得提如果你是在自己的小数据集上微调加载预训练权重后第一轮 epoch 的 loss 应该明显低于随机初始化。如果第一轮 loss 反而很高那不是权重加载失败就是数据加载环节出了偏差比如没有做归一化图片像素范围还是 0 到 255而模型预期的是 0 到 1。从那以后我每次接这种「权重单独放」的项目都会强制走一遍拆包、验证、路径确认、单图推理的流程确认输出掩膜的形状和类别数符合预期后再放开训练。模型能不能收敛看调参但权重接不上这种低级错误绝不该浪费第二次训练时间。希望帮到你。本文还有配套的精品资源点击获取