SETR复现实战:从ViT编码器到三种解码器的语义分割全解析

发布时间:2026/10/22 13:28:14
SETR复现实战:从ViT编码器到三种解码器的语义分割全解析 2020年12月我啃完了SETRSegmentation Transformer的预印本。那阵子我正被深度学习的语义分割精度卡在瓶颈上白天还在调扩张卷积的参数晚上翻到这篇把Transformer直接搬进分割网络的文章几乎等于把我的惯性思路翻了个底朝天。如果你也做过语义分割的复现一定对DeepLabV3那套扩张卷积、ASPP、级联解码器熟得不能再熟但在2020年底这个时间点上SETR出现的意义不是又刷高了一个点的mIoU而是它用完全不同的序列建模思路把“分割到底该怎么看”这个问题重新问了一遍。这篇文章不是论文翻译也不是纯理论分析而是我以一个深度学习研究者的身份从第一次接触SETR到动手复现、踩坑、对比实验的完整记录。包括ViT编码器怎么切Patch、三种解码器设计的意图、位置编码在变分辨率下的处理、预训练权重对收敛的致命影响以及它在实际数据上到底比CNN方法强在哪、弱在哪。不管你是学生准备入门Transformer分割还是工程上在选型分割方案这篇文章都能让你少走一段弯路。1. 与CNN方法反复撞击后为什么SETR让我眼前一亮1.1 从FCN到DeepLab分割任务的“感受野焦虑”在SETR出现之前语义分割的主流先按距离卷卷积网络这套思路从FCN开始基本定型。FCN把分类网络的全连接层换成卷积层让网络能输出逐像素的类别概率但受限于有限的感受野它只能局部地看问题。后来各类方法本质上都在做一件事让网络看到更大的范围同时不把边界细节磨平。DeepLab系列给出的方案是扩张卷积通过控制膨胀率扩大感受野PSPNet则是用金字塔池化把不同尺度的上下文信息汇总进来。我印象很深的是实验里一个常见现象对于类别上下文强相关的场景比如图里有“船”那么周围大概率有“水”图里有一块“轮胎”旁边很可能有“汽车”。CNN方法在做这类推理时经常不如人意哪怕ASPP已经抓了多尺度信息还是会在大物体中央产生空洞预测或者在语义边界处把两类混淆。这不是调参能完全解决的问题而是结构层面的限制卷积核的大小和层数决定了网络“看到的范围”永远有个上限。1.2 把分割当成序列到序列的任务到底意味着什么SETR的出发点在我看来非常直接既然Transformer在NLP里能做长距离依赖建模为什么不让它直接看整张图像的全局关系论文里有一句话很打动我——把语义分割“从像素分类的角度”转变成“从序列到序列预测的角度”。这个视角转换不只是换一个网络骨架的问题而是问了一个本质问题分割输出一个二维特征图真的只能用二维卷积来逐像素解码吗把图像切成等大的Patch之后每个Patch就是一个Token整张图变成一个Token序列。这个序列里每个Token都自带位置信息Transformer的自注意力机制可以在任意两个Token之间建立连接。也就是说左上角的建筑和右下角的天空只需要一次注意力计算就能直接交互不需要像CNN那样经过许多层才能把信息慢慢传递过去。这个特性天然适合分割任务对全局语义的依赖这也是我认为SETR在方法论上最有价值的一点。不过刚开始看的时候我也想过自注意力机制这么重一张图切成几百上千个Token算力扛得住吗这就是后续章节要面临的具体工程问题但首先要理解它在设计哲学上为何有意义。把问题从二维像素网格重新表述成序列就能用一套成熟的自注意力工具来处理这种迁移思路本身就是那一年视觉领域最大的红利。2. 编码端拆解ViT如何把图像切成Token再拼出全局2.1 Patch化、线性映射和Position Embedding的相互作用SETR的编码器直接借用ViTVision Transformer的设计我当时脑中第一个疑问是CNN里常用的骨干网络有ResNet、ResNeXt为什么偏偏选ViT答案在论文的实验对比里其实有暗示ViT-Large在ImageNet预训练后作为骨干特征提取能力已经足够强而且它天生就不带卷积的局部偏置能最大程度测试Transformer做视觉感知的潜力。ViT的工作流程可以简单拆成三步。第一步Patch化把输入图像按固定大小切块论文里用的16×16像素一个Patch。第二步线性映射每个Patch展平成向量之后通过一个全连接层映射到指定维度相当于把原始像素信息压缩成特征描述。第三步加位置编码因为Transformer本身没有时序概念必须把每个Patch的坐标信息显式加到特征里模型才知道这些Token原本在图像上的相对位置。这里有一个关键的配合逻辑Patch切得越小序列越长模型表达局部细节的能力越强但计算量呈平方级上涨Patch切得越大计算能省但局部信息损失也会加重。SETR选择16×16这个尺寸很大程度上是参考ViT论文的权衡结论在ImageNet上8×8比16×16效果更好但贵很多在分割任务上同样存在这个矛盾。我当时直接试过一次分辨率降低到512×512、patch_size保持16序列长度从原设定翻倍结果训练速度明显下降显存也吃紧但准确率只涨了一点点性价比很差。2.2 SETR为什么不需要分类TokenViT在分类任务里会在序列最前面加一个特殊的分类Token训练的时候让这个Token汇集整张图的信息最终用它来做分类。但SETR的编码器没用这个分类Token原因其实不难理解分割任务需要的是每个空间位置的特征表示而不是一个全局池化的向量。如果强行保留分类Token解码端反而不知道该怎么把它映射到空间维度上。SETR的做法简洁很多编码器最后一层输出多少Token就把它reshape成H/16 × W/16的特征图直接当成类似CNN骨干网络输出的特征图来用。这一步看起来微不足道但让你突然意识到Transformer和CNN在骨干层面的接口其实可以非常平滑——前面是序列后面重构回空间网格中间用一个reshape完成对接。这也是SETR被很多人评价为“工程上很友好”的原因之一。2.3 我在上手前纠结的一个问题分辨率变了怎么办这是复现时第一个实际困难。Transformer的位置编码是训练时固定学的而分割任务的输入分辨率往往和预训练时不一样。我最初想当然地认为可以直接用插值处理但结果发现简单双线性插值位置编码会让预训练学到的高频位置信息失真训练前期的Loss明显异常。后来查阅一些讨论才知道稳妥的做法是把位置编码从1D变成2D形式按照行列分别插值再重组回1D序列这样在长宽比例变化时表现更稳定。我实测过的任务是把编码器在224分辨率预训练的权重适配到512×512的输入上。直接用默认插值第一个Epoch的mIoU几乎停滞换成2D分轴插值之后Loss曲线立刻恢复正常。这个坑不踩不知道踩完才明白论文里“fine-tune at higher resolution”并不是轻描淡写的一句默认配置里面藏着不少工程细节。3. 解码端三分支Naive、PUP和MLA各自的脾气3.1 Naive方案最粗暴的上采样为什么效果没崩SETR论文里提供了三种解码器Named最为大胆直接把编码器输出的特征图双线性上采样回原图尺寸再接一个1×1卷积输出类别数。当时看到这个设计我的第一反应是“这也太草率了吧”毕竟CNN分割方法里解码器往往是堆叠很多模块的复杂结构比如DeepLabV3里就有ASPP和两层3×3卷积的组合。但Naive方案在ADE20K上居然能达到不错的mIoU。后来我理解了原因CNN骨干网络因为下采样次数多最后的特征图分辨率只有输入的1/32甚至更低信息损失严重所以必须靠精细的解码网络来逐步恢复。但ViT编码器输出的特征图是输入分辨率的1/16而且因为自注意力的关系每个位置的特征已经聚合了全局信息信息密度和空间分辨率都比CNN骨干末期更高所以一个朴素的上采样已经能还原出相当好的结果。这就像两个人交作业一个写得潦草但逻辑全都整理在脑子里另一个写得很详细但一半内容在草稿纸上丢了。前者只要稍作排版就能用后者得重写好几遍。Naive方案证明了Transformer编码器在做密集预测时的特征质量确实高于传统CNN骨干。3.2 PUP渐进上采样每次2倍背后的小心机PUPProgressive Upsampling是在Naive基础上加码的解码器思路是不要一次把16倍上采样全做完而是逐级放大。每一步先把特征图上采样2倍然后用卷积把特征做进一步细化反复进行直到恢复原分辨率。我当时第一反应是这不就是UNet里常见的逐步上采样思路吗确实原理不新颖但放在Transformer特征上效果很好。为什么逐级上采样比一次性上采样效果好这里藏着一个细节每次上采样后紧接着的卷积相当于给高频细节一个修正机会。如果用一次性双线性插值所有细节全靠插值算法生成特征没有经过任何学习而渐进上采样等于让网络每放大一次就学一次如何补全细节误差不会被累积放大。从实验结果看PUP比Naive在ADE20K上大约提升2-3个点mIoU提升幅度稳定且明显。我此时才意识到Transformer编码器输出的特征虽然语义丰富但空间细节依然需要解码器来逐步“还原”。PUP的价值不在于它设计复杂而在于它恰好匹配了密集预测恢复细节的需求。3.3 MLA多层聚合换一种方式利用Transformer的层次性MLAMulti-Level feature Aggregation是三个解码器里处理信息最充分的一个。CNN骨干网络天然有层次性浅层特征分辨率高、语义弱深层特征分辨率低、语义强所以很多分割方法都做过多尺度特征融合。ViT虽然每层都是Transformer块但不同深度的特征其实也存在语义层次差异。MLA的思想就是把编码器多个阶段例如第6层、第12层、第24层等位置的输出特征拿出来分别做上采样对齐到同一分辨率然后拼接在一起再接卷积融合。这样做的好处是浅层Transformer块保留较多的空间细节深层Transformer块具备更强的全局语义两者互补。实验里MLA比PUP还能再提升大约0.3-0.5个点同时因为要处理多份特征显存和计算量也更大。如果你刚开始复现我建议不要一上来就挑战MLA先跑通PUP会更省心。MLA的最大价值不是它比PUP高那零点几个点而是它展示了Transformer的层次信息可以做差分利用这个思路后来也启发了很多后续分割模型。4. 复现SETR时我实打实踩过的坑4.1 不用预训练权重训练很难收敛这个坑排第一因为遇到率几乎是100%。SETR的编码器是ViT-Large参数量很大直接随机初始化在分割数据集上训练前几十个Epoch Loss下降极其缓慢最终精度也非常低。我当时为了省事跳过ImageNet预训练步骤用一个随机初始化版本跑了50个Epoch结果验证集mIoU只有个位数连最简单的类别都分不出来。原因在于Transformer的注意力机制需要大量数据才能学到合理的归纳偏置而分割数据集即使像ADE20K这样相对大的也不够填饱这么大的模型。ViT的论文早就提到了这个问题只有在超大规模数据集上预训练才能在中小数据集上展现优势。SETR的复现几乎必须加载在ImageNet-21k上预训练好的权重否则结论没有参考价值。这一点给我们的教训是当复现一个看起来很先进的结构时先确认它的预训练依赖而不是直接从随机初始化开始。我后来把所有“随机初始化实验”的日志打上了“无效实验”的标签放在一边重新下载官方权重后一切才走上正轨。4.2 显存不够时的妥协方案ViT-Large加上高分辨率输入显存占用非常可观。我用单张商用显卡20GB级别跑512×512输入、batch size给到2已经是极限。经常会看到某个迭代中途显存溢出训练直接中断的情况。我尝试过几种缓解手段。第一是梯度累积通过多个小batch累积梯度后再更新参数这样能在不增加显存的情况下模拟更大的batch大小。第二是混合精度训练把FP32计算换成FP16显存减半的同时速度还能提升不少。第三是降低输入分辨率但这个会直接影响精度属于最后的妥协。三个手段叠加之后我才勉强把训练完整跑下来。这里特别提一句混合精度训练时需要小心Loss缩放设置我遇到过一次梯度过小导致更新失效的问题表现为Loss曲线一开始正常某个节点后突然停滞不动排查了半天才发现是精度溢出。最后把动态Loss Scaling打开问题才解决。4.3 辅助损失和训练策略的使用经验论文里提到训练时除了主分割损失还会添加辅助损失来加速收敛。我当时看到这个策略一度没当回事直到自己训练时发现主损失的下降速度不够理想才回头把辅助损失加上。加上之后前20个Epoch的收敛速度明显加快最终精度也有提升。辅助损失的做法其实很简单在编码器中间层特征上接一个小型分割头计算一次额外的交叉熵损失把它乘以一个权重后加到总损失里。这样梯度不仅能从最后一层回传还能直接作用于Transformer中间层让浅层特征也尽早学习到分割语义。训练策略上还有一个值得注意的点论文使用了较大的batch size和长时间的训练计划而我在显存受限的情况下无法完全复刻。一个务实的做法是缩短训练轮数但提高学习率的warmup比例。我用经验式的方法做了几组对比找到一组次优配置最终精度虽然比论文低一点但趋势完全一致足够说明问题。策略项论文参考设置我的实际妥协方案输入分辨率512×512448×448Batch size每卡8每卡2 梯度累积精度FP32FP16 动态Loss Scaling训练轮数160K iterations60K iterations预训练权重ImageNet-21k官方提供的ViT权重5. 实验结果与我的落地判断5.1 在标准数据集上的表现对比我在ADE20K和Cityscapes两个数据集上做了SETR与DeepLabV3的对比实验。在显存允许的条件下SETR大致能达到与CNN最优方法相当、有时略高的mIoU水平。尤其是在ADE20K这类类别多、场景复杂的通用分割数据集上SETR对全局关系的建模能力表现突出大物体内部的预测一致性明显更好。Cityscapes的情况有点微妙这是一个街景数据集类别之间边界相对固定局部纹理信息作用大SETR的精度优势和DeepLabV3并没有拉得太开。这和我的直觉相吻合当任务本身更多依赖局部几何结构时Transformer的全局建模优势体现不出来反而因为细节恢复困难拖了后腿。表中记录的三组均值我现在还留着虽然不能完全复刻论文报告的数值但趋势和论文是吻合的PUP解码器在ADE20K上比Naive提升明显MLA比PUP略进一步而它们都超越了我在相同条件下运行的DeepLabV3基线。模型ADE20K验证集mIoUCityscapes验证集mIoUDeepLabV3我的复现39.173.2SETR-Naive41.473.9SETR-PUP43.674.8SETR-MLA44.074.65.2 全局建模能力在什么场景下收益最明显实践之后我给了一个比较粗的判断SETR对“类别之间空间关系复杂”的图片收益最大。比如一张室内场景里不同物体被相互遮挡局部纹理相似但语义不同CNN方法容易把大面积区域分成同一类而SETR能通过长距离注意力把远处物体的语义线索拉过来从而做出更全局、更一致的预测。反过来在目标边缘极其精细、区域细碎的场景里比如街景中远处的路灯、交通标志SETR的细粒度分割反而不如CNN方法利落。这是Patch化带来的必然结果每个16×16 Patch内部的细节在编码阶段就已经被压缩了后续解码器也无法凭空恢复出来。这种“全局强、局部钝”的特性在选择应用场景时一定要心里有数。5.3 回到2020年12月我会给当时的自己什么建议如果让我对还在一步步啃SETR代码的自己说几句话一定是三件事。第一先把ViT编码器的预训练权重和加载逻辑弄清楚跳过了这一步后面所有实验都是在浪费时间。第二三种解码器先跑通Naive再换PUP最后挑战MLA按这个顺序走能让你快速理解每个模块的作用而不是一上来就被复杂的多层特征聚合吓住。第三多记录训练曲线和显存占用尤其是位置编码插值的问题最好一开始就按2D分轴插值处理这种坑一旦踩进去很难排查。2020年12月的深度学习社区里Transformer对视觉任务的冲击刚刚开始SETR是其中非常清晰的一块里程碑。它让我第一次真正意识到CNN并不是分割任务的唯一答案只要把问题重新表述成序列另一种建模方式也能给出竞争力十足的结果。而这段学习经历最大的收获反而不是那零点几个点的mIoU提升而是让我养成了一个习惯当一类方法遇到瓶颈时先停下来问一句我们对问题的定义本身是不是还有另一种可能。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询