ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

自适应监督策略:稀疏奖励下强化学习的行为蒸馏与奖励塑形实践

2026/10/8 9:55:11 拓冰建站 浏览量
自适应监督策略:稀疏奖励下强化学习的行为蒸馏与奖励塑形实践 上篇梳理结尾时我把 On-Policy Distillation 这条线暂时定在了用固定权重的蒸馏约束帮助 student 在稀疏奖励环境下稳定起步上。当时自己很清楚这只是把问题往后推了一步固定权重意味着 teacher 的监督强度不会随着 student 的真实水平变化早期够用中期开始别扭后期基本反噬。所以 6 月到 9 月这三个月我把重心从 reward shaping 挪到了自适应监督方向上中间又不得不反复回到 shaping 的老问题里补课。这篇就按时间线把这三个月的进展、卡壳、和最终跑通的东西梳理一遍。内容偏向实际复现和调参过程适合在做 RL 稀疏奖励训练、行为蒸馏、或者在线模仿学习的同行参考。1. 为什么6月还在折腾reward shaping稀疏奖励下的老路与新问题1.1 项目背景与旧路线的瓶颈我这次推进的任务是一条六自由度机械臂的抓取-放置流水线状态空间是关节角、末端执行器位姿和物体坐标动作是连续的四维控制量。环境本身是典型的稀疏奖励设定只有物体落到目标区域才给 1其他所有时刻奖励都是 0。第一次跑 PPO 时agent 在几百步内几乎学不到任何梯度信号探索完全靠随机初始化策略去撞运气——这种情况谁跑谁知道基本等于让新手闭着眼找路。5 月份之前我依赖的是 reward shaping用贴合任务先验的势能函数把连续进度信号注入环境。起初效果立竿见影agent 很快学会了靠近物体并抓取的前半段技能但越往后越不对劲。6 月的工作就是在给这套 shaping 方案做手术试图修补它在任务中后期暴露出的缺陷。1.2 势能塑形的原理和它承诺的东西Reward shaping 的理论根基是 Ng 等人在 1999 年提出的 potential-based shaping核心公式是F(s, s) γΦ(s) - Φ(s)把 F 加到原始奖励上得到新奖励 R R F。这个形式最漂亮的性质是只要 Φ 只依赖状态不依赖动作那么新奖励下的最优策略和原始奖励下的最优策略完全一致。也就是说理论上我可以随便设计一个合理的 Φ 来引导 agent而不必担心引导过头导致最终策略偏掉。实际落地时我们会给 F 乘一个缩放系数 η变成 R R η(γΦ(s) - Φ(s))因为环境本身的奖励和塑形信号量纲不同直接相加会让某一边主导。我 6 月最初的版本就是拿当前末端执行器与目标点的负欧氏距离当 Φ让 agent 每走一步都获得接近目标的密集正反馈。这个版本把训练收敛步数从漫无边际压到了可接受范围但我很快遇到了更隐蔽的问题。1.3 6月实践中暴露的三个深坑第一个坑是塑形信号与真实任务的博弈。当远端抓取和最终放置属于两个子任务时单一距离势能会在中间段形成能量低谷。agent 学会了靠近物体却会在抓到物体之后停在原地磨蹭因为继续前进带来的塑形增益还不如当前接近目标的稳态红利。直观说距离势能把 agent 导向了局部极大值区域而这个区域并不是真实稀疏奖励希望的路径。第二个坑是 η 的尺度非常难调。我试过固定 η 和让 η 随训练步数退火都只适用于单一环境。换一个物体初始位置分布、换一个目标区域大小最优 η 就变了。这个调参过程消耗大量轮次而且每换一次任务配置都要重新来根本算不上一个通用方案。第三个坑最致命shaping 在某些状态下会主动毁掉探索。因为塑形奖励是稠密的agent 一旦发现某个方向会产生稳定正反馈就会固化在那一小片状态区域里。策略熵快速下降真实稀疏奖励还没碰到过agent 已经提前觉得我找到了最优。后来复盘时我看过采集的状态分布中后期所有 episode 的初始位置高度集中agent 根本没有尝试过把物体抓到其他角度再放置的可能性。所以 6 月下旬我做了一个决定不再单独依赖 handcrafted shaping而是引入一个外部监督信号来源让 agent 不只从稀疏奖励里自己摸索而是有一个老师在示范该往哪里走。这条路就是 On-Policy Distillation。2. 转向On-Policy Distillation监督信号的本质变化2.1 为什么蒸馏比shaping更适合做稀疏奖励的引导信号Reward shaping 本质上是在工程层面修改 MDP 的奖励函数它通过数值反馈告诉 agent 当前状态好不好。但数值反馈有一个天然短板它不包含动作信息。agent 知道哪个状态好依然不知道该往哪个动作方向调整。Distillation 完全不同它的监督信号是 teacher 在当前状态下给出的动作概率分布是直接的行为指引信息密度比一个标量奖励高很多。我最终选择走 On-Policy Distillation 而不先考虑常规行为克隆原因是样本分布匹配问题。行为克隆要求离线收集固定示范数据集但 teacher 和 student 的状态覆盖范围往往不同student 在训练中访问的状态很容易落到示范集稀疏的区域。On-policy 蒸馏的思路是student 一边与真实环境交互一边从 teacher 的在线输出中学习teacher 是在 student 当前造访过的状态下给出监督分布一致性天然好一些。2.2 第一版蒸馏方案的设计与实现细节7 月中旬我搭出了第一版完整方案核心结构如下teacher用密集奖励版本带 shaping 但训练充分收敛预训练的 PPO 策略冻结不再更新student与 teacher 同架构但随机初始化的在线 PPO 策略每步与环境交互训练损失student 自有的 PPO loss 加一项蒸馏损失。蒸馏项我采用了 KL 散度方向选择的是 KL(π_student || π_teacher)。这个方向有一个明确的好处它是 mode-seeking 的student 只需要拟合 teacher 分布中的主要模式而不必强行覆盖 teacher 分布的全部尾部。考虑到 student 网络容量有限拟合主要模式可以让训练更稳定不容易被 teacher 在低置信度状态下的随机动作带偏。一次训练的损失大概是这样的# student_policy: 当前策略 # teacher_policy: 冻结的策略 # old_policy: 更新前采样时的策略 def distillation_loss(states, actions, old_log_probs, advantages): # PPO 策略项 new_log_probs, entropy evaluate_actions(states, actions) ratio torch.exp(new_log_probs - old_log_probs) policy_loss -torch.min( ratio * advantages, torch.clamp(ratio, 1.0 - clip_eps, 1.0 clip_eps) * advantages ) # 蒸馏项 student_dist student_policy.get_dist(states) teacher_dist teacher_policy.get_dist(states) kld_loss torch.distributions.kl_divergence(student_dist, teacher_dist) # KL(student || teacher) total_loss policy_loss beta * kld_loss return total_loss第一版跑出来效果超出预期student 收敛速度比纯 shaping 时快了不少尤其是前期抓取动作teacher 的示范让 student 少走了大量弯路。但跑到中后期问题又出现了student 越来越像 teacher最终性能被 teacher 封死在一个上界附近别说超越连持平都勉强。更麻烦的是 student 自发探索几乎停滞因为蒸馏损失总是趋向于把 student 拉向 teacher 的确定性输出这和有熵正则的探索机制是冲突的。2.3 固定权重蒸馏的关键缺陷我后来把问题归结为两个层面。第一是时间层面的固定权重。训练早期 student 一张白纸强蒸馏是对的到中后期 student 已经具备一定能力蒸馏信号和真实稀疏奖励开始出现分歧如果权重还是那么大student 会优先服从 teacher 而不是从真实奖励里学习。直观来说一个已经认得回家的路的小孩你还要全程牵着他走他永远学不会独立判断。第二是状态空间层面的固定权重。不同状态下的 teacher 可信度差异可能非常大。有些状态 teacher 知道得很清楚有些状态 teacher 本身也很困惑动作分布的熵很高。一个全局 β 完全没有能力区分这两种情况。所以 8 月我把工作重点转向了自适应监督把蒸馏监督的强度从固定超参变成随 student 学习状态动态变化的量。提示固定权重蒸馏在稀疏奖励设定下不是不能跑而是很难跑出超越 teacher 的效果。如果目标只是复现 teacher 的水平固定权重加一个合适的退火就够但如果目标是让 student 最终超过 teacher必须让监督信号学会什么时候放手。3. 自适应监督设计从退火权重到state-level动态调度3.1 自适应监督想解决的核心矛盾自适应监督的本质是处理一个动态权衡student 早期需要 teacher 带后期需要 teacher 放teacher 在某些状态值得信某些状态不值得信。这个权衡如果用固定超参表达那就永远是一刀切无法匹配训练动态和状态差异。所以我把监督强度拆解为两个控制维度一个全局层面的β控制整体蒸馏强度一个状态层面的α控制每个样本点的蒸馏权重。全局β解决的是训练阶段问题student 能力越接近 teacherβ应该越小最终趋近于 0把全部学习交给真实环境奖励。状态层α解决的是空间差异问题student 在该状态下与 teacher 的分布越不一致说明 student 越需要 teacher 帮助α越大已经和 teacher 没有分歧的状态α应该压下来让 student 自行决定是否探索更好的行为。3.2 两层调度机制的最终形态我最终的方案可以写成这样全局β_tβ_t 由 eval 阶段 student 的平均回报与目标回报的差距决定差距大β_t 大回报接近或超过目标β_t 指数下降用 sigmoid 或者简单的 clip 映射都可以重点是让 β_t 随真实能力信号变化而不是随训练步数线性退火。beta beta_max * sigmoid(-k * (eval_return - return_target))状态层α(s)输入是当前状态下 teacher 分布与 student 分布的 KL 散度当 KL 大说明 student 偏离 teacher 明显需要更强烈的监督当 KL 小说明 student 已经跟上 teacher监督权重下调为了稳定性α还要做一个平滑处理不能直接用瞬时值。kl kl_divergence(teacher_dist(states), student_dist(states)) alpha clamp(sigmoid(k_alpha * (kl - kl_target)), alpha_min, alpha_max) alpha ema_smooth(alpha, alpha_ema) # 关键避免噪声最终蒸馏损失distill_loss mean(beta_t * alpha(s) * kl)注意这里 KL 方向我改回了 KL(teacher || student)。因为在自适应权重下我们期望用 KL 的大小来标定student 与 teacher 的距离用对称或者 forward 方向更合理mode-seeking 的 reverse KL 会让 KL 在 student 远离 teacher 时被低估因为只覆盖主要模式导致 α 无法及时拉高。3.3 关键实现细节梯度断开与平滑自适应监督写起来不难但两个细节直接决定实验能不能跑通。第一个是 α 必须detach()。如果你让 α 是 student 分布的函数并且直接乘进蒸馏损失里回传student 会学会一条捷径通过降低自己的低置信度来压低 KL 进而压低 α蒸馏梯度因此被削弱。这不是我们想要的。我们想要 α 扮演监督调度器的角色而不是 student 可操纵的逃逸开关。所以我在实现里把 α 强制从计算图中断开with torch.no_grad(): student_dist_for_kl student_policy.get_dist(states) teacher_dist_for_kl teacher_policy.get_dist(states) kl kl_divergence(teacher_dist_for_kl, student_dist_for_kl) alpha torch.clamp(torch.sigmoid(k * (kl - kl_target)), alpha_min, alpha_max) # 使用 detach 的 alpha 参与蒸馏损失 distill_loss (alpha.detach() * beta * kl).mean()第二个是 α 的平滑。最初我直接拿每个 batch 内逐样本的 KL 算 α结果训练曲线抖动得很厉害。原因是 teacher 在某些状态的分布熵本身就很高KL 会突然飙升导致 α 脉冲式波动。我给 α 加了一个简单的 EMA指数滑动平均之后训练瞬间稳定下来。这个 EMA 的系数不能太大也不能太小我试下来 0.98~0.995 之间的效果比较合理。如果你在复现时发现蒸馏权重震荡优先检查这里的平滑。3.4 为什么这套设计能同时解决 shaping 和固定蒸馏的问题Reward shaping 的问题在于它给的是状态价值的局部梯度agent 只能从中推断方向却不能获得动作级反馈。自适应蒸馏的监督信号来自 teacher 的动作分布动作信息密度远高于 scalar shaping同时它的强度又是动态的student 越弱teacher 越强势介入student 越强teacher 越退到幕后。这正好补上了固定权重蒸馏把 teacher 的盲区和学生潜力一起封死的短板。全局 β 和状态层 α 的作用范围是互补的。β 负责宏观学程管理决定某个训练阶段整体上 teacher 该多大声音说话α 负责细粒度信用分配在同一个 batch 内部区分哪些状态 teacher 该多说、哪些状态该少说。两者相乘同一个监督信号就同时具备了时间自适应和空间自适应。4. 实验复盘哪些效果是真实的哪些是假象4.1 实验设置与对比基线8 月底到 9 月初我做了一组横向对比实验在三个环境配置下分别跑四种方法RS-only纯 reward shapingη 做步长退火Distill-fixedOn-Policy Distillationβ 固定为 0.5Distill-anneal全局 β 按步数线性退火无状态层 αAdaptive本文的自适应监督方案全局 β 状态层 α。所有配置共用同一套 PPO 超参数student 网络结构一致seed 覆盖 5 个。评估指标取训练收敛后的平均 episode return、成功率、以及收敛所需的环境步数。实验数据基于我当时跑的配置不同环境有波动但趋势是稳定的。4.2 关键对比结果环境1抓取-放置中距离任务物体初始位置中等偏移方法平均回报成功率收敛步数RS-only0.2114%未完全收敛Distill-fixed0.6271%1.2MDistill-anneal0.6874%1.1MAdaptive0.7989%0.9M环境2近距离堆叠任务teacher 本身表现较好的场景方法平均回报成功率收敛步数RS-only0.189%未完全收敛Distill-fixed0.5866%0.8MDistill-anneal0.6470%0.8MAdaptive0.8593%0.6M环境3长距离规避任务teacher 也有明显失败率方法平均回报成功率收敛步数RS-only0.093%未完全收敛Distill-fixed0.2318%0.7MDistill-anneal0.2722%0.7MAdaptive0.4139%0.7M三个环境趋势一致自适应监督在回报、成功率和收敛速度上都显著优于固定权重和单纯退火。环境3尤其说明问题teacher 自己也弱固定蒸馏把 student 锁死在了一个低水平上自适应监督在 teacher 明显困惑的状态下降低了监督权重给了 student 自己绕开失败区域的余地。4.3 给我印象最深的两个失败案例第一个失败的尝试是直接用 KL 阈值做硬切换。我不想让 α 连续变化而是设了一个阈值KL 大于某个值就开启蒸馏小于就关闭。结果 student 在边缘状态反复失去老师上一轮还有监督下一轮突然没有策略在两种模式之间疯狂切换训练彻底崩了。这个案例让我意识到监督强度的变化必须是软的、平滑的硬门控会造成优化目标不连续PPO 的梯度估计直接恶化。第二个失败是忽略 teacher 熵导致的 α 失真。我在某个版本里发现 α 在所有状态下都偏高student 根本没有独立空间。检查后发现问题出在 teacher 在远离任务状态的区域分布熵很大KL 始终很大α 一直压在最大值。后来我加了 teacher 本身的置信度调制如果 teacher 在当前状态的熵超过某个上限我们就认为 teacher 在这个状态并没有真正的掌握知识监督权重也应当压低。这个修正让 α 的分布从处处都大变成了在该大的地方大效果提升明显。4.4 关于评估的一点提醒我也踩过一个假象陷阱。自适应监督方案在训练中段的回报曲线看起来不如固定蒸馏因为前者的 β 在早期很大student 更多时间在模仿看起来学得慢而后者的 β 固定student 很快在 teacher 的强约束下表现得像 teacher让人误以为它学得更快。但随着训练推进固定方案的回报曲线很快撞上 teacher 上界自适应方案则持续上升实现反超。如果你只看前 300k 步的曲线很可能得出相反结论。评估这种方案时一定要跑完全程中期曲线短期的落后恰恰是后期超越的必要代价。5. 下一步打算与这三个月最想说的经验5.1 下一步想做的两个扩展第一个方向是把 teacher 本身变成混合模型。单 teacher 在部分状态不可靠的问题与其靠 α 做被动压制不如直接换成多个 teacher 的集成输出用 teacher 间的分歧度作为不确定性的估计。如果集成 teacher 在各状态的动作分布高度一致说明这个 state 的监督信号是可靠的如果分歧大说明这个 state 连专家都不确定α 应该自动降低。这相当于把对 teacher 信任度的估计从手工设计变成了数据驱动。第二个方向是把 reward shaping 的势能函数也纳入自适应框架。现在 shaping 和蒸馏是两套独立的信号前者给数值反馈后者给分布监督。但我越来越觉得它们可以统一shaping 的势能 Φ 可以用 teacher 的 value function 替代这样 agent 获得的塑形信号也是状态价值势能差的形式而蒸馏则作为动作层面的辅助监督两者强度由同一套自适应机制协同调度。5.2 这三个月我个人最想分享的几句经验做 Reward shaping 时别太信任势能函数保证最优策略不变这句话。它保证的是理论上的最优策略不是实际训练中的收敛策略。有限样本、有限表达能力的 agent 会被塑形信号带进各种局部模式这些模式离理论最优非常远。做 Distillation 时把学生何时该独立当成一个一等公民的建模问题而不是调参问题。固定权重和简单退火都是在训练之前就定死了监督节奏完全没有考虑 agent 在训练中的真实状态。自适应监督的效果之所以好本质上不是因为某个公式而是因为它让监督信号具备了反馈闭环agent 的状态决定监督强度监督强度反过来又影响 agent 的状态。最后如果只能给一条具体的操作建议我会说先用 KL(student || teacher) 还是 KL(teacher || student) 这种细节不要纠结太久但 α 的平滑和 detach 必须在第一版就做对。平滑决定稳定性detach 决定学习方向是否正确这两处错了后面所有精调都是在错误的地基上反复折腾。