资讯动态

适配器即解耦器:跨域少样本语义分割的简捷实现与复现指南

发布时间:2026/10/15 22:18:22 来源:尧图企业网站定制
做论文阅读笔记这件事我坚持了很多年判断一篇工作值不值得精读的标准其实很朴素它有没有用一个特别简单的机制戳中一个长期没人讲清楚的问题。这篇讲适配器天然充当跨域少样本语义分割解耦器的工作就是典型的例子——标题已经把核心观点亮出来了不用设计复杂的解耦损失不用引入额外的特征分离分支在冻结的骨干网络里插入几组适配器域相关的信息和任务相关的信息就被自动拆开了。这个命题初看有点反直觉细想又觉得顺理成章。我前后读了三遍还动手复现了核心流程。这篇笔记会把我的理解、实验细节和踩坑经验整理出来对正在做跨域分割、少样本学习以及参数高效微调方向的朋友应该都有点参考价值。1. 这篇工作到底在解决什么问题1.1 跨域少样本语义分割的难点在哪里先把问题框起来。少样本语义分割Few-Shot Semantic SegmentationFSS的标准设定是训练阶段用一批包含基类base classes的样本学习如何根据类别原型去分割新类的能力测试阶段每个新类只给1到5张带像素级标注的样本作为支撑集support期望模型在查询图query上把那些没见过的新类像素完整地分出来。跨域Cross-Domain设定在这个基础上又叠了一层约束训练数据来自源域比如常规的自然图像分割数据测试数据来自目标域比如遥感影像、医学内镜图像、合成渲染场景、无人机俯视图。域间差异体现在色彩分布、纹理统计、物体尺度、光照条件、成像机制等多个维度。自然图像里车是光滑的金属外壳加玻璃遥感影像里的车可能是俯视角下几个像素的亮斑两者的特征分布差距非常大。两件事叠加难处就非常具体了。第一少样本本身信息不足一两张支撑图提供的监督信号极其有限模型很容易过拟合到这几张图的表象上第二跨域让源域预训练模型提取的特征在目标域上发生明显偏移原本在源域上很干净的类别聚类到了目标域就搅在一起。如果只做无监督域适应通常需要大量目标域无标注数据做分布对齐如果只做同域少样本分割又默认源域和目标域分布一致。跨域少样本分割要的是只有极少量目标域标注同时还要跨越巨大的域差异。最朴素的解法是把目标域的支撑图直接喂给源域训练的模型提取特征求原型再拿原型去匹配查询图。实验里你会看到一个普遍现象模型在基类上性能尚可换到新类就掉得厉害域差异越大性能衰减越明显。这说明源域学到的特征表示里混入了大量源域特有的风格信息直接迁移过去并不干净。1.2 为什么解耦是个绕不开的话题为了解决上述问题解耦一直是这个领域被反复提及的目标把特征拆成域相关部分和任务相关部分。域相关部分负责描述这张图来自哪个域、成像风格是怎样的任务相关部分负责描述哪些像素属于哪些语义类。理想的跨域模型只依赖后者做分割。过去的主流做法是显式解耦设计两个分支分别编码域信息和任务信息或者加梯度反转层或者引入对抗损失、互信息约束强迫两部分信息互相不串门。显式解耦的问题也很明显需要精巧的损失函数、额外的网络分支、一堆需要反复调的权重系数而且对抗训练稳定性差动不动就崩溃。更重要的是在少样本场景下目标域只有几张标注显式解耦那一大堆目标函数根本喂不饱很容易陷入过拟合或者塌缩。这篇工作的高明之处在于换了个视角与其费劲设计约束来逼网络解耦不如在结构上直接让解耦成为必然。适配器参数量极小、容量有限在冻结骨干面前它既没有能力也没有必要去重新表达整个语义分割任务于是它只能去吸收当前输入分布和源域分布差在哪这部分信息。任务知识留在冻结骨干里域知识被适配器吸收——解耦成了容量差异带来的自然结果。2. 核心框架与适配器解耦的原理2.1 冻结骨干加可训练适配器的整体设计整个框架建立在一个预训练好的分割骨干之上骨干参数全程冻结。适配器以瓶颈结构插入骨干的每个Transformer块内部可训练参数只有适配器自身。前向流程是这样的支撑图和查询图经过同一套冻结骨干加适配器提取特征支撑图的特征在被标注像素位置上做池化得到每个类别的原型向量查询图每个像素的特征与所有类别原型做相似度匹配归一化后得到像素级分割结果。训练阶段用源域数据构造大量episode模仿训练时只见基类、测试时见新类的节奏做元学习测试阶段到了目标域则用目标域的少量支撑样本对适配器做几步梯度更新再对查询图推理。这里有个关键设计值得多说一句大多数人直觉上会认为跨域了就该把骨干放开微调。论文的结论恰恰相反——冻结骨干是保证解耦成立的前提。一旦微调骨干域信息和任务信息会在骨干参数里重新纠缠适配器就失去了充当解耦器的结构基础。注意这个冻结主干、只动旁路的设计思路本质上和参数高效微调PEFT是同构的但它服务的目标完全不同——不是为了省算力而是为了制造信息分流。理解这一点才算读懂了这篇工作。2.2 从容量角度看适配器为什么能天然解耦适配器是一个典型的瓶颈结构输入特征先经过一个降维投影把维度从D压到很小的d经过非线性激活后再升维回D最后以残差形式加回原特征。这个结构的参数量大约是2×D×d相比骨干网络里的D×D矩阵容量小了两个数量级。从信息论角度看容量小意味着表达能力受限。适配器能拟合的映射集合本质上是特征空间里的一组低秩变换。它可以很方便地编码分布偏移这一类全局性、低秩的统计变化——比如色调偏移、纹理风格差异、边缘锐度变化——因为它往往能用一个近似低秩的变换来刻画。但它很难在这点参数量里去重新组织整个语义分割所需的复杂高阶特征交互。打个比方骨干网络相当于一个对物体类别判断很有经验的老手适配器相当于一副根据当前环境光线和色偏定制的眼镜。老手的判别知识不动眼镜只负责把当前场景的视觉偏差矫正过来。眼镜度数有限它替代不了老手的判断能力所以它只能老老实实去编码域的差异。这个推理在实验里也有对应证据研究者通常会发现适配器输出端的残差范数与域差异程度正相关——域差异越大适配器学到的修正幅度越大而把适配器拿掉骨干特征在目标域上的分布偏移也恰恰是那个量级。两侧对上了解耦的结论就站得住。2.3 与显式解耦方案的对比把适配器方案和显式解耦方案放到一起对比优势会很直观对比维度显式解耦方案适配器解耦方案额外模块域编码器、任务编码器等独立分支仅瓶颈适配器额外损失对抗损失、互信息约束、梯度反转等无可调超参损失权重、梯度反转系数等大量敏感参数瓶颈维度、插入位置等少量结构参数训练稳定性对抗训练常震荡、需要大量调参经验训练稳定收敛行为接近普通微调目标域标注需求通常需要较多无标注数据做分布对齐极少标注即可驱动适配器更新额外参数量通常较大骨干参数的1%到2%这个对比并不是说显式解耦没有价值而是在跨域少样本这个具体设定下显式解耦的成本太高、需要的燃料太多。适配器方案等于把解耦目标直接做进了结构里训练时不需要额外的损失监督测试时又因为参数少而天然抗过拟合整套逻辑自洽。3. 关键实现细节与参数选择3.1 适配器结构与零初始化适配器的具体实现有很多变体这篇工作使用的结构可以概括成下面的样子class Adapter(nn.Module): def __init__(self, dim, bottleneck_dim, scale1.0): super().__init__() self.down nn.Linear(dim, bottleneck_dim) self.act nn.GELU() self.up nn.Linear(bottleneck_dim, dim) self.scale scale def forward(self, x): residual self.up(self.act(self.down(x))) return x self.scale * residual注意两个细节。第一适配器内部要先做LayerNorm再进降维投影这能避免目标域特征的均值和方差偏移直接被放大。第二初始化方式非常关键——down和up投影的权重都初始化为零这样训练刚开始时适配器输出是零残差整个网络等价于纯冻结骨干。好处是训练初期不会因为引入随机旁路而破坏骨干已经稳定的特征表示优化起点非常干净。scale参数也值得说一下。固定为1.0在大多数情况下够用但如果瓶颈维度偏大或者任务数很多可以试试0.1到0.5的小scale相当于限制了适配器的修正幅度。这和LoRA里对低秩矩阵乘一个缩放系数的道理是相通的。3.2 插入位置与瓶颈维度的选择Transformer块内有两个候选插入位置多头自注意力之后或者MLP之后。实践下来两个位置都插效果最好但如果只能选一个优先插在MLP之后。原因是MLP层负责的是逐位置的语义特征变换域风格信息在这里留下的痕迹更明显自注意力之后的特征更多保留了Token间的交互结果直接做残差修正的收益相对弱一些。瓶颈维度d的选取是个典型的权衡。太大会让适配器容量过大开始有余力去干扰任务知识破坏解耦效果太小又不足以完整编码域偏移。在我实验的配置里d取骨干隐层维度的1/16到1/8是一个比较稳的区间继续加大收益不再提升反而在跨域少样本的评测上出现下滑。另外可以做一个很实用的诊断单独把某一层的适配器输出关掉看精度掉多少。掉得多的层说明该层的域偏移修正最依赖适配器是信息的重灾区掉得少的层适配器可有可无。根据这个诊断结果可以在不同层配置不同的瓶颈维度把参数花在最需要的地方。3.3 训练与测试的两段式策略训练阶段沿用元学习范式在源域数据上随机采样支撑集和查询集构造episode损失是查询图分割结果与ground truth之间的交叉熵。整个过程中只更新适配器参数骨干一动不动。测试阶段是这篇工作最具实用价值的环节拿到目标域的支撑样本后不需要重新训练任何东西只对适配器做少量梯度更新来适配目标域分布。因为适配器参数极少通常二三十步梯度更新就能收敛更关键的是因为容量有限就算在1-shot这种极端条件下做几十步更新也不容易把支撑图背下来导致过拟合。实操提示目标域支撑集样本太少时建议把梯度更新步数压到10到20步之间学习率在骨干预训练学习率的10倍以上比如1e-3量级。步数多了反而掉点这个现象在1-shot设定下非常明显。3.4 原型计算、相似度匹配与温度系数原型就是支撑图上属于某个类别的所有像素特征的平均向量。但直接平均容易被异常像素带偏实际操作中可以先对支撑集做一次自我预测把预测置信度低的像素踢掉再求均值能明显提高原型质量。匹配阶段建议对原型和查询特征都做L2归一化后再算余弦相似度然后除以一个温度系数τ做softmax。温度系数在跨域场景下比同域场景敏感得多。τ太大分割图模糊边缘不干净小物体容易丢τ太小预测锐利但容易误分置信度虚高。我在跨域评测里用0.05到0.1这个区间效果比较稳同域设定常见的0.2到0.5反而不太合适。还有一个容易翻车的地方骨干网络输出的特征图分辨率通常只是输入的1/16甚至更低而上采样到原图分辨率这一步要做在相似度匹配之后不能在匹配之前直接对特征图做双线性插值。插值后的特征会引入相邻像素的混合信息让边界处的类别判别变钝。4. 实验设置与核心结论解读4.1 评测协议别在基类上自嗨跨域少样本分割的评测协议有一个重要约定训练阶段的基类和测试阶段的新类不能有类别重叠否则模型只是认得这类物体而不是学会按原型分割新类。很多复现翻车都是数据划分时没注意这一点类别泄漏导致分数虚高。标准的评测做法是在多个跨域方向上分别评测比如从自然图像分割数据迁移到合成渲染数据、从自然图像迁移到遥感数据、从自然图像迁移到医学影像。每个方向都按新类的mIoU来报数有些工作还额外报前景二分类IoUFB-IoU来辅助判断。mIoU对新类类别数敏感FB-IoU对面积极小的类别更敏感两个指标配合着看才能判断一个方法是真的在分割还是在碰运气。4.2 主要结果怎么读整理几个关键对比位置给大家参考方法可训练参数占比跨域新类mIoU表现源域模型直接推理0%基线水平域差异越大掉得越多全量微调骨干100%源域好跨域少样本下过拟合明显不稳定只微调分类头约5%有一定提升但无法修正特征分布偏移适配器方案1%到2%稳定接近甚至超过全量微调且对支撑集数量不敏感全量微调在跨域少样本设定下的表现很有意思在1-shot时它往往不如适配器方案因为支撑样本太少全量参数一更新就严重过拟合目标域那几张图只在5-shot甚至10-shot时它才有机会反超。这恰恰说明了在标签极度稀缺的场景里参数效率本身就是一种重要的正则化。4.3 消融实验最有价值的三个发现第一关于瓶颈维度性能随维度提升先升后平再降最优区间存在且相当宽说明这个方法对超参并不敏感工程上友好。第二关于插入位置只插在注意力后的效果明显弱于只插在MLP后两个都插还能再上一截。这和各层承担的功能有关也印证了域风格信息主要残留在MLP变换后的特征里。第三关于测试时适配步数把这个曲线画出来非常直观——步数从0加到20mIoU稳步上升20到30步进入平台期超过50步开始回落。0步时性能也高于不插适配器的基线说明适配器即使在源域训练、不做目标域适配也能通过结构解耦带来收益而目标域适配几步之后又把域差异进一步压掉了。5. 复现过程的常见问题与排查实录5.1 适配器训练震荡或完全不收敛我一开始复现时遇到过适配器loss震荡的情况后来定位到两个原因。一是零初始化没做对随机初始化旁路会在训练初期破坏冻结骨干的输出分布导致loss大幅波动二是学习率设成了和骨干微调一样的量级适配器参数少最优学习率区间和全量微调差别很大我最后用网格搜索把学习率固定在骨干预训练学习率的5到20倍才稳定下来。如果适配器loss在早期降到很低但精度始终上不去大概率是支撑集和查询集构造有问题——比如episode里支撑和查询取自同一张图或者类别划分泄漏了。先去检查数据加载逻辑别急着调模型。5.2 原型被背景像素污染求原型时如果直接把支撑图所有标注像素的特征取平均背景杂讯和标注边缘误差都会被平均进去。1-shot时一张支撑图里目标物可能只占几百个像素这些噪声占比很可观。我的做法是两遍过滤第一遍用冻结骨干加当前适配器先对支撑图做一次预测取预测mask和标注mask的交集区域参与原型计算如果做了支撑增强比如多尺度缩放、翻转再把增强样本的原型做平均。这一招通常能稳定提升一到两个点mIoU。5.3 测试阶段适配步数越多越差这是跨域少样本复现里最常见的翻车点。根源是支撑集过于干净模型几步更新就能把支撑图背下来却无法泛化到查询图。解决思路有三个一是限制步数用验证集从支撑集里留一小部分做early stopping的proxy选最优步数二是限制更新幅度把适配器输出scale调小到0.1到0.3三是在更新过程中给特征加一点噪声或dropout等效于正则化。我的经验是优先限制步数简单直接效果好scale调小的收益不如限步数明显而且scale太小会削弱解耦修正能力导致域差异压不掉。5.4 快速排查速查表现象优先排查项常用解法训练不收敛/loss震荡适配器是否零初始化初始化down/up为零确认冻结骨干基类好新类差类别泄漏检查基类/新类划分是否严格不相交1-shot掉点严重适配步数过多压到10到20步或缩小scale原型质量差特征分辨率/掩码对齐确认特征图下采样倍数匹配后再上采样跨域方向差异大温标τ不适配针对每个方向单独验证τ在0.05到0.1区间边界粗糙、小物体丢失温度过高降低τ并避免对插值后的特征做匹配6. 我的心得与后续可以尝试的方向6.1 结构偏置有时候比损失函数更可靠反复跑完这套流程我最大的感受是解耦不一定非要靠显式约束去逼出来结构本身的容量偏置就可以把信息分流这件事做成默认结果。这给所有做跨域、做泛化、做OOD的工作都提了个醒——当你在为某个目标设计复杂损失时先想想有没有一种简单的结构约束能让网络不得不这么做。减少可训练参数的容量看起来是在限制模型实际上是在给模型指路。另外一点体会是适配器和LoRA这类低秩旁路模块在跨域问题里可能普遍带有解耦器的属性不止限于语义分割。凡是冻结主干加低秩旁路的用法旁路都倾向于吸收分布偏移主干保留通用知识。这个视角对做参数高效微调的人来说也许比单纯把它当作省算力的工具更有价值。6.2 值得继续做的几个方向如果我继续在这个方向上做会优先试这三件事。一是根据每层域差异程度自适应分配瓶颈维度——前面提过适配器残差范数可以当诊断信号那就直接用这个信号指导结构设计甚至可以做可微的维度搜索。二是把适配器和原型校准结合在目标域用极少量标注同时更新适配器和类别原型变成一种统一的两级适配框架。三是把这个思路移植到跨域少样本检测或点云分割上看看低秩旁路解耦的规律是否在别的主干结构上依然成立。最后分享一个我实际跑实验时的小习惯每次换跨域方向后先跑一个只训练适配器、不做目标域适配的快速实验把结果和纯冻结骨干对比。如果这个对比没有明显提升说明适配器在源域就没有学到有效的解耦修正这时候调什么测试阶段参数都没用应该回头查适配器结构和训练配置。这个小检查只要十几分钟能帮你省下大量在错误方向上反复试错的时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