Unsupervised Domain Adaptation (UDA)
无监督域适应将使用带标签源域数据训练的模型适配到只有无标签数据的新目标域,从而缩小域差距。
无监督域自适应(UDA)会调整在某个场景(源域)的带标注数据上训练的模型,使其适用于另一个场景(目标域);目标域只有未标注数据。两个域的任务和类别相同,但输入外观不同:合成渲染与真实照片、不同医院的扫描仪、白天与夜间的街道,或不同型号的摄像机。仅在源域训练的模型在目标域上往往会损失大量准确率;UDA 无需在新域中投入数据标注成本,就能恢复准确率。UDA 属于迁移学习的一个分支;“无监督”仅指目标域缺少标签。
域偏移为何影响模型#
Shai Ben-David 等人在 2010 年提出了这一问题的标准理论。分类器在目标域上的错误由三项构成上界:它在源域上的错误、分类器族看来两个域有多大差异的度量,以及对两个域都适用的最佳单一分类器的错误。第一项可通过使用源域标签进行常规训练来降低。大多数 UDA 方法会针对第二项,学习能让源域与目标域输入看起来相似的特征;第三项则提醒我们,如果域之间的标签关系本身发生变化,自适应就会失败。
主要方法#
- 统计匹配:对齐源域和目标域特征的简单统计量。最大均值差异和 CORAL(匹配特征协方差)会在训练损失中加入惩罚项;Yanghao Li 等人在 2016 年提出的 AdaBN 则直接用目标域数据重新计算每个批归一化层的均值和方差。
- 对抗式对齐:Yaroslav Ganin 和 Victor Lempitsky 于 2015 年提出的域对抗神经网络(DANN),会训练一个域分类器来区分源域特征和目标域特征;梯度反转层则促使特征提取器欺骗该分类器。
- 图像转换:CycleGAN 等生成模型会改变源图像的风格,使其看起来像目标域图像,这样带标签的训练图像就会更接近部署时的图像;CyCADA 就将此方法用于驾驶场景。
- 自训练:源域模型为目标域图像生成标签,将置信度高的预测作为伪标签,再用这些伪标签重新训练模型;训练时通常会使用缓慢更新的教师模型,以保持标签稳定。
- 无源自适应与测试时自适应:SHOT 无需访问源域数据即可自适应已训练模型;TENT 则在推理时仅更新批归一化参数,通过提高模型对测试批次预测的置信度来完成自适应。
AdaBN 展示了域差异有多少可能来自批归一化层中的统计量。这个 PyTorch 示例使用 1,000 张手写数字训练一个小型网络,并在其余数字上测试;这些数字经过渲染,呈现出曝光不足的相机拍摄效果,具有更低的对比度和更高的亮度:
import torch
from sklearn.datasets import load_digits
from torch import nn
torch.manual_seed(0)
X, y = load_digits(return_X_y=True)
X, y = torch.tensor(X / 16, dtype=torch.float32), torch.tensor(y)
target_x = 0.3 * X[1000:] + 0.6 # target domain: the last 797 digits as a washed-out camera would capture them
# Train on the labeled source domain, the first 1,000 digits
model = nn.Sequential(nn.Linear(64, 64), nn.BatchNorm1d(64), nn.ReLU(), nn.Linear(64, 10))
optimizer = torch.optim.Adam(model.parameters(), lr=1e-2)
for _ in range(200):
optimizer.zero_grad()
nn.functional.cross_entropy(model(X[:1000]), y[:1000]).backward()
optimizer.step()
model.eval()
print(f"Target accuracy before adaptation: {(model(target_x).argmax(1) == y[1000:]).float().mean():.3f}")
# AdaBN: replace the source BatchNorm statistics with those of the unlabeled target images
model[1].reset_running_stats()
model[1].momentum = None # use a plain average over the target batch
model.train()
with torch.no_grad():
model(target_x)
model.eval()
print(f"Target accuracy after adaptation: {(model(target_x).argmax(1) == y[1000:]).float().mean():.3f}")对偏移后数字的准确率从 0.290 提升至 0.940,全程无需任何目标域标签,接近同一模型在偏移发生前对这些数字取得的 94% 准确率。提升幅度之所以如此明显,是因为对比度和亮度变化经过第一个线性层后,会转变为逐特征的偏移和缩放,恰好是重新归一化所能消除的;形状或内容上的偏移则需要使用上述更强的方法。
基准测试与应用#
Kate Saenko 等人于 2010 年发布的 Office-31 包含来自三个域的 4,110 张办公物品图像,共 31 类:亚马逊商品照片、网络摄像头拍摄的照片和 DSLR 照片。VisDA-2017 要求模型将 12 类物体的合成 3D 渲染图训练所得的知识迁移到真实照片上;GTA5-to-Cityscapes 则使用电子游戏中的 24,966 帧训练语义分割模型,并在真实城市街道图像上测试。
同样的模式也推动着实际应用。自动驾驶汽车会用合成数据和模拟器渲染补充真实驾驶素材;医学图像分析模型必须适用于不同厂商的扫描仪和不同医院;农业模型则要应对新的田地、作物品种和季节。检测器通常通过自训练进行自适应:Ultralytics Python 包中的 auto_annotate 函数会对未标注图像文件夹运行 YOLO26 检测器,用每个检测框提示 Meta 的 Segment Anything Model (SAM),并写出 YOLO 格式的分割标签;这样,在源域上训练的检测器就能为目标域图像生成伪标签,供审核和微调使用。
UDA 与相关设置#
监督微调需要目标域标签;半监督学习假设带标签和未标注数据来自同一分布。域泛化完全没有目标域数据,而是通过数据增强和域随机化训练模型,使其能够适应未见过的域。分布鲁棒优化会针对一系列可能的偏移进行准备,而 UDA 则针对模型已见过图像的某一个目标域进行自适应;数据漂移监控可以显示已部署模型何时进入需要自适应的新域。










