ARTICLE DETAIL

资讯详情

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

迁移学习入门到实践:微调、域自适应与负迁移避坑指南

迁移学习入门到实践:微调、域自适应与负迁移避坑指南 迁移学习这几年已经成了我项目里最常用、也最容易被误解的一套方法论。刚入行那阵我也跟很多人一样觉得模型就得从随机初始化开始练用别人训练好的权重就像抄作业心里没底。后来被小样本、贵标注、缺算力三座大山反复教育之后我才彻底转变思路能干着把知识从 A 任务搬到 B 任务本身就是一门极其讲究的学问。迁移学习解决的问题很朴素数据不够、标注太贵、算力吃紧而这三件事几乎出现在每一个真实项目里躲都躲不开。这篇文章的定位我尽量讲清楚。如果你是刚接触迁移学习的新手需要一份把概念、分类、套路一次性捋顺的入门综述如果你被“直推式迁移学习”“域自适应”“Fine-tuning”“负迁移”这些名词绕得头晕想找一个能落到代码和实验上的理解框架如果你已经跑过几个迁移实验但效果时好时坏想在调参和方案选型上少走弯路——那这篇文章值得你花十分钟读完。内容覆盖迁移学习的完整分类、四大核心实现路径、一套可复现的落地流程以及我从实际项目里踩出来的排坑经验全程只讲干货。1. 迁移学习解决什么问题先理解为什么要迁1.1 真实项目里的三个死穴先说我印象很深的一次经历。早几年做工业质检工厂给了两千张带缺陷标签的钢材表面图像。这个数据量撑不起一个稍微深一点的卷积网络团队里有同学不信邪坚持从零训练 ResNet-18跑了一周测试集准确率停在 83% 上不去。后来我把 ImageNet 上预训练好的 ResNet-50 取出来替换分类头冻住前面大部分参数只做三十轮微调半天时间准确率刷到 94%。一周到半天差了整整一个数量级的时间成本这就是迁移学习最直观的价值。这种故事背后的困境通常可以归成三类数据稀缺目标任务只有几百上千个样本连一个中型网络都喂不饱更别说今天动辄上亿参数的模型。标注昂贵医疗影像、工业缺陷、法务文本这些垂直领域的标注高度依赖专家单样本成本从几元到几百元不等大规模标不现实。算力紧张从零训练大模型的费用非常惊人大部分团队根本没有这个预算更等不起那个训练周期。这三件事是每个做实际业务的人都会撞上的墙。而迁移学习给出的解决办法是别再死磕“从零开始”去已有的、或许不完全对口的资源里搬知识过来用。1.2 迁移学习和传统学习到底有什么不一样传统机器学习的默认假设是训练集和测试集服从同一分布模型学到的规律在同一个分布里成立。但真实世界里这个假设太脆弱了。你在晴天拍摄的数据上训练完部署到阴雨天、夜间的环境就掉点A 医院的 CT 影像和 B 医院的 CT 影像因为设备型号、扫描参数、患者人群不同模型精度也会肉眼可见地下降。传统的“同分布假设”在实际场景中几乎总是被打破。迁移学习恰恰是冲着一个不同的问题来的它允许源域和目标域不同也允许源任务和目标任务不同。所谓源域就是你已经拥有丰富标注数据或成熟模型的领域目标任务则是你当前要解决的、数据相对紧张的领域。迁移学习的目标是把从源域学到的可复用知识转移给目标任务让后者不再从零起步。用一个很生活化的比喻普通训练是让一个学生面对一张白纸从零学起迁移学习则是给这个学生一屋子参考书让他带着这些积累去学一门新课程。参考书不可能完全对口但里面写着的通用规律——图像里的边缘、纹理文本里的语法、逻辑模式——恰恰是可以迁移的部分。这个朴素的观察是整个迁移学习领域的起点。2. 迁移学习的分类框架别再被各种“迁移”绕晕迁移学习发展了这么多年分类体系有好几种版本。我在实际调研里觉得最有帮助、也最贴近工程选型的是按“源域和目标域的标注情况”来划分。这样分完你面对一个具体任务时能立刻知道自己手里有什么牌该往哪个方向找方法。2.1 三个大方向直推式、归纳式、无人监督式按典型教材和组织方式迁移学习可以分为三大类我整理成一张表方便对照类型源域标签目标域标签源任务与目标任务典型场景直推式迁移学习有无任务相同、域不同源域训练好的分类器迁移到无标注的新数据域归纳式迁移学习可有可无有任务可以不同预训练 微调NLP/CV 里的主流玩法无人监督式迁移学习无无任务相关但不完全一致跨域聚类、降维、表征学习这三类的核心差别就看目标域到底有没有标签。目标域有标签基本走归纳式目标域没有标签、但任务不变走直推式两个域都没有标签就只能走无人监督式。这个判断规则简单但是决定后续技术路线的关键。2.2 直推式迁移学习重点拆解直推式迁移学习Transductive Transfer Learning是我每次讲综述都要单独拎出来强调的概念因为太多人把它直接等同于“域自适应”严格来说这两个词不能完全画等号。域自适应是直推式迁移学习最主要的实现形式但直推式的外延更大它还包括多任务学习中目标域无标注的那一部分设定。直推式的完整设定是这样的源域有大量标注数据目标域只有无标注数据而且两个域的任务是同一个例如都是分类且类别体系一致但两个域的数据分布不同。目标域数据在训练阶段是可见的只是没有标签。这个设定很有工程意义——你手头拿到一批全新的、没有标注的数据希望之前的分类器能在这批数据上表现好自然要用上这批数据本身提供的信息。它的主流解法有两个方向基于样本的方法从源域中挑出和目标域分布更接近的样本给它们更高权重甚至可以放弃偏离过大的源域样本。本质上是做分布适配让源域“看起来像”目标域。基于特征的方法把两个域的数据映射到一个公共特征空间在这个空间里尽量拉近两个域的分布差异。经典做法有最大均值差异MMD配合核映射深度时代的代表则是 DANNDomain-Adversarial Neural Network用梯度反转层来训练域对抗特征。讲一个我做过的实际例子在公开数据集上训练了一个车型识别模型要迁移到另一个城市、另一套摄像头系统拍出来的车型数据上。目标域图片一张标注都没有但可以用无标注目标域参与特征对齐训练。这就是直推式最舒服的应用场景把模型搬到一批“看得见、标不起”的数据上。实操里要特别提醒一点直推式迁移对目标域数据量有最低要求。如果目标域只有几十张图特征分布统计完全不可靠对齐训练不仅没用反而可能把已经学好的特征带偏。这时候老老实实直接使用源域模型做推理效果反而更好。我一般建议目标域数据至少具备几百张以上才值得走直推式路线。2.3 归纳式迁移与无人监督式迁移归纳式迁移学习是当下最“热”的玩法因为预训练 微调就是它的典型代表。源域的任务通常是大规模预训练任务比如在互联网海量文本上训练语言模型、在 ImageNet 上训练图像分类模型目标任务则是具体的下游任务比如情感分类、实体抽取、细粒度图像识别。归纳式的关键特点是目标任务有自己的标签所以整个流程非常直接从预训练模型出发在目标任务标注数据上继续训练。它不要求源任务和目标任务一致也不要求目标域数据出现在预训练阶段。无人监督式迁移学习在实际工程中的出现频率略低主要分布在深度聚类、跨域生成、自监督表征学习这类任务上。举个例子在大量无标注的自然图像上学习一个编码器再迁移到医学影像的聚类任务上。即便医学影像一张标签也没有迁移过来的编码器往往也比直接在目标域上训练的编码器稳定得多。它的机理在于域无关的特征提取能力——边缘、纹理、形状这些底层结构规律在预训练阶段就已经被捕获了。3. 四大核心实现路径样本、特征、模型、关系分类框架解决的是“往哪个方向走”的问题真正到了落地阶段还需要解决“用什么技术手段迁移”的问题。目前主流的方法可以归纳成四条路径基于样本、基于特征、基于模型、基于关系。我逐个拆给大家。3.1 基于样本的迁移靠加权和筛选硬调分布基于样本的思路最直白源域里有些样本跟目标域根本不是一路人强行拿进来训练会拖后腿所以干脆给源域样本重新加权或者直接筛选出最接近目标域的那些样本让源域的分布朝着目标域靠拢。这类方法的代表算法是 Kernel Mean MatchingKMM和 TrAdaBoost。KMM 的核心思路是估计一组权向量使得加权后的源域样本均值在再生核希尔伯特空间里尽量接近目标域样本均值。听起来很优雅但实际操作有两个痛点一是核函数和带宽参数需要仔细调二是数据量大了之后求解权向量比较慢。所以我自己的工程实践里TrAdaBoost 反而更常见。它类似 AdaBoost 的改版通过迭代训练多个分类器自动降低那些与目标域不匹配的源域样本权重把“不太对路”的样本迭代排除掉。基于样本适合什么场景我认为是源域和目标域整体分布有重叠只是局部偏移时。比如同一个拍摄设备在不同光照条件下采集的图像用样本加权可以很快地修正模型。如果两个域差的实在太远——拿手写数字去帮助工业零件缺陷识别——样本加权基本没有意义因为源域里根本没有多少“靠谱”样本可挑。这种情况下就应该考虑特征级方法。3.2 基于特征的迁移在公共空间拉近分布基于特征的方法是当前理论基础最扎实、研究产出最密集的方向。它的核心假设是存在一个公共特征空间把源域和目标域数据映射到这个空间之后两个域的分布差异可以被显著缩小。在这个空间里用普通的分类器或回归器就可以同时应付两个域。分布差异怎么度量是整个方向的灵魂。常见的度量方式有两类最大均值差异MMD计算两个分布在再生核希尔伯特空间中的均值差。简单理解就是把分布映射到高维空间之后看它们的数据中心差了多远。深度网络可以直接在特征层上计算 MMD把它当成训练损失的一部分。对抗损失引入一个域判别器让特征提取器尽可能“骗过”判别器让它分不清特征来自源域还是目标域。训练到最后特征提取器学到的是两个域共同的特征表达。DANN 是这一系的代表作后面的 CDAN、WDGRL 等都是在对抗思路上做的改进。基于特征的方法有两个非常实用的工程经验。第一特征提取器容量不能太小浅层小网络根本学不出有区分度的域不变特征视觉任务里至少从 ResNet-18 往上起步效果会更稳。第二域对抗损失和任务分类损失之间的权重十分敏感。权重偏大时特征会被拉向各向同性类别可分性下降权重偏小时域不变性又不够迁移效果不明显。多数论文推荐的起点是 0.1我测试下来确实是个能用的初值具体还要在自己的验证集上微调。3.3 基于模型的迁移Fine-tuning 为什么这么高效基于模型的迁移是工程落地理度最高的一条路平常说的“Fine-tuning”微调就在这里。核心思想很简单加载一个在源任务上表现很好的模型保留它学到的参数替换掉输出层用目标任务的数据继续训练。为什么 Fine-tuning 效果好到成为了行业默认做法关键在于深度学习模型的层级结构。预训练模型的浅层学到的是边缘、颜色、纹理这类高度通用的特征中层学到的是部件和局部模式深层才与具体任务强绑定。做目标任务微调时通用特征直接被继承新的分类头负责把目标任务的类别信息重新组织起来。换句话说预训练已经帮你修好了“眼睛”你只需要教会它“看什么”。图像分类微调的经验我总结了这么几条目标域只有几百张图时把输入图预处理得和预训练阶段一致尺寸、归一化、色彩空间非常关键这个小细节能做到和模型权重“无缝衔接”。BatchNorm 层不要一直冻结我习惯在微调中解冻 BN 层让统计量更新多数情况下能带来 2 到 5 个点的提升。学习率永远是第一优先级。用 AdamW 时初始学习率设在 1e-4 左右比较稳很多新手一上来开 1e-2模型直接发散。文本任务的做法类似但注意 tokenizer 版本要和预训练模型匹配BERT 类模型的初始学习率通常更低在 2e-5 到 5e-5 的区间里更合适。3.4 基于关系的迁移结构相似性也能搬最后一条路径相对偏研究向但在某些领域很管用值得知道它的存在。它不要求源域和目标域的样本在内容上相似只要求两个域之间的“关系结构”有可迁移的模式。最典型的例子是社交网络社交网络 A 的好友关系结构可以辅助预测社交网络 B 的人际关系知识图谱的实体关系嵌入可以辅助另一个领域的关系推理代码抽象语法树的层级关系也可以用来做跨语言的缺陷预测。这类方法的实现通常不是开箱即用的需要你自己定义清楚“关系”是什么用什么相似度度量、用什么结构指标、怎么把关系结构编码成特征。因为建模成本高、调参自由度大工程风险也相对高。我的建议是除非业务上能非常明确地描述两个域之间的结构共性否则先从基于模型或基于特征的路线入手。4. 实操从方案选型到完整落地流程4.1 迁移可行性评估动手前先问自己四个问题见了太多次“拿到任务直接开始 Fine-tune”的操作结果跑出来效果还不如小模型从零训练。所以第一步一定是做可行性评估。我习惯把它拆成四个问题源域和目标域到底相关吗完全不相关比如用语音识别模型迁移到涂鸦分类的情况下迁移不仅无效还大概率负迁移。目标域数据量有多少几十张样本连微调都撑不起来这种情况下直接用预训练模型做特征提取冻结全部参数只训练分类头反而更靠谱。目标域有没有标签没有标签且任务不变走直推式有少量标签走归纳式微调。这个判断直接决定方法选型。算力预算在哪一档算力紧张时选小规模预训练模型配合全参数微调比选超大模型配合参数高效微调更稳妥因为大模型的加载和推理本身就占用大量资源。这四个问题想清楚基本能排除掉一半不合适的方案。4.2 参数选型与训练策略一个稳定的 baseline图像分类微调里我常用的稳定的 baseline 设置如下预训练权重ImageNet-1k 上的 ResNet-50torchvision 官方权重 分类头替换为输出维度等于目标类别数的全连接层 优化器AdamW 初始学习率1e-4 权重衰减0.05 学习率调度CosineAnnealingLR最小学习率 1e-6 训练轮数10 轮起步配合早停 Batch size32显存不足可降至 16并用梯度累积补偿 预处理统一 resize 到 224x224使用 ImageNet 的 mean/std 归一化这些数字不是一个万能配方但确实是经过大量实验验证的稳妥起点。很多人忽略的一点是图像预处理也要跟着预训练权重走。你用 ImageNet 预训练权重就要用 ImageNet 的归一化参数否则预训练学到的特征分布和你的输入不匹配效果打折扣。文本任务也是同理tokenizer 和预训练模型来自同一个版本和同一套词表这个细节要严格对齐。训练过程中有一个我强烈建议执行的策略早停。微调本来就容易过拟合尤其是目标域数据量小的时候。在验证集上监控 loss 或准确率连续若干轮没有提升就停止训练。这能省下大量试错时间。4.3 最小可复现流程从加载权重到训练输出下面这段描述的是图像分类迁移的最小可复现流程翻译成 PyTorch 代码大概不到一百行加载预训练模型去掉最后一层分类头。添加新的分类头fc_new输出维度设置为目标任务类别数。目标数据少于 1000 张时冻结骨干网络大部分层只训练最后 1 到 2 个 block 和分类头。目标数据多于 10000 张时解除冻结对骨干网络全参数微调。数据预处理和预训练阶段保持完全一致尺寸、均值、方差。用 AdamW 低学习率训练配合 Cosine 学习率衰减。在验证集上监控 loss 和准确率触发早停条件则停止。效果不理想时逐步解冻更多的层重新训练。第 3 和第 4 步的数据量阈值是经验值我见过五千张数据全参数微调成功的也见过两千张数据全参数微调直接崩掉的关键还是要看任务本身的难度和图像多样性。但骨架流程是通用的可以先照着跑再根据结果做决策。这里插一句千万不要一开始就全参数微调一个小数据集。冻结骨干、只调分类头得到的结果可以直接用来判断“这套预训练特征在目标任务上到底行不行”。如果冻结特征的 baseline 就已经不错那说明特征本身质量够高后面微调会顺很多。如果连冻结特征都不如随机初始化训练别犹豫立刻换预训练模型或者重新评估任务相关性。4.4 工具与框架哪些库值得放进日常工作流做迁移学习实验扎实的工具链能省掉大量无用功。我常用的有下面这些PyTorch Image Modelstimm收录了大量预训练图像模型权重接口统一下载权重、改分类头、预处理都封装得很干净视觉迁移必备。Hugging Face Transformers 和 PEFTNLP 和跨模态预训练模型最全的生态LoRA、Adapter 这类参数高效微调直接内置极大降低了尝试成本。DomainBed做域自适应研究或对比实验时的参考 benchmarkDANN、CORAL、CDAN 等流行方法都有现成实现。MMClassificationOpenMMLab完整工具箱图像分类任务里的迁移实验高度配置化适合批量做消融实验。需要提醒的是timm 和 Transformers 提供的预训练权重有各自的许可证和商用限制尤其是用在大规模训练数据上的权重落地前务必核对授权条款。5. 常见问题与避坑指南5.1 负迁移迁移后的效果还不如不迁移负迁移是迁移学习最让人头疼的问题它指的是迁移操作反而导致目标任务的性能低于直接从头训练。踩过这个坑的都知道有多痛苦但它的诱因其实很集中源域与目标域完全不相关。你搬了一个与任务毫无关系的预训练模型过来相当于让一个学法律的人去做心脏手术。源域模型学到的特征过拟合于源域噪声这些噪声在目标域不仅没用还干扰分类器。目标域数据极少同时源域和目标域分布差得离谱微调根本拉不回分布差异。排查负迁移时有一套 30 分钟的快速流程对比随机初始化模型和预训练冻结特征模型在目标任务上的表现。如果冻结特征模型明显比随机初始化差直接判定预训练模型与任务严重不匹配放弃这个源。如果两者接近再进一步比较全参数微调的效果判断是否值得继续调。这个流程虽然简单但可以快速过滤掉大部分负迁移情况把精力花在正确的源域上。5.2 域偏移模型在源域好端端到了目标域就拉胯域偏移和负迁移经常同时出现但本质不同。域偏移说的是源域和目标域数据分布本来就不一样模型在源域表现很好但部署到目标域就掉点。迁移学习要做的就是主动应对这个分布差异。缓解域偏移的手段从轻到重排列BatchNorm 统计量校准用目标域无标注数据重算 BN 层的 running mean 和 variance成本很低效果有时出奇地好。特征分布校准用 CORAL 这类方法使源域和目标域的二阶统计量协方差尽量对齐。对抗域适应使用 DANN、CDAN 训练域对抗特征效果更强但需要额外训练一个域判别器训练复杂度也更高。测试时自适应 TTA部署阶段利用目标域无标注样本进行在线自适应这类方法近几年在连续变化场景中表现很好。我建议按顺序优先试便宜的手段。很多人上来直接跑 DANN如果数据量不够训练不稳定反而浪费大量时间。5.3 训练不稳定loss 振荡、精度上不去微调比从头训练更容易出现训练不稳定因为预训练权重的 loss landscape 和你新增的分类头之间经常存在“代沟”。经验上最有效的三个调整项学习率降一档这是第一优先级。微调的学习率通常要比从零训练低一到两个数量级。Batch size 适当缩小或者用梯度累积来补偿某些模型对 batch size 很敏感。增加 warmup 步数让模型先用小学习率“热热身”再进入正式学习率微调大模型时尤其有用。训练稳定的标志不是 loss 一开始就下降而是曲线平滑地、逐步地回落。如果 loss 曲线剧烈上下跳动基本可以断定学习率或者 batch size 出了问题。5.4 问题速查表症状可能原因解决动作迁移后效果反而下滑源域与目标域相关度太低评估共享特征考虑更换预训练模型训练初期 loss 爆炸学习率过大降低学习率增加 warmup目标域精度低但源域很高域偏移较大引入域自适应或对目标域邻近样本加权冻结特征训练效果差任务差异较大解冻更多层或换更大容量的预训练模型显存不足模型过大或 batch 过大使用梯度累积、混合精度或换更小模型微调后灾难性遗忘学习率过高或数据过度拟合降低学习率增大权重衰减配合早停这张表在我日常实验里被翻来覆去地使用每一个问题都是真金白银踩出来的。6. 一些多年实践后的个人体会跑了这么多年迁移学习实验我越来越觉得它不是一个独立的“模型”而是一整套建模思维。它的价值不体现在某一条公式、某一个网络结构上而体现在“如何利用已有知识解决问题”的视角上。很多项目能把源域选对、能搞清楚分布差异怎么度量其实已经成功了一大半。最后分享一个很实用的小技巧做视觉迁移时别急着盯最终 accuracy先看预训练特征在目标域上的 t-SNE 可视化。如果目标域样本在特征空间里已经被预训练模型分出了清晰的簇结构说明这个源模型的通用特征质量很高可以放心走微调路线如果特征图糊成一团先回头检查数据清洗、预处理、或者说换个更合适的源模型再谈训练策略。迁移学习的模型和工具每年都在更新但核心问题永远是那几个源域怎么选、分布差异怎么度量、负迁移怎么解决。把这几个底层问题吃透不管模型怎么变你都能在具体业务里找到最适合自己的迁移方案。后续如果大家感兴趣我还可以专门写一篇文章把 DANN 的代码实现和调参细节全部拆开讲一遍。
返回列表