← 阅读室全部精读正在排版公式与图表…
PAPER ANALYZER · P17 · 跨场景方向

DANN:让特征识别类别,却难以暴露来源

拆解领域对抗、梯度反转与无监督适配的适用边界

Ganin et al. · JMLR 2016 · arXiv:1505.07818

一句话总结

源域监督保持语义,领域对抗减少分布差异;目标域输入仍然需要在训练时可访问。

DANN 的问题设定:目标域无标签,不是没有目标域

Domain-Adversarial Training of Neural Networks 由 Ganin 等人发表于 JMLR 2016。本页阅读其完整论文及补充实验,重点解释无监督领域适配。源域有样本和任务标签,目标域有样本但没有任务标签;训练期间两域样本都能访问。这里的“无监督”只描述目标域的情感或类别标签缺失,并不是训练过程没有任何监督。

设想已经标注的一批访谈表情视频是源域,另一批直播视频是目标域。两者都使用相同的七种表情类别,但背景、光照、人物表达方式不同。直接训练源域分类器可能依赖访谈中的背景线索,因此换到直播失效。DANN 希望表示仍能识别类别,却不容易暴露样本来自哪个域。

这与持续学习不同:DANN 没有要求你先学完源域后销毁它,也没有专门保存历史任务知识的机制。把它用于逐场景学习必须说明旧场景数据是否还在;如果旧数据不可访问,原始训练目标中的源域监督项就失去输入,不能仍然声称完整复现了 DANN。

三个网络分别在做什么

特征提取器把原始输入转成特征向量,类别预测器根据特征判断类别,领域判别器根据同一特征判断源域或目标域。领域标签并不需要人工标注,因为数据来自哪个集合是已知的。把表情标签与领域标签混用,会把无监督适配误做成目标域有监督训练。

训练有一个刻意安排的冲突:领域判别器希望尽量分清两个域,特征提取器希望让它分不清。与此同时,特征提取器还要帮助源域类别预测保持正确。单纯把所有特征变成同一个向量当然能骗过领域判别器,但会破坏类别分类,任务损失正是防止这种无意义坍塌的重要约束。

原文 Figure 1 可以按数据和梯度两条路线阅读。前向时所有箭头都是普通网络计算;反向时领域支路经过梯度反转层,只有传回特征提取器的梯度改变符号。领域判别器自己的参数仍正常下降其分类损失,类别支路也正常训练。理解“只对哪一部分反转”比记住对抗这个词更重要。

$$L_y=\frac1{n_s}\sum_{i=1}^{n_s}\operatorname{CE}(G_y(G_f(x_i^s)),y_i^s)$$

原文监督项的均值写法。只有源域标签进入类别损失;目标域标签即使保存在数据文件中,也不应传入这一项。

$$E(\theta_f,\theta_y,\theta_d)=L_y-\lambda L_d$$

对应原文式(10)的目标结构。特征和类别参数最小化 E,领域参数最大化 E;对领域参数来说最大化负的领域损失等价于最小化领域损失。

$$R_\lambda(z)=z,\qquad \frac{\partial R_\lambda}{\partial z}=-\lambda I$$

原文式(16)—(17)的梯度反转层。前向不改变数值,反向乘负系数。这是特意定义的反向算子,不能把前向代码简单写成负的特征来替代。

$$\theta_f\leftarrow\theta_f-\eta(\nabla_{\theta_f}L_y-\lambda\nabla_{\theta_f}L_d)$$

原文更新规则的简记。若已经使用梯度反转层,实际程序可以把类别损失与领域损失正号相加;再手动减领域损失会造成两次反转,训练方向反而错误。

$$\lambda(p)=\frac{2}{1+\exp(-10p)}-1,\quad p\in[0,1]$$

原文深层网络实验的渐进安排。p 是整体训练进度,开始接近零,逐渐加强对齐。领域分类器本身可以从一开始正常学习,不应把它的全部梯度也一同压成零。

$$\widehat d_{\mathcal A}=2(1-2\epsilon)$$

原文式(3)的代理 A 距离。epsilon 是区分两域的分类误差;均衡两域且分类器充分训练时,随机水平误差二分之一对应距离零。误差零点一对应距离一点六。

为什么分不清域可能有帮助,又为什么并不够

原文的理论动机把目标域错误与源域错误、领域差异和两域共享分类器的最小联合错误联系起来。减小领域差异只是其中一项。如果两个域的类别含义不一致,或者同一种表情在特征空间里发生难以兼容的变化,共享分类器本身可能无法同时做好,两域整体分布接近也不能救回分类。

对初学者最直观的反例是两域类别比例不同:源域多数为高兴,目标域多数为悲伤。强行把整体特征分布完全重合,可能把目标域悲伤推到源域高兴区域。这说明领域不变并不自动等于类别语义不变。你应检查按类别的混淆,而不是只看领域准确率下降就宣布成功。

领域准确率接近一半还可能来自判别器太弱、优化没有收敛、两域样本数量不平衡,或者特征丢掉了全部信息。应训练一个独立的后验领域探针,在固定特征上验证可区分程度,同时看源域分类和目标域最终表现。原文 Figure 3 的距离实验有具体训练设置,不能把任意小网络的随机输出当作同样证据。

