ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

精读Mask2Former:掩码注意力如何统一语义、实例与全景分割

精读Mask2Former:掩码注意力如何统一语义、实例与全景分割 分割这个方向论文多到什么程度呢光是用关键词去搜语义分割、实例分割、全景分割、点云分割、遥感分割、医疗分割每一类都能拉出几十上百篇更不用说这两年Transformer和Mask类方法爆发之后几乎每周都有新工作挂arXiv。我自己的经验是硬着头皮一篇篇读读十篇忘八篇真正能在自己项目里用起来、能讲清楚它到底解决了什么问题的可能只有两三篇。这篇博文我想拿一篇我自己反复读了很多遍、也真正用到过实际项目里的分割模型代表作来拆解——Mask2Former把论文精读这件事从头到尾演示一遍。不是翻译摘要也不是罗列贡献而是以我拿到一篇分割论文该怎么读、读完怎么用为线索把架构设计、损失函数、训练细节、复现部署这些环节一层层剥开。这篇文章适合刚入门分割方向的研究生也适合已经在做落地项目、想从论文里找优化思路的工程师。1. 为什么选了Mask2Former它站在分割方向的分水岭上1.1 从FCN到Mask2Former分割范式的三次切换分割领域早期的统治范式是FCN全卷积网络和它的继任者们U-Net、DeepLab系列、PSPNet这些模型的核心思路是逐像素分类。你在某个空间位置上有特征向量全连接层或1x1卷积把它映射成类别概率得到的就是H×W×C的logits图。语义分割这么做非常自然因为语义分割的定义就是给每个像素一个类别标签加上跳层连接和空洞卷积之后精度也很能打。但这个范式有个绕不开的瓶颈它天生做不了实例分割。同一个类别下有两个物体逐像素分类只能告诉你这是人没办法区分这是第一个人还是第二个人。后来就有了两阶段的实例分割思路代表性工作是Mask R-CNN。先跑一个目标检测器RPN给出候选框每个框内部再做RoIAlign和掩码分支生成二值掩码。这种范式解决实例分割确实有效但问题在于它把检测和分割两件事绑死了。掩码质量受检测框质量拖累特征对齐依赖框的坐标遇到密集小目标或者重叠严重的场景框稍微偏一点掩码也跟着崩。而且语义分割和实例分割是两套网络结构想同时做好就得各训练各的或者用多任务硬接。Mask2Former出现的时机很有意思。它之前已经有DETR把Transformer引入检测证明查询机制可以替代锚框和NMS让目标检测从密度估计后处理变成集合预测。Mask2Former把这个思路延伸到了分割用一组可学习的掩码查询mask queries同时预测掩码和对应的语义标签语义分割、实例分割、全景分割全用同一套结构去做。这篇论文在2021年12月挂出COCO实例分割、Cityscapes全景分割、ADE20K语义分割几个榜单上都拿了当时的最优成绩。它不是单点上的改进而是范式的切换——把分割从按像素/按框建模变成了按掩码建模。1.2 精读之前先搞清它自称的三点贡献读论文之前先看贡献这是我自己一直用的方法。摘要和引言里的贡献列表相当于作者在说我做了三件什么事后面所有章节都是给这三件事提供证据。Mask2Former的贡献可以压缩成三点第一提出了一种通用的掩码分类架构用掩码查询加Transformer解码器统一处理语义、实例、全景三类分割任务。这是最核心的贡献其他两点都是为它服务的。第二设计了掩码注意力机制让解码器在做跨层注意力时只关注预测掩码区域内的特征收敛速度快了3倍论文里明确写了训练epoch减少到之前的四分之一左右这在Transformer类方法里是很关键的工程优化。第三在多个数据集上验证了架构的通用性包括COCO、ADE20K、Cityscapes和BDD100K覆盖了室内外场景和自动驾驶场景。这三个贡献不是并列关系而是一个总—分结构。第一点是核心命题第二点是让这个命题能高效落地的关键组件第三点是验证。理解了这层逻辑再看后面的方法部分就不会迷失在细节里。1.3 为什么给论文标精读而不是速读我自己刚开始读论文时也走过弯路。拿到一篇paper从Introduction开始逐字看看到Method的公式卡住了就翻回去再看结果半小时过去了才看了两页前面看完的也忘得差不多。后来调整策略先粗读一遍Structure搞懂框架画出模型结构图标出每个张量的流动方向第二遍只盯自己关心的部分深抠比如某篇论文的loss设计、数据增强策略、推理时的后处理第三遍看代码对照论文找细节。这种三遍读法对Mask2Former这类方法型论文尤其适用。因为它的价值不在某个惊艳的公式而在一种组织方式——怎么用Transformer把掩码这件事从解码器一路贯彻到损失函数。如果你只是速读一遍标题和摘要得到的印象就是哦一个泛化分割模型但下次自己设计模块时不会从这类论文里汲取到任何养分。所谓精读读的不是文字是作者做决策的思路他为什么在解码器里用6层为什么掩码注意力能加速收敛为什么匹配策略选择匈牙利算法每一项都可以深挖。2. 方法的主干从共享主干到掩码分类的完整链路2.1 像素解码器FPN在这里不是主干是旁路Mask2Former的总体结构可以分成三块主干网络用来提特征像素解码器用来生成高分辨率逐像素特征Transformer解码器用来迭代式地细化掩码查询。大多数人看到结构图会只盯Transformer解码器但我建议反过来先把像素解码器的设计搞清楚因为这里藏着理解整篇论文的伏笔。作者把主干输出的多尺度特征送入像素解码器这个解码器用的不是FPN里那种自顶向下逐层融合的传统结构而是带Transformer编码器的特征金字塔。用论文里的配置来说主干用ResNet-50或Swin Transformer输出C3、C4、C5三个尺度的特征图经过一个编码器做全局上下文建模之后再由像素解码器逐层上采样并合并高层语义最终生成高分辨率的逐像素特征向量。这个特征向量有两个去处一部分通过一个大致的掩码嵌入per-pixel embedding参与掩码预测另一部分在掩码注意力里作为key/value参与查询和特征之间的交互。很多人刚开始读会混淆一个点FPN的输出不是用于逐像素分类它是给掩码注意力用的特征库。像素解码器的直接产物是每个位置的embedding最终掩码是通过query embedding和per-pixel embedding做点积算相似度得到的。理解这一层关系后面看掩码注意力机制时才能明白为什么它关注的区域会随着训练动态变化。2.2 Transformer解码器查询如何从一团噪声变成掩码集合Transformer解码器的输入是N个查询向量实验中默认是100全景分割时可以用50这些向量在初始化时几乎不包含任何位置信息。每一层解码器做的事情用大白话说就是调整这100个向量让它们逐渐变成对场景中每个物体的编码。具体来说每个查询会经过一次自注意力让查询之间彼此拉开距离避免多个查询聚焦到同一个物体上然后经过一次交叉注意力到像素特征中去取信息最后经过前馈网络做非线性变换。Mask2Former的交叉注意力不是让每个查询去关注整张特征图而是让查询先根据上一步预测的掩码把特征图的注意力范围限制在这个掩码对应的区域内这就是掩码注意力名字的来源。这个设计的直觉是如果某个查询已经粗略定位了一个物体不需要再看全图来找人只需要在物体所在的位置细化边界和细节就行了。计算量和性能之间做了巧妙的权衡。解码器总共堆叠6层每一层都会输出一组中间预测先由当前查询和像素嵌入生成一个掩码logits再用这个掩码logits计算掩码注意力权重去加权特征图中的特征供下一层使用。如果你去看代码或者论文的Figure 3会发现作者画的是一个循环结构但实际前向时是逐层串行的。最后一层的输出经过两个分支一个产生类别logits用来做分类另一个与像素嵌入做内积产生掩码logits用来做分割。2.3 为什么这种分类掩码的耦合在数学上是自洽的掩码分类范式可以追溯到Panoptic FPN和DETR但Mask2Former把分类掩码的耦合做得更加彻底。每个查询最终预测的是一个tuple类别概率和掩码。预测的掩码是一个H×W的二维logits图H和W等于输入分辨率除以步幅训练时使用匹配后的GT掩码计算损失推理时把超过阈值的区域作为预测结果。这种方式让模型的输出天然是一组带标签的掩码正好契合全景分割的定义——既需要区分语义类别又需要区分同一类别下的不同实例。这个设计与像素分类范式在损失函数上的差异是很本质的。FCN系模型的损失函数直接拿预测的像素类别与GT逐像素计算交叉熵Mask2Former的损失则分为两部分每个查询预测类别时使用交叉熵预测掩码时使用二值掩码交叉熵加Dice Loss。而且不是所有查询都参与损失计算训练时会通过匈牙利算法把100个查询里的每一个和GT实例做最优匹配只有被匹配上的查询才会产生监督信号。一句话概括像素分类训练的是每个像素是什么类别掩码分类训练的是每个物体长什么样、叫什么名字。3. 掩码注意力这篇论文最值得拆开看的机制3.1 注意力权重从哪里来先预测掩码再做注意力掩码注意力的输入有三个查询向量Q像素特征K/V以及该查询目前预测出的掩码logits。它的公式和标准多头注意力非常像区别只在于attention bias那里——在每个位置加上一个由掩码logits决定的偏置值。展开来讲给定某层的查询q和H×W的特征图先用点积得到查询与每个像素位置的相似度然后把这个相似度加上掩码logits的对应值非掩码区域给一个很大的负值经过softmax之后整张特征图上大部分位置的权重都会被压低只有掩码区域的权重得以保留。这个操作虽然只比标准注意力多了一行加法带来的效果却很直接。DETR那个年代的Transformer解码器在处理高分辨率图像时非常慢因为每层交叉注意力都要全局交互复杂度是O(NHW)而掩码注意力把交互范围从全图缩到预测的前景区域单阶段训练收敛速度明显变快。作者在论文中专门有一个表格展示ResNet-50和Swin-L两种主干下使用掩码注意力比使用全局交叉注意力在训练轮数上限少很多就能达到相似精度这个数据值得重点看。3.2 一个直觉类比先框出房间再去找钥匙掩码注意力的行为类比一下生活场景会非常好记找东西时你不会把整间屋子一寸寸全看一遍你通常会先根据记忆判断可能落在哪个区域走进那个区域再仔细翻。Transformer解码器每层做的事情也一样第一次迭代时掩码可能还很粗糙但注意力已经在聚焦于某个区域下一次迭代时掩码细化了一层注意力聚焦得更准确。这种由粗到细的迭代过程有点类似于传统分割方法里的CRF后处理只不过把后处理挪进了网络内部而且和特征提取端到端地共同优化。我在实际读代码时确认过一个细节掩码注意力是per-query独立计算的也就是不同查询在同一层使用的attention bias完全不同。这一点非常关键因为如果所有查询共享同一个bias那模型就退化成了对整张图做加权无法区分不同实例。Per-query的独立性是掩码注意力能同时处理多个实例的结构前提。3.3 消融实验里的隐藏信息每一步都是可复现的收益论文Table 4记不清具体编号也没关系大致就是消融那张表展示了从基线到完整模型的递增式改进。第一步是在掩码分类的基线上加多尺度特征第二步加掩码注意力第三步加AdamW和更长的训练策略每一步都能带来稳定的指标提升。如果你要复现这篇论文我强烈建议把这张表当作科目一来核对你的复现应该能重现这些增量趋势而不是只追求最终数字。还有一处细节容易被忽略作者在语义分割设置里做了查询数量敏感度实验100个查询和50个查询的性能差异并没有想象中大。这意味着在资源受限的部署场景下可以大胆地把查询数量减半来换速度。我自己就在一个移动端场景里试过把100个查询减到30个mIoU只掉了不到一个点但解码器推理时间少了接近一半。这类结论论文里不会加粗强调但精读时捕捉到就是在实际工程里能直接折现的信息。4. 损失函数与匹配策略训练阶段的点睛之笔4.1 二分匹配是怎么把一组预测对齐到一组真值的掩码分类的其中一个特殊之处在于分割任务里的GT数量是不固定的比如一张图中可能只有3个实例但模型却固定输出100个查询。那么计算损失的时候到底让谁来对GT负责答案是最优二分匹配。计算步骤如下第一步分别计算GT中每个实例与100个查询中每个查询的匹配代价匹配代价是一个加权组合包括类别预测的交叉熵、掩码的Dice分数、边界框IoU可选。第二步用匈牙利算法求解一个最小代价的一对一映射也就是让每个GT恰好匹配一个查询。第三步只有被匹配到的查询参与最终损失的反向传播未匹配到的查询只负责拉低match score并且其类别预测会被导向空类别no object。这个机制和DETR一脉相承但落实到分割任务上有一个额外优点它给实例是无序集合这一先验提供了天然结构。实例分割中物体的顺序没有意义你不需要像目标检测那样做NMS去抑制重复框因为二分匹配天然保证每个GT只被一个查询负责两个查询如果都强烈响应同一个目标只有匹配代价更低的那一个会被选中另一个会被抑制掉。4.2 Dice Loss为什么能稳住掩码的边界质量掩码分类的损失函数由多部分加权组合类别交叉熵、掩码交叉熵、掩码Dice Loss有时还带边界损失或mask IoU loss。Dice Loss这个组件值得单独讲讲因为它对小目标和边界像素的表现影响很大。Dice Loss衡量的是预测掩码和GT掩码的重叠程度公式是1 - 2|P∩G|/(|P||G|)直接优化Dice系数。相比逐像素交叉熵Dice Loss对类别不平衡不敏感尤其适合像素级掩码问题——因为大多数自然图像里前景和背景的比例严重失衡交叉熵对小目标物体被淹没的问题往往无能为力Dice Loss能显著提高小目标的掩码质量。Mask2Former把Dice Loss和掩码交叉熵做成加权求和交叉熵提供像素级的判别梯度Dice Loss提供区域级的一致性约束两者互补效果比单独用其中任何一种都稳定。我在实践里还发现Dice系数存在一个容易踩的坑在极端情况下当预测掩码和GT完全没有交集时Dice Loss的梯度可能不稳定。对此可以加一个smooth项来避免除零问题这属于实现层面的细节论文里不会写但精读加复现时一定会遇到。4.3 训练策略里的隐藏工程所有超参都是精心调出来的论文的实验设置部分列出了一批训练超参数包括batch size通常是16、初始学习率ResNet主干用1e-4Swin主干用1e-5、权重衰减、训练轮数12到36个epoch、随机失活率、权重初始化方式等。这里面有两个设计很值得留意。第一个是随机失活的多样性。作者用了包括随机裁剪、缩放、颜色抖动、水平翻转等在内的数据增强其中随机裁剪larger-scale-jitter对像素级任务的影响非常大。它让模型在多尺度下都能保持稳定的预测能力我在复现时如果把随机裁剪范围缩小Cityscapes的mIoU掉2个点都不止。第二个是学习率和主干的选择。ResNet-50主干的初始学习率通常设为1e-4但Swin-L主干则低一个数量级到5e-6左右这是因为Transformer主干本身对学习率更敏感直接用1e-4很容易不收敛。这些细节看起来琐碎但真正影响复现成败的恰恰是它们。论文的附录或开源代码里通常会写明这些参数精读时必须认真对照。5. 数据、评测和场景适配从论文数字到自己的业务5.1 三类任务在评测指标上的不同脾气Mask2Former的通用性让它必须在不同数据集上分别证明自己。语义分割通常用mIoU平均交并比实例分割用mask AP全景分割用PQPanoptic Quality。理解这些指标本身并不难难的是读论文时要注意模型是在什么设置下取的数。以COCO数据集为例实例分割的标准评测是大写APmask AP阈值从0.50到0.95取平均这跟Cityscapes数据集上常用的AP50或AP只取0.5到0.95的平均并不完全一样。论文中还会区分使用测试时增强TTA与不使用TTA的分数通常TTA会对多尺度输入做平均能带来1到2个点的提升。如果你在对比不同论文的指标必须确认这些前提一致否则就容易出现我的模型加上TTA但别人没加分数还比他低这种让人困惑的情况。5.2 遥感影像分割和息肉分割这类垂直场景能直接用吗热搜词里出现了遥感影像语义分割、息肉分割、点云分割这些应用方向正好可以展开说说Mask2Former这类通用分割模型搬到垂直领域时有哪些该注意的地方。遥感影像分割的典型特点是大尺寸几千乘几千像素、类别极度不均衡道路、建筑、植被面积占比悬殊、以及边界模糊。直接用Mask2Former去训遥感数据集第一个坑就是显存不够——高分辨率输入会让像素解码器输出很大的特征图匈牙利匹配也会随之变慢。可行的做法是切patch训练比如切成512×512或1024×1024的块并用overlap策略来减轻边界切割带来的掩码不连续问题。实测下来Swin主干加分块训练的组合在ISPRS/Vaihingen这类遥感数据上能跑出不错的效果但还是得在损失函数里适当加大Dice Loss的权重来应对类别不平衡。息肉分割这样的医疗影像场景本质上是二类分割息肉区域vs背景标注数据往往只有几百上千例。这种情况下与其从零训练Mask2Former更建议用预训练权重做迁移学习——冻结主干网络的前几层只微调解码器和查询向量。另外医疗影像的分割对召回率要求很高漏检一个息肉比多检一个背景严重得多所以推理阈值要专门调整甚至可以考虑对多个epoch的权重做模型集成。点云分割的热搜词里还有个DBSCAN这个和Mask2Former不在一个赛道。DBSCAN是经典的无监督聚类算法常用于点云的地面分割这类几何任务而Mask2Former处理的是图像数据。如果点云已经投影成2D距离图像那用图像分割模型来做基于range image的语义分割是可行的但直接处理稀疏3D点云还是得用PointNet这类专门的网络。论文精读得越多越要有拿对工具做对事的警觉——并不是越新的模型就适合所有场景。5.3 推荐配套阅读的几篇论文和代码仓库只精读一篇论文是远远不够的特别是Mask2Former这种站在多个肩膀上工作的模型。我建议按这个顺序配套阅读DETR因为Mask2Former的集合预测和匈牙利匹配直接继承自它不读DETR很多设计动机没法理解。MaskFormer这是Mask2Former的前作它提出了掩码分类概念但当时跨层注意力还是全局的没有掩码注意力机制性能也不算最强。对比MaskFormer和Mask2Former就能看出掩码注意力带来的收益到底有多大。开源代码方面官方仓库是facebookresearch/Mask2Former基于Detectron2实现结构清晰但上手偏重LeapLabTHU的mmdetection实现也很良心如果用mmdetection做复现直接跑官方config即可。如果想看工程化更轻量版本可以搜索Mask2Former的ONNX/TensorRT导出帖子有人做过针对单一类别的精简改版移植到端侧时很有参考价值。6. 复现和部署踩过的坑动手才是检验精读的唯一标准6.1 第一个坑环境版本不一致带来的隐形bug复现Mask2Former的第一步不是跑代码而是把环境锁死。官方仓库依赖Detectron2而Detectron2对PyTorch、CUDA、TorchVision的版本组合相当敏感。我自己的经历是在CUDA 11.7的机器上PyTorch 1.13可以正常编译但换成PyTorch 2.0.1后某些自定义算子出现了输出位置偏移mIoU直接掉了5个点而且没有任何报错信息。排查了两天才发现是Torch版本导致的自定义CUDA kernel行为变化。给你的建议是严格按官方README里的环境配置安装装完先跑一次demo预测确认输出正常再开始训练。不要为了图新版本功能去升级依赖除非你有充足时间排查兼容性问题。6.2 第二个坑显存和batch size的博弈Mask2Former在COCO数据集上的标准设置是用8卡训练每张卡batch size为2总batch size为16。如果你只有单张24GB显存卡这个配置直接崩。多数人的做法是降低单卡batch size到1同时调整学习率策略。具体来说把总batch size从16改成8学习率也应该相应地从1e-4降到5e-5保持线性缩放的经验法则。如果直接沿用原本的学习率loss曲线容易出现震荡。显存不够的另一个解法是把输入分辨率从1024降到800或640。但要注意Mask2Former的性能对输入分辨率很敏感我在Cityscapes上试过从1024降到640mIoU能掉3个点所以在降低分辨率时要有心理预期同时可以尝试用混合精度训练来省显存。6.3 第三个坑训练时间和推理速度的实测数据我用自己的单卡A10080GB复现过Mask2Former ResNet-50在ADE20K上的训练32G显存下单卡batch size能开到48个epoch大概跑了40多个小时。这个时间成本并不低如果只想验证思路可以考虑先在小数据集比如Cityscapes的val子集上做short-run训练或者直接加载官方在COCO上训练好的权重冻结主干只微调解码器。推理速度方面单张A100上ResNet-50主干的Mask2Former跑1024×1024输入大概在15到20 FPS左右Swin-L会掉到5 FPS以下。这个推理延时对实时应用来说还是偏高所以很多工程落地会选择蒸馏或量化把Mask2Former当Teacher模型蒸馏给更轻量的学生网络。这也是论文之外值得探索的方向。7. 精读论文的方法沉淀我读了这么多分割论文之后的心得7.1 信息分层一篇论文里哪些该细读哪些可以略过把时间花在刀刃上。以Mask2Former为例我建议的信息分层是这样的精读部分包括方法总览特别是框架图和公式3那个掩码注意力公式、损失函数设计、消融实验。这三块决定了这篇论文的贡献是否成立、是否可复现、对你的任务有没有启发。泛读部分包括相关工作、更多数据集结果、以及一些工程实现细节如DCN、TTA策略。相关工作适合在你写论文时再回过头来补初次精读不必逐篇展开否则容易迷失。直接略过的Training details里你对不上的超参数可以不细究真正复现时再回来看附录里的定性可视化可以快速扫一眼主要是观感上的验证。7.2 用自己的话把论文讲给一个不懂AI的人听检验你是否真的读懂了一篇论文最好的办法是自己解释一遍。我不是说做presentation而是用最朴素的语言概括。比如描述Mask2Former可以这么说它拿到一张图片后先由主干提取纹理和形状信息再由像素解码器生成一张逐像素的语义底图同时有100个探针查询向量在底图上游走每个探针负责盯住一个可能的物体边界反复迭代之后探针输出的是这个物体叫什么它占了哪些像素。这句话虽然不精确但能帮你厘清模块之间的上下游关系写代码时你只需顺着这句话去对应类名和函数即可。7.3 精读之后怎么从论文里榨出工程迁移点每篇高分论文都有可迁移到工程中的养分。Mask2Former至少可以榨出这几个点掩码注意力是一个通用的稀疏注意力设计范式。你不需要做分割只要你的任务有重点区域这个先验就能借鉴这种用预测结果去约束注意力的思想比如目标检测、关键点检测里都可以试。二分匹配策略可以应用到任何无序集合输出的任务包括多标签分类、端到端跟踪等。Dice Loss几乎是所有像素级任务里提升小目标表现的最简单手段。查询数量可以自由调整性能只有轻微变化这一发现对移动端分割模型的设计启发是不妨把查询数量当做一个可调的超参数而不是固定值。我自己做落地项目时的习惯是每精读一篇论文就写一份迁移清单把可能对自己有用的组件列出来标上适用条件和改造成本。Mask2Former这份清单里掩码注意力和Dice Loss两项已经在我的业务中派上了用场二分匹配暂时还没用到但遇到类似任务时我一定能想起来有一条这个思路。回到最开始说的那个问题分割方向论文那么多精读到底该怎么选、怎么读、怎么用。对我来说Mask2Former是一个特别理想的样本因为它既有关键创新点掩码注意力又有完整的消融验证还有统一的架构视角几乎涵盖了论文精读需要的所有要素。论文读到最后不是看懂了公式和图表而是看穿了一个团队在一个具体问题前的推理路径——他们在哪里做了取舍在哪里下了重注这些推理资产才是精读能留给你的真正财富。
返回列表