4、域适应(Domain Adaptation):特征对齐、对抗性训练、与ACT策略的结合点
好,咱们接着聊。前面几章我们讲了ACT策略的基本原理,也聊了迁移学习。但有个现实问题一直绕不开——仿真环境和真实环境之间的鸿沟。
说白了,你在仿真里训练得再好,模型一上真机,表现往往就崩了。为什么?因为两个域的分布不一样。仿真里的光照、纹理、物理参数,跟真实世界总有差距。这就是典型的域偏移(Domain Shift)问题。
我个人习惯把域适应分成三个层次:数据层、特征层、模型层。今天重点讲特征层和模型层,因为这两块跟ACT策略的结合最紧密。
4.1 特征对齐:让两个域“看起来一样”
先问个问题:为什么ACT策略在仿真里学得好好的,到真机上就不行了?
我举个例子。你在仿真里训练机械臂抓杯子,仿真里的杯子纹理清晰、光照均匀。但真实场景下,杯子可能有反光、有污渍,甚至背景都不一样。ACT策略提取的特征,在仿真域和真实域之间,分布是完全错开的。
特征对齐的核心思想,就是通过某种映射,让源域(仿真)和目标域(真实)的特征分布尽可能接近。
具体怎么做?我常用的方法有两种:
- 最大均值差异(MMD):计算两个域特征分布的差异,把它作为损失函数的一部分。训练时让这个差异最小化。
- 相关对齐(CORAL):对齐两个域特征的协方差矩阵。简单说,就是让特征的二阶统计量一致。
我在项目中遇到过这样一个场景:用ACT策略做零件抓取,仿真里训练了100万步,效果很好。但一换到真实产线,抓取成功率直接掉到30%。后来加了特征对齐模块,把仿真和真实图像的中间层特征做了MMD约束,成功率回升到85%。
关键点:特征对齐不是简单地把两个域的特征拉到一起。你要注意对齐的层级。ACT策略中,动作编码器的中间层特征更适合做对齐,因为底层特征太细节(纹理、光照),高层特征太抽象(任务语义)。中间层刚好平衡了域不变性和任务相关性。
4.2 对抗性训练:让域判别器“分不清”
特征对齐是显式地拉近分布。对抗性训练则是另一种思路——让模型自己学会“欺骗”域判别器。
这个想法最早来自GAN,后来被用到域适应里。结构很简单:
- 一个特征提取器(就是ACT策略里的编码器)
- 一个域判别器(判断特征是来自仿真还是真实)
- 一个任务学习器(ACT策略本身)
训练时,特征提取器要同时做两件事:让任务学习器能准确预测动作,让域判别器分不清特征来自哪个域。说白了,就是对抗博弈。
代码实现上,梯度反转层(Gradient Reversal Layer, GRL)是个经典技巧。前向传播正常,反向传播时把梯度取反。这样特征提取器就会朝着“欺骗”域判别器的方向更新。
# 伪代码示例:GRL层
class GradientReversal(tf.keras.layers.Layer):
def __init__(self, lambda_=1.0):
super().__init__()
self.lambda_ = lambda_
def call(self, x):
return x
def get_gradients(self, loss, params):
# 反向传播时梯度取反
return [-self.lambda_ * g for g in super().get_gradients(loss, params)]
# 在ACT策略中插入GRL
features = encoder(observation) # ACT编码器提取特征
task_output = actor(features) # 动作预测
domain_output = domain_classifier(GradientReversal()(features)) # 域判别
我的经验:对抗性训练有个坑——训练不稳定。我曾经调了一个星期的超参数,λ值从0.1试到10.0,才找到合适的平衡点。建议你从λ=0.5开始,观察域判别器的准确率,如果一直低于50%说明对抗太强,高于80%说明对抗太弱。
4.3 与ACT策略的结合点
好,前面讲了两种域适应方法。现在关键问题来了:怎么把它们嵌入到ACT策略里?
ACT策略的核心是条件变分自编码器(CVAE),它包含编码器、解码器、动作预测器。域适应可以加在三个位置:
| 插入位置 | 方法 | 效果 |
|---|---|---|
| 编码器输出 | 特征对齐(MMD/CORAL) | 让隐空间特征域不变 |
| 解码器输入 | 对抗性训练 | 让生成的动作序列更鲁棒 |
| 动作预测器 | 联合训练 | 端到端域适应 |
我个人最推荐的是编码器输出端做特征对齐。为什么?因为ACT的编码器把观测(图像、关节角)压缩成隐变量,这个隐变量是策略决策的基础。如果隐变量本身是域不变的,后续的解码和动作预测自然就鲁棒了。
具体做法:
- ACT编码器提取仿真数据和真实数据的隐变量
- 计算两个隐变量分布的MMD损失
- 把这个损失加到ACT的总损失里(权重0.1~0.3)
- 联合训练
嗯,这里要注意:不要一次性加太多域适应损失。我刚开始做的时候,把MMD、对抗、CORAL全加上了,结果模型直接不收敛。后来只保留MMD,效果反而更好。
避坑指南:我曾经在ACT策略里同时做特征对齐和对抗训练,结果两个损失互相干扰。后来发现,特征对齐更适合离线阶段(用预采集的真实数据),对抗训练更适合在线阶段(边交互边适应)。分开用,别混在一起。
4.4 整体框架图
下面这张图展示了域适应与ACT策略的完整结合方式。你可以看到,特征对齐和对抗性训练分别作用在策略的不同环节,共同提升策略的泛化能力。
你看,整个流程很清晰:仿真和真实数据分别经过编码器,在特征对齐模块的约束下,被映射到域不变的隐空间。然后对抗性训练进一步确保这个隐空间对域信息不敏感。最后,ACT策略基于这个鲁棒的隐表示输出动作。
说实话,域适应这块内容,理论看着简单,实际调起来挺磨人的。但一旦调好了,效果提升非常明显。我建议你从特征对齐入手,先跑通一个简单的MMD版本,再逐步加入对抗性训练。别一上来就想搞个大而全的方案——稳扎稳打,才是工程之道。
公众号:蓝海资料掘金营,微信deep3321