域适应概述:定义、动机、应用场景
各位好,我是你们这门课的老朋友。今天咱们聊聊域适应,这个在实战中让我又爱又恨的东西。
先说说我自己的经历。几年前我接手了一个项目,要在不同光照条件下做行人检测。训练集是在晴天白天拍的,结果模型一到阴天或夜晚就崩了。当时调了半天参数,数据也加了,还是不行。后来才意识到——这就是典型的域偏移问题。说白了,训练集和测试集的数据分布不一样了。
什么是域适应
域适应(Domain Adaptation)解决的就是这个痛点。它让模型在源域(有标签,比如晴天数据)上训练后,能迁移到目标域(无标签或少量标签,比如阴天数据)上表现良好。你想想看,如果每次换场景都要重新收集标注数据,那成本得多高?
一个经典的例子:
- 源域:合成图像(比如游戏渲染的街景),有精确标注的车辆和行人。
- 目标域:真实拍摄的街景,没有标注。
- 域适应就是让模型学会"忽略"渲染和真实之间的差异,只关注真正的物体特征。
为什么需要域适应
其实原因很直接——标注成本。一个标注框在特定场景下可能花几毛钱,但不同城市、不同天气、不同传感器……你根本标不完。我们算一笔账:
| 场景类型 | 标注成本(估算) | 域适应后节省 |
|---|---|---|
| 晴天白天 | ¥5/张 | 源域已有标签 |
| 阴天傍晚 | ¥6/张 | 无需新标注 |
| 夜间红外 | ¥8/张 | 无需新标注 |
曾经我遇到一个客户,他们要做不同城市街道的交通标志识别。每个城市路灯、涂装、风格都不同。他们一开始打算重标所有数据,被我拦住了。用域适应,只标一个城市的数据,其他城市直接迁移,效果只掉了5%以内。嗯,这里要注意:域适应不是万能药,但用在差异可控的场景下,效果极好。
应用场景一览
我归纳了几类最常见的场景:
- 图像分类与检测:合成数据→真实数据(自动驾驶)
- 语义分割:不同季节/城市的街景分割
- 医疗影像:不同设备厂商的MRI/CT图像
- 自然语言处理:产品评论域→社交评论域
- 语音识别:不同口音/麦克风/环境噪声
你可能会问:那直接做数据增强不行吗?行,但不够。数据增强解决的是已知变化,而域适应能应对未知的分布偏移。举个例子,数据增强能把晴天图片转成阴天(调亮度、加噪声),但无法模拟夜间红外相机的成像特性——那个物理模型完全不同。
域适应的三种基本范式
咱们先建立个框架,后面章节会逐一深入。按目标域标签可用性划分:
| 范式 | 目标域标签 | 核心思路 |
|---|---|---|
| 监督域适应 | 少量标签 | 微调+对齐 |
| 半监督域适应 | 少量标签+大量无标签 | 伪标签+对齐 |
| 无监督域适应 | 无标签 | 直接对齐分布 |
我个人习惯把无监督作为主攻方向——因为它最贴近真实工业场景。你想想看,要是目标域有标签,我干嘛还做域适应?直接训练不就完了?
一个简单的实例:手写数字识别
我们用MNIST(源域)和SVHN(目标域)来感受一下。MNIST是黑白手写数字,SVHN是街景门牌号——彩色、背景杂乱、数字形状差异大。直接拿MNIST训练的模型去测SVHN,准确率只有30%左右。经过简单的域适应(比如DAHCC或CorrAlign这类方法),能到70%以上。
代码示意(伪代码,理解思想即可):
# 源域特征提取器
source_feat = extractor(source_images)
# 目标域特征提取器(参数共享)
target_feat = extractor(target_images)
# 计算分布差异(比如MMD、对抗损失)
loss_domain = domain_discriminator(source_feat, target_feat)
# 分类损失(只在源域有标签)
loss_classifier = classifier(source_feat, source_labels)
# 联合优化
total_loss = loss_classifier + lambda * loss_domain
这里面有个关键点:domain_discriminator 要尽量区分不了哪个特征是哪个域的,而extractor 要尽量骗过它。这个对抗思想,是后面几章的核心。
λ = 0.1 开始调。
本章知识体系
我把核心逻辑画成了一张图,帮你理顺脉络:
从图上你能看到:源域和目标域之间存在域偏移,我们要学习域不变特征。然后按照目标域标签多少,分成三种范式。再往下,常见的方法包括分布对齐(MMD、CORAL)、对抗训练(DANN)、特征熵最小化等——这些都会在后续章节逐一实战。
域适应 vs 其他迁移学习
很多人容易混淆,我拿个表格说清楚:
| 概念 | 源域与目标域 | 任务 | 典型方法 |
|---|---|---|---|
| 域适应 | 数据分布不同 | 相同 | 分布对齐、对抗 |
| 迁移学习 | 可不同 | 可不同 | 微调、特征重用 |
| 预训练-微调 | 不同但相关 | 相似 | 冻结+全连接 |
| 多任务学习 | 共享输入 | 多个 | 共享底层+任务头 |
举个例子:预训练-微调假设源域和目标域任务非常接近(比如都是图像分类),而域适应专门处理分布变化但任务不变的情况。我以前犯过傻,直接用ImageNet预训练模型去测医学CT图,效果差得一塌糊涂——因为纹理、分布完全不同。后来换成域适应,效果才上来。
好了,这一章咱们把域适应的定义、动机、应用场景理清了。你脑海中应该有个整体框架:什么场景该用域适应、三种范式怎么选、常见方法有哪些。后面每一章都会在这个框架上添砖加瓦。