实战指南:从稀疏奖励困境到高效强化学习)
做强化学习的人十有八九都经历过这种绝望环境搭好了算法写好了训练脚本启动了结果跑了几十万步reward 曲线像一条死人的心电图动都不动。我之前调一个机械臂抓取任务用 PPO 硬跑了三个通宵每次 episode 的奖励都稳定在 -0.1 左右策略基本就是在原地抖。后来把 Hindsight Experience Replay后见经验回放简称 HER加进去一个晚上成功率就上了八成。这个 hindsight事后诸葛亮的思想是 OpenAI 那篇 NeurIPS 2017 论文的核心后来被无数个机器人、导航、游戏项目拿过来当急救包。这篇文章我会把 HER 是什么、为什么它能成为稀疏奖励场景下的标配、以及实际落地时那些论文里不写的细节一次性讲透。不管你是刚入门的 RL 新手还是已经跑过几个环境的在职工程师只要你的任务里有多目标这层结构这篇内容都值得认真看一遍。1. 先搞清楚 HER 到底解决的是什么问题1.1 稀疏奖励多少项目死在永远学不会这一步先别急着看代码得先把问题的本质掰扯清楚。强化学习本质上靠奖励信号驱动奖励就像老师批改作业学生策略根据对错调整自己的行为。但如果奖励是稀疏的——比如机器人任务里只有末端执行器精确到达目标位置才给 reward其他情况全是 0——那整个训练过程就相当于让一个学生做一份全是填空题、而且只有全对才给分的试卷。他试了无数次每次都只能看到零分根本不知道哪一步接近了正确答案最后只能瞎蒙。这种情况下策略学到的东西几乎为零。更麻烦的是探索本身也会陷入死循环刚开始策略是随机的它大概率到不了目标于是拿不到任何正反馈梯度信号接近于零网络参数几乎不更新。你使劲加熵权重、加探索噪声结果只是让策略在状态空间里横冲直撞偶尔蒙到一次成功但概率太低根本不足以形成稳定的学习信号。我见过很多项目就在这一步把时间全耗光了然后归咎于算法不行。这里就体现出目标条件化的价值了。如果我们把策略写成 π(a|s, g)也就是把当前想要达到的目标 g 一起喂给网络那么同一个状态 s 下因为目标不同策略可以执行完全不同的动作。这个小小的改动让从经验中学习这件事有了新的可能性——因为你可以人为地换目标从而把一次失败的轨迹变成一条成功的轨迹。所谓失败往往只是相对于你预设的那个目标而言的。换个角度看这条轨迹里的每一步其实都在向某个实际到达过的状态靠近——如果以那个状态作为目标这些经验不仅不失败反而是完美的教科书。HER 的核心也就在这重新标注目标的视角把死局盘活。1.2 HER 的思路把失败轨迹改造成伪成功样本HER 的做法一点也不玄乎。假设你在训练一个机器人推物体的小任务目标是物体从位置 A 推到位置 B。一条 episode 里机器人把物体从 A 推到了 C但 C 不是 B所以这条轨迹里所有 transition 的奖励都是 0没有任何学习信号。传统 RL 算法到此就放弃了这条数据。HER 的做法是既然轨迹结束时物体实际在 C那我就把这条轨迹的目标从 B 改成 C然后重新计算奖励——此时每一步的 reward 都变成 1 了因为目标 C 最终确实被达到了。这条轨迹从全零奖励的废数据变成了全成功奖励的金数据被重新扔进 replay buffer供策略学习。理解了吗它没有改变环境没有伪造任何物理过程只是换了一个评判标准。这个思想特别像射箭你想射十环结果射偏了落在八环。传统做法是这一箭白射了HER 的做法是把八环当作目标重新复盘这一箭——咦这一箭其实轨迹很稳如果目标就是八环那这就是一次完美的射箭。多复盘几次你至少学会了如何稳定地射中某个位置再从中泛化到十环就容易多了。这种事后诸葛亮式的学习正是稀疏奖励环境里的一剂强心针。因为它不依赖运气不依赖探索到真正目标只要轨迹里出现了任何有价值的状态都会被充分利用。你不需要真正完成任务也能学到完成任务所需的技能片段。1.3 适合什么任务不适合什么任务当然HER 不是万能的药。你得先认清它的适用边界否则硬套只会浪费算力。适合 HER 的任务都有一个共性存在目标和状态之间的可分离结构。经典的适用场景包括机器人运动控制手臂到达某个坐标、抓取物体、推动物体到指定位置导航任务到达某个坐标点离散游戏中的状态匹配问题比如解开某个特定布局的魔方任何可以定义目标空间、并且目标可以事后被修改的环境这种环境下你总能很自然地问一句这条轨迹最终到达了什么状态把这个状态当作目标是否合理如果答案是肯定的HER 就能用。不太适合 HER 的任务也有明显的特征目标本身无法事后替换或者奖励和是否达成某个目标的关联太弱。比如训练一个倒立摆平衡的任务目标就是保持直立你没法把轨迹中某个时刻的倾角当作新目标去重标注因为平衡是一个连续维持的过程不是某个状态快照。再比如训练棋类对弈目标是赢棋而一条输掉的棋局里没有哪个中间局面能当作胜利目标来重写奖励。这类任务硬用 HER只会引入错误的监督信号让策略越学越歪。判断方法其实很简单拿一条失败轨迹出来问自己一句——如果我把目标改成轨迹中某个实际经过的状态这条轨迹是否就能被认为是成功的如果答案是肯定的那你的任务就是 HER 的菜如果不确定可能要找找其他稀疏奖励解法。2. 核心机制拆解目标重标注是怎么改变学习信号的2.1 一次完整的重标注过程演示只讲思想不讲细节等于没讲。我们用一个最简单的 2D 连续空间例子把 HER 重标注的手续一步步走一遍。环境设定一个点在 2D 平面里运动状态是坐标 (x, y)动作是位移目标也是坐标 (x_g, y_g)。奖励规则如果点和目标的欧氏距离小于 0.1reward0否则 reward-1。一次 episode 从 (0.0, 0.0) 出发目标设为 (1.0, 1.0)最多跑 50 步。这条 episode 实际跑出来的轨迹大概是从 (0.0, 0.0) 依次经过 (0.1, 0.2)、(0.3, 0.5)、(0.6, 0.7)、(0.9, 1.1)最后停在 (0.8, 0.9)。因为终点离目标 (1.0, 1.0) 还有约 0.22 的距离大于阈值 0.1所以每一步的 reward 都是 -1。假如没有 HER这条轨迹对策略唯一的教训就是全程都是错的梯度方向混乱基本学不到东西。现在做 HER。随机挑终点 (0.8, 0.9) 作为新目标命名为 g (0.8, 0.9)。然后把轨迹里的每一条 transition 的 goal 字段从 (1.0, 1.0) 改成 (0.8, 0.9)重新计算奖励第 49 步最后一步状态 (0.8, 0.9) 与目标 (0.8, 0.9) 距离为 0reward0成功第 48 步状态 (0.9, 1.1) 与目标 (0.8, 0.9) 距离约 0.28reward-1更早的步骤同理都在 -1你看最后一步从 -1 变成了 0形成了一条成功信号从后往前传导的轨迹。虽然大部分步骤奖励仍然是 -1但至少存在一个明确的、可达的正向反馈点。强化学习的时序差分机制就会沿着这条轨迹反向传播让前面所有步骤都获得朝这个方向走是对的的梯度信号。这还不是全部。实际操作中一条轨迹通常不止重标注成一条新轨迹。以 OpenAI 论文里的做法往往对每条轨迹额外加入多条重标注轨迹默认 k4每个都挑轨迹中不同的状态作为新目标。这样一条 50 步的失败轨迹能变成 4 条带成功信号的轨迹数据利用率提升好几倍。2.2 为什么事后目标能提供有效梯度有些同学可能会疑惑把目标改成轨迹实际到达的状态这不等于自欺欺人吗策略学到的其实是无论我想要什么我都停在某个地方就行这有什么意义这里就要回到目标条件化策略的泛化能力上来了。策略网络 π(a|s, g) 的输入同时包含当前状态 s 和期望目标 g。在重标注后的轨迹里策略在状态 s_t 下要朝 g 前进而这个 g 恰好是轨迹中未来的某个状态。这种数据在告诉策略如果你现在在 s_t而且你希望到达 g那么执行接下来这一步动作是合理的、会导致成功。训练过程中策略会不断看到诸如此类的当前状态-目标-下一步最佳动作三元组。由于重标注的目标来自轨迹中实际发生的状态这些三元组在状态-目标空间里的覆盖范围非常广——不是只有一个固定的 (1.0, 1.0) 目标而是整个可达状态空间里密密麻麻的点。策略相当于在大量虚拟目标上练习如何接近终点这就像射箭的人不只是反复练射十环而是反复练把箭射向自己选定的、刚好够得着的目标基本功扎实了再去挑战十环自然容易得多。更重要的是重标注后的轨迹不会引入不可能完成的幻觉。因为新目标 g 是这条轨迹中实际到达过的状态从 s_t 出发是真实可达的所以策略学到的动作-目标配对永远是可实现的不会学到朝着不可能目标飞这种脱离物理规律的行为。从数学角度解释也很顺。HER 本质上是在改写价值函数的学习目标普通方法只在一个目标 g 上回归 Q 值HER 则在大量目标 g 上回归。这正好契合了通用价值函数的思想——用一个函数逼近器同时预测无数个目标下的价值参数共享让它们互相促进、互相泛化。目标越多函数逼近越平滑学习效率越高。2.3 目标空间与奖励函数之间的关系你可能已经注意到HER 的成败很大程度上取决于目标空间怎么定义。目标空间和状态空间是同一个空间还是存在映射关系这直接影响重标注的难易。最简单的设计是目标空间 状态空间。比如上面那个 2D 点运动例子目标就是一个坐标和状态完全一致。这种情况下一条轨迹里任何一步的状态都能直接作为新目标不需要额外处理。但更多时候目标只是状态的一部分或者需要经过变换。比如机器人抓取任务状态包含机械臂关节角、物体位置、物体姿态而目标往往只是物体位置。此时重标注就要小心选一个新目标 g 时必须保证它和原始轨迹里的achieved goal对应得上。也就是说你需要从 transition 数据里单独记录achieved_goal字段——这是 HER 工程实现里一个极其容易踩坑的地方。奖励函数在重标注后也要保持一致。原环境里如何判断成功的重标注后就用同一套规则判断。假设环境给了一个稀疏奖励函数compute_reward(achieved, desired)那重标注后的奖励就应该是compute_reward(achieved, new_desired)而不是想当然地赋一个固定值。很多复现代码跑出来效果不对十有八九是这里出了问题。这里也顺便说明一下目标空间连续和离散的区别离散目标空间比如把 2D 平面离散成 10×10 网格重标注简单粗暴两个状态相等就奖励 0不等就是 -1连续空间通常要定义距离阈值或者用负距离作为稠密奖励。阈值设大了策略糊弄一下就达标设小了成功信号极其罕见HER 的威力就大打折扣。我通常的做法是先用环境本身提供的默认阈值跑通以后再去微调。3. 从论文到代码实操落地的关键环节3.1 replay buffer 里到底要存什么很多人第一步就错了很多新手把 HER 想象成一种高大上的算法觉得要改网络结构、要改损失函数。其实 HER 最核心的改动就在数据流上而数据流的第一步就是 replay buffer 的存储格式。普通 DDPG、DQN 的 buffer 里存一条 transition大概是四元组(s, a, r, s)有的加一个 done 标志。但 HER 必须在此基础上增加两个字段desired_goal这条数据原本的目标和achieved_goal执行动作后环境实际达到的目标状态。也就是说一条完整的 HER transition 长这样transition { observation: obs, # 当前状态 action: action, # 执行的动作 reward: reward, # 基于原始目标计算出的奖励 next_observation: next_obs, # 下一状态 done: done, # 是否终止 desired_goal: desired_goal, # 原始目标/重标注后的目标 achieved_goal: achieved_goal # 实际达到的目标用于重标注 }注意achieved_goal通常不能直接从next_observation里截取一段维度就行。它必须来自环境返回的info字典因为在很多环境里目标状态可能不是状态的原始形态而是经过某种归一化或变换后的表示。你截错了维度后面重标注算出的奖励全是错的而且这种错在训练曲线上非常隐蔽——它不会让 loss 爆炸只会让学习效率极低。一个坑中坑是 done 标志。原始轨迹里目标没达成done 是 False重标注之后目标达成或者到达终点了done 该不该改成 True如果你用的是带截止回合的强化学习建议重标注后仍保持原始的 done 标志不变因为 episode 在物理上确实没有真正完成最终目标把它标成 True 会让价值函数误以为到达任意状态就等于终止导致后续训练把随便停在某个地方当成最优策略。等到你真正想让策略停在目标点时它反而变得孱弱。3.2 重标注采样策略future 为什么是默认选项确定存储结构之后下一个关键点是如何从这条轨迹中选择状态作为新目标。OpenAI 论文里总结了几种不同的策略效果差异很大策略做法特点final只取轨迹最后一个状态作为新目标简单但每个 episode 只生成一条新轨迹信号有限episode从整条轨迹里随机取一个状态作为新目标覆盖面广但有些状态在时间上离当前步骤太远学习信号偏弱random从所有历史轨迹里随机取一个状态作为新目标适用范围广但目标可能与当前轨迹几乎无关引入较大噪声future从当前 transition 之后的未来时间步里随机取一个状态作为新目标时间上因果一致目标总是可达的效率最高实际操作下来我几乎只推 future 策略也就是每个 transition 都从其所在的 episode 的后续时间步里随机挑 k 个状态作为候选新目标。为什么 future 效果最好因为它保持了一个隐含的时间一致性在 t 时刻你设定的新目标 g 来自未来某个时刻 tt t的状态。这保证从 s_t 出发到 g 是真实可行的而且轨迹中从 t 到 t 的动作序列就是一条天然的、通向 g 的示范。策略学起来既不费劲也不误导。k 值怎么选论文里最常用的是 k4也就是每一条原始轨迹额外补充 4 条不同目标的重标注轨迹。这个数字不是拍脑袋定的它是在多个任务上调出来的平衡点。k 太小重标注信号太少效果不明显k 太大replay buffer 里伪成功样本占比过高策略可能过度拟合近期状态可达到的模式对远距离目标的泛化反而变差。我自己在机械臂任务上对比过 k1、k4、k8k4 在收敛速度和最终成功率上综合最优k8 在训练前期略快一点但后期稳定性差一些。一个小细节future 采样时要不要排除 tt 这种同一时刻建议不要选当前时刻本身因为那样新目标和当前状态一致对学习毫无增量。务必要让 t t。3.3 核心训练循环伪代码能跑通的最小实现讲完理论直接上一段能负责把 HER 跑起来的伪代码。以最常见的 DDPG HER 组合为例逻辑对 DQN、TD3、SAC 同样适用import random import numpy as np # 假设 env 返回 obs, reward, done, info其中 info 必须包含 achieved_goal # replay 是自定义的 ReplayBuffer支持按轨迹episode存储 for episode_idx in range(total_episodes): obs env.reset() episode_transitions [] achieved env.goal # 初始的 achieved_goal for t in range(max_episode_steps): # 目标条件化策略输入包含 obs 和当前 desired_goal action policy.select_action(obs, desired_goal) exploration_noise next_obs, reward, done, info env.step(action) achieved info[achieved_goal] # 注意这里取到的才是真正目标空间表示 episode_transitions.append({ obs: obs, action: action, reward: reward, next_obs: next_obs, done: done, desired_goal: desired_goal, achieved_goal: achieved, }) obs next_obs if done: break # —— 核心HER 重标注 —— her_extra [] for i, trans in enumerate(episode_transitions): # 对每个 transition采样 k 个 future 状态作为新目标 future_states random.sample( episode_transitions[i1:], # 只能从未来取 min(k, len(episode_transitions) - i - 1) ) for future_trans in future_states: new_goal future_trans[achieved_goal] new_reward compute_reward(new_goal, trans[next_obs]) her_extra.append({ obs: trans[obs], action: trans[action], reward: new_reward, next_obs: trans[next_obs], done: False, # 保持 done 为 False前文已解释 desired_goal: new_goal, achieved_goal: trans[achieved_goal], }) # 原始轨迹和重标注轨迹一起入 buffer for trans in episode_transitions her_extra: replay.add(trans) # —— 训练阶段和普通 off-policy RL 没有区别 —— for _ in range(updates_per_episode): batch replay.sample(batch_size) policy.update(batch)这段代码的核心就两件事一是把每条轨迹里的所有 transition 都额外生成 k 条重标注版本二是重标注后的 done 保持 False。你把这两件事做好了DER 的 70% 功效就到手了。还有几个容易被忽略的实现细节。第一重标注的奖励计算必须复用环境的compute_reward函数不要自己另写一套否则环境和策略的评判标准不一致训练会撕裂。第二如果环境自带的就是稠密奖励比如负距离重标注后仍然用同样的稠密公式只是把目标换成新目标HER 不限定只能用稀疏奖励。第三建议在重标注之后对整条轨迹做一次肉眼检查——打印几个新目标的坐标看看是否合理可解释这一步能帮你避免很多隐性问题。3.4 超参数速查直接把能用的值贴给你参数这东西光看论文不给具体值等于大海捞针。我根据自己复现和跑工程的经验把 HER 相关的关键参数整理成一张速查表参数常见取值说明重标注数量 k4每条 transition 额外生成的样本数采样策略future从同一轨迹的未来时间步中采样buffer 大小10^6尽量大因为重标注会成倍增加样本训练频率1 次 update / 1 个 episode如果 episode 很长可改成每步更新探索噪声0.1~0.3太大会掩盖学习信号太小探索不足目标阈值环境默认别急着调先跑通再优化网络结构两层 256 或 128小任务 128复杂任务 256别一上来就超大网络特别提醒 buffer 大小这一点HER 会额外生成 k 倍的伪成功样本如果你 buffer 设得小这些样本很快会被后续数据冲刷掉策略的泛化地基就打不稳。我在一个推箱子任务上把 buffer 从 10^5 扩到 10^6最终成功率直接提升了 20 个百分点。很多人复现 HER 效果不好buffer 容量不够往往是第一元凶。4. 训练那些坑失败模式排查与调参实录4.1 训练曲线纹丝不动时按这个顺序排查HER 听起来美好但工程实现里翻车的概率一点都不低。我自己在多个项目里踩过不少坑把最常见的失败模式整理成了一套排查顺序。第一步检查重标注后的奖励是否真的有变化。很多人在 buffer 里存数据没问题但重标注逻辑写错了——比如拿next_obs做新目标时取错了维度导致新目标和旧目标几乎一样伪成功样本根本没产生。排查方法很简单单独跑一条 episode手动调 HER 函数打印重标注前后的 reward 对比。如果重标注后的轨迹里一条 reward0 的样本都没有问题出在重标注本身。第二步检查缓冲区里伪成功样本的比例。理想情况下训练初期的采样 batch 里应有明显比例的伪成功样本——因为伪成功样本对应策略过去曾经达到过的状态这些状态是策略的已知成功区。如果这个比例太低比如不足 5%说明 future 采样的逻辑有问题或者 episode 太短导致可选未来状态太少。第三步看 critic loss 是否正常。HER 场景下 critic loss 通常不会爆炸但如果你发现它在训练初期就震荡得厉害那可能是奖励尺度的问题。伪成功样本的 reward 从 0 到 -1 不等原始样本和重标注样本的 ratio 如果不平衡价值函数会被伪成功主导。此时可以尝试把重标注样本的优先级调低如果用了优先回放或者简单地在采样时对两类样本做个 1:1 的混合。这些排查步骤走一遍大部分训练无动静的情况都能定位到具体原因。我自己的经验是90% 的问题出在数据格式和重标注逻辑上算法本身反而很少背锅。4.2 稳定性问题训练后期成功率来回跳另一种常见现象是训练前期效果不错后期成功率在 60%~80% 之间反复横跳始终上不去。这种问题多半和两个因素有关一是探索噪声过大二是重标注目标的范围太窄。探索噪声大这个好理解训练后期策略已经有一个不错的 baseline如果 noise 还保持初期那么大策略的动作会被噪声干扰好不容易学到的精细控制被破坏。解决方法是老生常谈的噪声退火annealing。但注意别退得太快否则策略又回到稀疏奖励的困境里。重标注目标范围太窄这个问题隐蔽得多。future 采样的目标全都来自同一 episode 的后半段如果环境初始状态每次差不多轨迹形状也比较集中那么重标注出的目标就会长时间聚集在某个状态子空间里策略对远距离目标的泛化能力就一直没被锻炼。一个有效的技巧是在采样 future 状态时稍微放宽限制比如以 70% 的概率选未来的状态30% 的概率选整条轨迹里任意状态等于混合 episode 策略。这样既不破坏因果一致性又能扩大目标的覆盖范围。我在车上做过实验这个混合策略对最终的泛化稳定很有帮助。4.3 对比实验不靠谱先看看这几个变量是否对齐如果你要做 HER 和某 baseline 的对比实验或者同一环境不同配置的消融实验有几个隐蔽变量最容易让结果失真。第一是评价指标。HER 训练的是多目标策略你不能只拿最初始的目标去测试成功率。正确的测法是随机采样一批目标要和训练时候的目标分布一致让策略分别去完成然后统计平均成功率。否则你很可能只看到策略在初始目标任务上的表现而忽略它在泛化上的优势。第二是随机种子。HER 的重标注过程本身是随机的同一配置下不同 seed 的结果差异可以很大。做对比实验时至少跑 3~5 个 seed取均值和方差再下结论。只跑一个 seed 就宣布方法有效或无效在 RL 里没有任何说服力。第三是训练步数和 buffer 状态的公平性。HER 因为额外生成样本同样的环境交互步数下buffer 里的样本更多、训练更新更频繁。如果你只是在总交互步数上对齐HER 天然占便宜。这时要说明清楚你比较的是同交互预算下的真实性能还是同更新次数下的算法优劣两种比较有完全不同的结论。5. HER 之后从离线数据到更复杂的任务5.1 与主流算法的适配远不止 DDPG很多人以为 HER 只能配 DDPG这是最大的误解。HER 是一个数据重标注模块不是算法本身它可以嵌入任何 off-policy RL 框架。我在项目里分别试过 DDPG HER、TD3 HER、SAC HER后两者在连续控制任务里效果明显更好尤其 SAC 的熵正则化会让策略在早期探索更充分配合 HER 的伪成功样本收敛速度和稳定性比 DDPG HER 高一个档次。配 TD3 或者 SAC 时有一点需要注意actor 和 critic 的输入都必须包含目标向量 g而且目标向量最好经过归一化处理后再进网络。HER 重标注出的目标分布可能与原始目标分布不同如果不做归一化网络输入的标准差会非常大影响训练稳定性。我通常的做法是在 buffer 里记录目标空间每个维度的均值方差然后做 running normalization。PPO 这类 on-policy 算法和 HER 的适配要麻烦很多。因为 HER 重标注的样本来自历史策略而 PPO 对 off-policy 数据的容忍度极差。理论上可以重标注后当作行为克隆的辅助损失来用但实现复杂度高效果也不稳定。如果你就在用 PPO 做稀疏奖励任务我会建议先换成 off-policy 算法再考虑 HER别硬凹。5.2 离线场景里的目标重标注潜力与风险并存近两年离线强化学习越来越火HER 在这个方向上的应用也被重新挖了出来。如果你手上有一堆离线数据比如柔性制造产线上采集的机器人操作日志里面绝大多数轨迹都是失败的怎么利用HER 的思路依然有效把轨迹实际到达的姿态作为目标重新标注就能从看似无用的失败数据里提炼出大量成功片段。但离线场景比在线多一层风险数据分布偏移。在线训练时重标注样本会被策略实时尝试并修正偏差离线时重标注样本里的动作-状态分布是固定的如果策略学到的是把所有轨迹都标成成功这种捷径它可能会产生幻觉——生成一个价值虚高的策略而真正部署到环境时立刻崩盘。我在离线项目中应对这个问题主要靠两条一是限制重标注目标只在轨迹末端附近的小邻域内取二是同时用原始目标样本给策略加一个保守正则项类似 CQL 的思路防止价值函数被伪成功样本撑爆。5.3 下一个值得关注的方向自动课程与子目标生成HER 本身已经是自动课程学习的一种朴素形态——它不断把目标替换成更容易实现的状态让策略阶段性地从易到难。但更进一步的做法是主动生成具有阶梯难度的课程目标而不是被动地从轨迹中采样。比如分层强化学习场景上层策略负责生成子目标下层策略负责执行。这种情况下下层策略依然可以用 HER 来学习如何达到任意给出的子目标上层策略再学习如何制定合理的子目标序列。HER 就像一个万能的下层执行模块给上层提供了可靠的基础能力。再比如和自动课程学习结合把 HER 重标注出的目标按照难度聚类训练早期多采样容易目标后期逐渐增加难目标比例。我在一个 open 环境的抓取任务里试过这种动态难度调度相比纯 uniform 采样最终成功率提升约 15%而且训练方差明显减小。这个方法不需要额外网络组件只是在采样时加了点权重调度成本很低值得一试。说了这么多最后聊聊我自己的实际操作体会。第一次跑 HER 时的感受是震惊的同样一个机械臂 reach 环境naive 版本策略 5000 个 episode 过去成功率几乎为 0加上 HER 以后500 个 episode 左右成功率就开始爬升2000 个 episode 时已经接近 90%。那种从死局里活过来的体验是做 RL 工程最爽的时刻之一。如果你打算在自己的项目里尝试 HER我建议你先做一个小验证再上大任务挑一个带achieved_goal字段的简单 gym 环境手动跑一条失败轨迹调用重标注函数亲眼确认奖励从全负变成含正样本。这个验证只需要十分钟但能帮你排除掉数据格式和奖励函数这两个最大的隐性杀手。等这一步确认无误再去跑完整的稀疏奖励任务你会发现自己少走了至少一半的弯路。这个技巧我几乎每次带人都要强调一遍因为它在实操中救过我好几次。