QAM与DIVL:机器人强化学习的评价-执行闭环设计
发布时间:2026/10/15 10:47:41 锦皓数字建站

QAM 和 DIVL 这两个缩写放在一起很多做机器人学习的同行第一眼会有点懵。我最早看到这个标题的时候也愣了一下因为这两个词在公开文献里并没有统一的定义更像是某个项目组内部对自研模块的命名。我按常见的命名习惯做了个解读QAMQuality Assessment Module负责质量评估DIVLDiversity-driven Intrinsic Value Learning负责内在价值驱动的多样化探索两者配合起来就是一个完整的“评价-执行闭环”。这套设计思路在机器人强化学习里非常实用尤其是处理稀疏奖励、多模态行为学习、仿真到实物迁移这类问题时比单纯堆算法有效得多。这篇文章我会用做机器人强化学习项目时的真实视角把这套闭环的设计逻辑、模块分工、核心计算公式、训练流程、踩坑记录全部拆开讲清楚。内容偏实操适合已经在跑强化学习、或者正准备在机器人上落地RL的工程师和研究人员参考。学生党想入门的也能看我会把基础概念穿插着解释不用你提前会很多。1. 拆开看QAM 与 DIVL 到底解决什么问题1.1 一个容易被忽视的闭环痛点强化学习的经典框架是Actor-CriticActor负责执行策略Critic负责评价动作的好坏。这个框架天然就是一个“评价-执行闭环”智能体做出动作环境给出反馈Critic评估状态和动作的价值Actor根据评估结果调整策略。听起来很顺但真放到机器人身上问题立刻暴露环境反馈太稀疏了。举个我实际遇过的例子。让一个六轴机械臂学习抓取桌面上的木块你设的奖励函数大概是“被抓取成功时给1其他时候都是0”。机械臂每次动作是一个高维连续向量初始阶段它完全是瞎试几百次交互里一次成功都碰不到Critic学到的价值估计基本全是0Actor得不到任何有效的梯度方向训练就像原地打转。这就是典型的稀疏奖励问题。更麻烦的是就算偶尔成功了一次Critic也不一定学得好。因为评价信号太单一它很难判断“刚才的动作序列里哪一步是关键贡献哪一步只是顺便做对了”。评价不准确执行端的策略更新就会抖动严重的甚至会把已经学到的能力回退掉。QAM和DIVL这对组合就是针对这两个痛点设计的。核心思路一句话概括执行端负责探索和试错评价端负责给出更细腻、更多层次的反馈两边不断互相修正形成一个稳定收敛的闭环。1.2 QAM 和 DIVL 在闭环中的角色划分这里得先说清楚QAM和DIVL不是某个现成算法的标准组件是对一类功能的抽象命名。理解它们的角色比记住名字重要得多。QAM质量评估模块它的职责是解决“评价不够准”的问题。传统Critic只输出一个标量价值QAM则把评价拆成多个维度。比如在机械臂抓取任务里它不只评估“最终是否抓到了”还会评估“末端执行器是否接近目标区域”、“夹爪开合状态是否合理”、“运动路径是否平滑”。每个维度给一个分数再合成综合评估。这样就算任务没有最终成功Actor也能从“部分正确的行为”里学到有用的东西。DIVL多样性驱动的内在价值学习它的职责是解决“探索不够广”的问题。如果只看外部奖励Actor很快就会收敛到它最早发现的策略上哪怕这个策略很差。DIVL会给智能体一个额外的内在奖励专门鼓励它去尝试没做过的状态和行为。有点像一个员工考核指标不只看业绩产出还看你有没有尝试新方法——哪怕新方法暂时没提高产出只要拓展了可能性也算加分。DIVL的“多样化”和QAM的“多维度评价”不是各干各的。DIVL探索出来的新行为模式需要QAM来评估这些新模式的质量QAM评估出哪些维度有欠缺再由DIVL引导探索去补足。整个系统才有真正的闭环感。2. 评价-执行闭环的核心机制设计2.1 为什么评价不能只靠一个奖励信号我在实操里反复确认过一件事稀疏的、单维的奖励信号是机器人强化学习最隐蔽的杀手。它不一定是训练失败的显性原因但绝对是训练效率低下的隐性主因。怎么理解这件事假设环境反馈只有“成功/失败”两个结果那Critic学出来的价值函数就像一盏只有开关两种状态的灯——产生了很大的价值区域但分辨不出区域内部的梯度差异。没有梯度信息策略优化算法PPO、SAC等对大多数状态的更新方向几乎是随机的。一个行之有效的替代方案是设计分层的评价指标。QAM的核心理念就是把任务目标拆成一组子指标每个子指标独立评估再按优先级或权重组合。拿机械臂抓取做例子QAM的评价向量可以这么设计末端位置接近度目标点与当前末端执行器位置之间的距离衰减函数。夹爪预抓取姿态匹配度夹爪开合方向和目标物体姿态的夹角余弦值。运动平滑度动作序列中加速度突变的惩罚项。任务完成度抓取成功/失败标志。每个子指标都输出一个区间在0到1之间的分数这样Critic总能得到一个稠密的价值信号。即便最终抓取失败第1、2项也可能给出较高分数Actor就能知道“我离成功更接近了”从而往正确的方向调整。有人会担心这么设计会不会太依赖人工经验确实会所以QAM通常会配合一个自适应权重调整机制。简单说就是根据训练过程中各子指标的变化率动态调整权重——某个指标长期不变化降低它的权重某个指标波动剧烈提高它的权重。这样就能减少人工调参负担同时保证评价的准确性。2.2 DIVL 的内在激励到底怎么算DIVL要做的事情是从算法层面鼓励智能体探索多样化的行为和状态。这里我要明确一点它和传统RL里的“熵正则”比如PPO里的entropy bonus不一样。熵正则只是让策略分布不要过早尖锐化它不关心探索出来的状态是否有价值。DIVL的内在奖励是基于状态空间的新奇度来计算的它关注的是“我是不是到了一个之前很少去过的状态”。一种常见且很简单有效的实现方式是用一个额外的预测器Predictor去预测当前状态的某些特征预测误差越大说明这个状态越“新奇”就给越高的内在奖励。这就是ICMIntrinsic Curiosity Module类方法的核心思想DIVL可以看作这类思路的一种变体扩展。具体计算公式可以写成这样r_intrinsic(s, a, s) || φ(s) - Pred(φ(s), a) ||²其中φ是状态编码器Pred是一个小型的预测网络。智能体去了一个预测器难以预测的地方内在奖励就大。这个机制鼓励它走出舒适区去探索环境的其他区域。但这里有个坑纯好奇驱动的探索容易让智能体只关注那些随机的、不可预测的噪音区域而忽略任务真正相关的区域。所以我和团队在DIVL里做了一个改进——加了一个任务相关性的门控。具体说只有当QAM评估出的“任务相关维度”分数低于某个阈值时才会增强内在奖励的权重如果任务评价已经比较高了就降低内在奖励的权重让智能体专注利用已有经验。这个设计有一个很实际的好处训练初期QAM认为任务相关分数低DIVL全力探索训练中期DIVL发现了一些有潜力的新行为QAM认为这些行为有价值分数逐渐提高训练后期QAM分数接近上限DIVL内在奖励自动抑制系统进入精细利用阶段。整个训练过程动态调节不需要手动切换。2.3 QAM 的评价结果如何回流到执行端评价端产出的多维度信号怎么变成执行端的优化信号这是闭环能否成立的关键。我见过一些团队的做法是把QAM的所有子指标加起来当做一个扩展的奖励向量送进传统RL算法的奖励函数。这样做有一个问题——各维度指标量纲不一致直接相加容易让某个指标主导整个优化方向其他指标形同虚设。我更推荐的做法是两层结构第一层在策略梯度层面把QAM输出的多维度评价作为辅助分布约束Actor的输出。具体来说Actor在输出动作时不仅根据Critic的价值信号还要参考QAM给出的“行为偏向建议”两者加权得到最终的策略分布。例如抓取任务中QAM评估出“末端位置接近度偏低”Actor的动作分布就会偏向那些能快速缩短距离的行为。第二层在内在奖励层面把DIVL的奖励作为总奖励的一部分。总奖励的公式类似r_total r_external α * r_intrinsic其中α是一个自适应系数由QAM的评估结果动态调节。QAM评价高α变小QAM评价低α变大。这个调节机制的作用相当于在训练的不同阶段自动切换“探索模式”和“利用模式”。这样QAM和DIVL的输出都同时作用在执行端并且互相影响对方的权重形成一个真正的闭环。我自己在项目里用这套结构替换掉原来的单一奖励方案之后训练收敛速度提升了一个数量级而且学到的策略也更加鲁棒。3. 实操落地从算法设计到工程实现3.1 整体架构和数据流纸上谈兵聊完了说点能直接上手的。我在实际项目里用的是SACSoft Actor-Critic作为基础算法在其上叠加QAM和DIVL模块。整体架构分成几条数据流机器人实时采集状态数据经过状态编码器φ映射为特征向量交给QAM和DIVL两个模块处理。QAM模块输出多维度评价信号存进经验池同时作为Critic的额外输入。DIVL模块用特征向量计算内在奖励把额外的奖励值加到环境奖励上存进经验池。Critic根据拼接后的状态特征原始状态QAM评价向量学习价值函数。Actor根据Critic的价值更新和QAM的辅助约束输出动作。经验池里的每一条transition记录是这个样子的(s_t, a_t, r_total_t, s_{t1}, qam_eval_t, qam_eval_{t1})把QAM评价向量也存进来非常关键因为后续训练Critic和价值函数时需要拿连续步的评价变化做时间差分学习。3.2 关键代码结构与核心逻辑下面是一段简化但能反映核心逻辑的Python伪代码结构class QAM(nn.Module): def __init__(self, state_dim, eval_dims): super().__init__() self.encoder MLP(state_dim, 128, 64) self.heads nn.ModuleList([MLP(64, 64, 1) for _ in range(eval_dims)]) self.dim_weights nn.Parameter(torch.ones(eval_dims)) def forward(self, state): feat self.encoder(state) evals torch.cat([head(feat) for head in self.heads], dim-1) evals torch.sigmoid(evals) return evals, torch.softmax(self.dim_weights, dim-1) class DIVL(nn.Module): def __init__(self, state_dim, action_dim, feat_dim32): super().__init__() self.state_encoder MLP(state_dim, 64, feat_dim) self.next_pred MLP(feat_dim action_dim, 64, feat_dim) def intrinsic_reward(self, s, a, s_next): phi_s self.state_encoder(s) phi_s_next self.state_encoder(s_next) phi_pred self.next_pred(torch.cat([phi_s, a], dim-1)) reward (phi_pred - phi_s_next).pow(2).mean(dim-1, keepdimTrue) return reward class QAMDIVLAgent: def __init__(self, state_dim, action_dim, eval_dims): self.qam QAM(state_dim, eval_dims) self.divl DIVL(state_dim, action_dim) self.actor GaussianPolicy(state_dim eval_dims, action_dim) self.critic1 QNetwork(state_dim eval_dims, action_dim) self.critic2 QNetwork(state_dim eval_dims, action_dim) self.alpha 1.0 def compute_total_reward(self, s, a, s_next): intrinsic self.divl.intrinsic_reward(s, a, s_next) qam_eval_next, qam_logits self.qam(s_next) task_score (qam_eval_next * qam_logits).sum(dim-1, keepdimTrue) gating torch.where(task_score 0.5, 1.0, 0.3) total_r s.get(external_reward) self.alpha * gating * intrinsic return total_r, qam_eval_next代码宿主有两个关键点gate逻辑根据QAM评估动态调整内在奖励防止过度探索。state输入给Actor和Critic时都拼接了QAM的评价向量让策略和价值函数都能“感知”到评价模块的实时反馈。3.3 超参数与计算过程训练超参数直接给一组我实测下来比较稳的配置环境是MuJoCo的FetchPickAndPlace类任务超参数值说明学习率3e-4三个网络共用更新步级联折扣因子γ0.99稀疏奖励场景下不能太低软更新系数τ0.005Critic目标网络更新速率经验池容量500k机器人任务需要较大缓冲批量大小256增大批提升评估稳定性探索温度系数α初始1.0由自适应调节器控制QAM评价维度数4根据任务拆分的子指标数内在奖励比例上限0.5防止内在奖励压制外部奖励训练流程序号是这样走的初始化QAM、DIVL、Actor、两个Critic网络以及对应目标网络。在环境中收集一条轨迹每一步同时记录外部奖励、QAM评价向量和DIVL内在奖励。计算总奖励将转换存入经验池。从经验池采样一个批次更新Critic回归目标更新。计算QAM的自适应权重更新QAM网络和DIVL预测器预测器只更新不影响策略梯度。用策略梯度加QAM辅助约束更新Actor更新目标网络软拷贝。周期性测试当前策略在环境中的实际表现保存评估指标。整个流程里最容易被忽略的细节在多条细节上最后更新Actor时别忘了同时更新QAM模块和DIVL模块的参数否则整套协作训练就是不完整的。QAM的辅助约束应该使用stop-gradient方式防止评价网络什么都学不到。3.4 训练曲线里怎么判断好坏训练过程中要盯几个关键指标不是只看总奖励曲线QAM各子指标的曲线变化如果核心子指标长期不涨说明DIVL探索方向跑偏了需要调整内在奖励的权重。DIVL内在奖励的数值变化内在奖励均值快速下降说明智能体已经把环境探索得差不多了进入利用阶段是正常的但如果下降过快且任务分数还很低说明探索过早收敛需要调大初始α或降低门控阈值。成功率曲线和平均步数曲线成功率上升的同时平均完成任务步数下降是健康的收敛过程。我从项目里观察到把QAM评价向量显示出来能非常直观地定位瓶颈到底是末端定位不准还是夹爪姿态不对还是路径生硬。这比单纯盯一个总回报省力得多。4. 常见问题与排查实录4.1 最常踩的五个坑我把实操里见过的问题整理成速查表方便大家对照排查现象原因解决方案训练几天成功率仍然为零外部奖励过于稀疏检查外部奖励信号是否触发成功加入QAM稠密化评估指标Actor输出动作剧烈抖动QAM评价权重失衡减小高方差子指标的权重增加温控惩罚项DIVL探索过度移动到无关区域门控阈值设置不当提高task_score门控阈值提前抑制内在奖励QAM各维度评价长期接近1评价网络过拟合到当前策略采样时混合高随机探索的数据重置评价网络部分层训练后期策略退化内在奖励权重未衰减确保α自适应逻辑随task_score增大而减小这些问题的共性规律是不是单一模块的错而是协同关系出了错。排查时一定要同时看QAM的输出和DIVL的奖励值变化才能定位到真正的原因。4.2 一次真实的排查过程一次在UR5e真机上做测试时遇到过一个很典型的场景。仿真里训练得很好的策略迁移到真机后一开始动作是正常的但十个来回之后策略开始变得很保守末端执行器一直在一个小范围里来回试探不敢靠近目标。我用训练日志排查时发现一个细节DIVL的内在奖励在真机上比仿真高很多因为真机的传感器噪音导致状态预测误差偏大模型觉得每个状态都“很新奇”所以内在奖励居高不下。智能体为了获取内在奖励就停留在那些噪音最大的状态空间里反复试探疯狂“刷探索分数”任务反而被搁置。解决办法也很直接在DIVL的预测误差计算前先对状态特征做Kalman滤波或EMA平滑把传感器噪音的影响压下去并加大门控阈值的抑制力度。这套组合方案实施后策略很快恢复正常的执行状态。这个案例里最重要的是想明白一个道理一切额外奖励模块引入的偏置都可能成为策略优化的干扰源。在仿真里DIVL的探索奖励是助力换到真机环境却变成了噪音放大器。所以模块设计时必须考虑部署场景的差异。4.3 调参的具体经验分享调参方面我最想强调的是一组实用心得对QAM的小标题进行归一化处理不要单纯堆原始数值。我给每个子指标都做了reward shaping标准化的处理数值范围贴在0到1之间。DIVL内在奖励的尺度要控制在外部奖励的0.1到0.5区间内超过这个范围训练就会出幺蛾子。QAM的自适应权重调节放在训练中期之后开启效果较好前期固定等权重让各子指标先分别学到稳定的评价语义再动态调节能避免部分子指标初始就被压制。经验池里需要保留至少5%比例的“高探索随机动作”数据这能显著增强QAM对边界状态的理解效果立竿见影。这些经验是我真金白银砸出来的教训写出来就不希望大家再交同样的学费了。5. 消融实验与扩展方向5.1 消融实验怎么看效果为了验证这套QAMDIVL机制到底有没有用我在项目里做过一组消融实验对比四种配置基础SAC无QAM、无DIVL稀疏奖励SACDIVL只有内在探索奖励评价仍是单标量SACQAM只有多维度评价无内在探索奖励SACQAMDIVL完整闭环实验结果很有代表性配置4的收敛速度远快于其他三组而且最终成功率最高。配置2虽然探索范围广但因为没有精细评估信号经常在无关区域浪费样本配置3虽然评价细腻但展开不够新制作的空间容易陷入局部最优。这个消融实验也验证了一个重要结论评价和执行两个模块不是简单的叠加它们的配合才是真正的价值所在。没有DIVL的探索供给QAM的评估数据不够丰富学到的评价模型容易偏差没有QAM的精细引导DIVL的探索又理不清方向。这就是我认为这个闭环结构的存在意义。5.2 后续可以往哪些方向做扩展这套结构还有很多值得延展的方向我自己目前正在尝试的有把QAM的评价维度扩展到安全约束和能耗约束让机器人不只要完成任务还要以更安全、更低能耗的方式完成任务。之前我试过在评价向量里加一个碰撞概率估计项策略会明显更偏好远离障碍物的行为。把DIVL的多样化度量从状态空间扩展到时序空间让智能体不只探索不同的状态还能探索不同的行为序列模式这对多步骤操作类任务很重要。结合world model做一个模型预测式的评价循环。更具体地说就是在每次动作前用一个环境模型预测QAM评价的变化趋势做短期的规划再执行。这等于把一个慢速的强化学习闭环升级成带前瞻的快速闭环样本效率是有实质性提升的。扩展方向很多但核心原则不应该变评价维度要与真实任务目标对齐探索机制要能在需要时涌现、在不需要时收敛。关于这套QAM与DIVL配合的闭环结构我最后还想再分享一个细节技巧。在实际训练中我习惯周期性打印QAM每个维度的数值分布直方图观察它是否出现过早饱和。一旦发现某个维度长时间在0.9以上的高位徘徊我就知道这个子指标对策略优化已经失去了引导作用需要主动降低它的权重或者换一种更细腻的评估函数。这个习惯帮我提前看过很多次训练崩溃的问题。希望这套思路也能帮你们少踩几个坑快点看到自己的机器人在真实环境里跑起来。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。