原文 Theorem 2 的额外项包含理想共享假设的联合误差及有限样本复杂度。它提供的是理解方法的条件,不是训练损失一降就能保证任何目标数据准确率提高。研究报告里可以说方法试图减小领域差异,但不能说它已经证明完全消除了场景偏差。

flowchart TD
S[Labeled source] --> F[Shared encoder]
T[Unlabeled target] --> F
F --> C[Class head]
F --> R[Gradient reversal]
R --> D[Domain head]
D -. Reversed gradient .-> F
C -. Normal gradient .-> F

原文实验:平均有效不等于每个迁移方向都有效

原文 Table 1 的亚马逊评论实验跨书籍、光盘、电子产品和厨房用品迁移,任务是评论情感分类,输入是词特征。每个设置使用两千个有标签源域样本与两千个无标签目标域样本,目标测试集依方向有数千样本。下面保留三个方向,观察同一个方法既有改善,也会失败。

第二张表仍来自 Table 1,但输入改成 mSDA 特征。这样可以看到特征预处理与对抗训练的作用并非完全等价。厨房用品迁移到书籍时,mSDA 加线性 SVM 的结果高于 DANN;这不是可以忽略的小异常,而是提醒我们不能把所有差异归结为领域判别能力不足。

原文 Table 1:原始词特征,目标准确率
迁移方向普通神经网络DANN线性 SVM
书籍→光盘0.790.7840.799
光盘→电子产品0.7320.7540.748
厨房用品→书籍0.7080.7090.707
原文 Table 1:mSDA 特征,目标准确率
迁移方向普通神经网络DANN线性 SVM
书籍→光盘0.8240.8290.83
光盘→电子产品0.7680.8090.739
厨房用品→书籍0.7210.7180.769

看图时应带着的问题

原文 Figure 2 是旋转双月形数据示例:它帮助理解分类边界如何在无目标标签情况下变化,不代表真实视频的所有复杂性。Figure 5 的特征可视化展示分布变化,但二维投影可能隐藏高维差异。你可以把这些图当作机制说明,最终判断仍依赖独立测试和完整对照。

原文也报告从 MNIST 到 SVHN 的困难,目标准确率约四分之一,并没有取得有效提升;反方向表现不同。迁移不是对称关系,简单手写数字到复杂街景的难度不同于反向。对于表情研究,也应分别报告访谈到影视和影视到访谈,不能用一个方向代替全部跨场景能力。

Office 实验使用完全转导式设定,训练时可以看见目标集合的无标签输入。若你的实际应用是面对未来完全不可见的新场景,这与论文设定不同,应另建严格留出目标测试样本的协议。输入可见性、标签可见性、模型选择可见性是三个独立维度,实验表头最好同时写清。

源码走读:反转层和训练损失

本次确认了作者团队的浅层实现仓库 GRAAL-Research/domain_adversarial_neural_network,其说明对应论文浅层实验;下列实际克隆并逐行阅读的是 fungtion/DANN 的第三方 PyTorch 教学实现,不能标作作者原始深层实验代码。它的 README 面向旧版 Python 与 PyTorch,需要迁移兼容接口,本文没有声称已直接跑通。

第一段反转层保存 alpha,并在反向阶段把梯度取负。第二段展示模型如何同时返回类别和领域输出。训练文件先计算源域类别与领域损失,再计算目标域领域损失,最后正号相加。目标样本的类别值被忽略,因此检查这一行比仅检查数据目录是否含标签更可靠。

第三方训练配置使用 Adam、学习率零点零零一和一百轮,不能与原文深层网络的 SGD 动量与衰减设置混称为一套配置。原文使用渐进领域权重,基础学习率零点零一、动量零点九及按训练进度的学习率衰减。复现时应选择一个目标版本并记录差异,避免同时拼接多个仓库的默认值。

第三方 MIT 实现:梯度反转:models/functions.py:4–15;固定提交 476147f70bb8。

class ReverseLayerF(Function):

    @staticmethod
    def forward(ctx, x, alpha):
        ctx.alpha = alpha

        return x.view_as(x)

    @staticmethod
    def backward(ctx, grad_output):
        output = grad_output.neg() * ctx.alpha

第三方 MIT 实现:两条预测路径:models/model.py:38–47;固定提交 476147f70bb8。

    def forward(self, input_data, alpha):
        input_data = input_data.expand(input_data.data.shape[0], 3, 28, 28)
        feature = self.feature(input_data)
        feature = feature.view(-1, 50 * 4 * 4)
        reverse_feature = ReverseLayerF.apply(feature, alpha)
        class_output = self.class_classifier(feature)
        domain_output = self.domain_classifier(reverse_feature)

        return class_output, domain_output

具体学习练习:先证明梯度正确,再做跨场景

第一项练习无需数据集:令输入为一个可求导标量,领域损失是其平方,在 alpha 等于零、二分之一和一时比较输入梯度。验收结果应分别为零、普通梯度的负二分之一、普通梯度的相反数。再检查领域分类器自身的参数梯度没有反转。这能直接排除最常见的双重负号错误。

第二项练习用两团二维点做源域,再旋转得到目标域。固定随机种子和每类样本数,先训练普通分类器,再加领域头。保存决策边界、源域准确率、领域探针准确率和目标测试准确率。不要把目标标签交给训练器;它们只在最后评价脚本中出现,文件和接口上就应隔离。

第三项练习回到视频:选择同标签空间的两个场景,先用冻结编码器提取定长特征,输入一个小型共享映射与两个预测头。先跑一个批次,打印源目标数量、标签掩码和三个损失;再做短训练。这样先验证对抗机制,避免把视频解码、时序建模和领域适配三类问题同时混在一起。

第四项实验只改变领域权重,比较零、固定值和渐增方案。验收不是必须超过基线,而是能解释每个设置的源域保持、目标域收益与领域可区分性。如果领域准确率下降而目标变差,应查看类别混淆、特征方差和类别比例,而不是无限增强对抗系数。

最后写一份两页记录:第一页明确源目标输入和标签是否可访问,第二页给出方向完整的结果矩阵与失败案例。对你的研究主线而言,DANN 提供“如何减少域信息”的基线;它没有回答“旧域不能回看时如何保留知识”,这个空缺正是接下来阅读 LwF、EWC、GPM 与 EmWorld 的原因。

附加来源:JMLR 出版页面;作者浅层实验仓库。

针对表情任务的进一步实现判断

领域头读取的是一个向量还是整段序列,需要在实验前确定。若把每帧都当成独立域样本,长视频会贡献更多领域损失;若先池化成视频向量,每个视频贡献一次。两者的权重与时间信息不同,不能在保持损失公式名字相同的情况下认为实验完全一致。初学阶段建议固定视频长度并用视频级特征,先把这一混杂因素去掉。

源域和目标域的批量比例也影响领域损失。假如大部分样本来自源域,一个始终猜源域的分类器就能得到很高准确率。最小实现采用两域等量采样,并分别记录源域与目标域的领域准确率;若数据规模不同,明确一个 epoch 是按较短集合截断还是循环较小集合。

作者局限包括方向不对称以及某些复杂目标域上的失败。独立判断是,表情场景中类别比例和背景通常一起变化,全局领域对齐可能同时移动有用的类别信息。一个具体诊断是固定类别分布重新采样后比较对抗收益;若收益明显变化,就有证据说明标签比例是重要因素,而不能继续把结果只归因于视觉域差异。

还可以设置故障注入验收:故意把反转系数设为零,特征提取器应只收到任务梯度,领域头仍然可以训练;故意去掉任务损失,观察是否出现特征坍塌或类别分离消失。故障实验用于理解机制,不进入正式方法排名,报告时应与正式训练明确分开。

可执行研究记录与评价纪律

把阅读成果变成可检查的实验记录。先建立一张样本清单,每行至少包括样本标识、原始视频或说话人标识、类别、场景、训练验证测试角色。先检查这些标识的交集,再开始训练。视频切成不同短片,并不意味着它们在语义、人物或拍摄来源上相互独立;随机划分得到的高分也不能自动证明跨场景泛化。

所有比较都应固定输入帧数、预训练权重、数据增强、优化步数和评价脚本。先用一个种子验证数据流、梯度和保存恢复,再用预先约定的多个种子做正式比较。记录每个种子的结果,报告均值和波动,而不是只保留最高一次。若为了显存缩小模型或批量,把它写入兼容性实验说明,不把改动后的结果称为原论文的严格复现。

检查分类效果时,同时保存逐样本预测和混淆矩阵。总体准确率上升可能只是多数类别变好;逐类召回率能揭示少数表情被牺牲的问题。跨场景实验还要报告每个场景的指标,防止样本量大的场景掩盖小场景退化。一个漂亮的特征可视化只能辅助观察,不能替代独立测试集、明确指标和误差分析。

模型选择必须与最终测试分开。用验证集选择学习率、训练轮数和新增模块的强度,先写清选择规则,再运行最终测试;不要根据测试集反复挑选超参数。若研究设定禁止访问旧数据,就不能为了选择防遗忘系数反复查看旧任务测试结果。可以预先固定系数,或另行声明验证数据的可访问范围,让比较遵循同一规则。

每次改动只回答一个问题,保存配置文件、代码提交、随机种子、数据清单哈希和检查点路径。最后交付一页实验说明,按“问题、对照、改动、结果、解释、失败案例”组织。若结果没有提高,先确认机制是否确实生效,再判断假设是否错误;未运行的实验只能写成计划,不能填上看似合理的数字。本文表格均为原文报告或明确注明的教学计算,并非本机复现实测。

原文短引与证据入口

原论文与完整上下文。以下三个短引仅定位作者用语,解释与判断见上文:“gradient reversal layer”;“domain-invariant features”;“unsupervised domain adaptation”。

自己的解释与验收记录

写出一条输入到输出的链路、一个关键公式的含义,以及你完成的最小检查。笔记仅保存在当前浏览器,可从主站「我的学习笔记」导出。