拓冰建站拓冰建站
首页 / 资讯中心 / 正文

强化学习稀疏奖励难题?HER目标重标注机制原理与工程实践

搞强化学习的人十有八九都经历过这种时刻精心设计了环境让智能体从零开始学一个任务结果跑了大半天奖励曲线纹丝不动。不是代码写错了而是奖励太稀疏——智能体在探索阶段连一次“成功”都没碰过梯度回传根本找不到方向。我自己在做机械臂推物体任务时就在这个坑里卡了快两周直到把hindsight后见经验回放HER的机制彻底吃透才真正绕开了这个死胡同。hindsight 这个词的直觉很简单人类回忆过去时总爱说“要是当初那样做就好了”。HER 把这套事后总结的思路搬进了强化学习——既然智能体这次没达到预设目标那就把它实际达到的状态当作一个新目标重新审视刚才走过的轨迹。这样原本被判定为“失败”的经验也能变成学习信号梯度更新就有了方向。我最初是在 OpenAI 那篇同名论文里接触到这个概念的后来又在好几个机器人控制任务里实际跑通了今天就把从原理到实装、从调参到避坑的完整流程一次性摊开讲清楚。这篇文章适合两类人一类是想搞清楚 HER 为什么能解决稀疏奖励问题、正准备把它接进自己 RL 项目里的工程师另一类是已经在 DDPG、SAC 上加了 HER 却迟迟不出效果、怀疑自己实现有 bug 的同学。这里头的很多细节论文里不会写代码注释里也没有但恰恰是决定成败的关键。1. 为什么需要“事后聪明”稀疏奖励下的学习困境1.1 稀疏奖励到底难在哪强化学习的经典套路是智能体和环境交互靠奖励信号调整策略。入门教程里的奖励设计通常很密集比如“离目标越近分数越高”“每走一步都有反馈”让智能体像走楼梯一样一步一步往上爬。但真实任务很少这么友好机器人抓取、物体搬运、零件拼装这些场景没法在每个时刻都给出有意义的密集反馈经常只能在一整段操作结束后告诉你“成没成”。这就构成了典型的稀疏奖励环境。在稀疏奖励环境里智能体初始策略基本是随机探索。拿机械臂推物体举例如果目标位置在桌面另一端随机策略在几十万次交互里都很难碰巧把物体推到目标附近。于是每条轨迹拿到的奖励都是同一个负常数或者零策略梯度算出来所有动作的优劣完全无法区分训练直接陷入死水。这也是为什么很多 RL 项目在真实物理环境中跑不起来——实验室里密集奖励的场景勉强能工作一换到真实操作就彻底失灵。1.2 常规补救方案的局限性遇到稀疏奖励大多数人第一反应是做奖励塑形reward shaping就是人为构造一个密集奖励函数。这确实能加快早期学习但坑非常多设计不当会引入局部最优智能体很快就学会钻空子比如绕着目标转圈刷分就是不学任务本身。另一个思路是课程学习curriculum learning把任务从简单到复杂排序让智能体先学容易的再逐步加大难度。这个方法思路没问题但每换一个任务都要重新编排课程表人工干预量非常大。第三种方向是增强探索比如把随机噪声调得更猛或者引进好奇心机制但很多稀疏任务就算探索得再充分依然采不到一次成功状态的样本。这些方案本质上都还困在“按预设目标给奖励”的大框架里。真正破局的角度是意识到目标这个变量本身也可以被调整。HER 就是从这个角度切进去的。1.3 HER 的聪明之处在哪里HER 的灵感来自一个再普通不过的生活常识失败不等于全无价值。在“事后”看来智能体虽然没有到达预期目标但它一定到达了某个状态。如果把这个实际到达的位置定义为新目标刚才那条轨迹就变成了一条“成功轨迹”。这种重新解释历史经验的方式像不像我们复盘项目时说“虽然没完成 A 方案但顺手验证了 B 方案的可行性”从数学视角看HER 做的事是在经验回放的存储环节里嵌入了一次目标重标注。原来的经验回放存的是 (状态、动作、奖励、下一状态、目标) 五元组其中目标是预固定的HER 会额外构造若干个替代目标并以此重新计算奖励把一批“失败经验”刷新成“成功经验”再放回缓冲区。这样一来即使真实总目标一次都没达成智能体也能从大量虚拟成功中学会“什么动作组合会导致什么状态变化”策略网络和价值网络的训练信号一下子就充实起来了。2. HER 核心原理目标重标注机制深度拆解2.1 从一条轨迹看重标注怎么做假设环境是带目标设定的按照 Gym 里 GoalEnv 的接口每个状态被拆成三部分observation 是观测主体achieved_goal 是实际达到的目标描述desired_goal 是期望完成的目标描述。以机械臂抓取为例observation 是关节角度和物体位置achieved_goal 是当前物体的位置或抓取状态desired_goal 是物体要送达的目标位置。智能体执行一条长度为 T 的轨迹全程都朝着 desired_goal g 去探索。到轨迹结束时物体停在位置 g_actual并没有到达 g于是这条轨迹里所有 transition 的奖励都是 -1或 0取决于指示函数怎么定义。按传统经验回放处理这些样本的价值标签全一样策略更新的梯度被偶然噪声主导完全学不到东西。HER 做的事情是从这条轨迹里挑出一个未来时间步比如第 k 步把这一步时物体的位置 g_k 作为新的 desired_goal然后把整条轨迹重新整理成“以 g_k 为目标”的经验。因为轨迹后来确实到达过 g_k所以从第 k 步往后的 transition 在新目标下就是成功的奖励立刻从 -1 变成 0。这些重标注样本进入缓冲区之后训练算法就能看到大量“目标可达”的正样本。这里有个关键细节重标注不是整条轨迹一股脑替换目标而是逐条 transition 处理的。原始目标版本保留每个 transition 额外生成若干替代目标版本所以经验池的存储量大约是原来的 K1 倍。2.2 四种重标注策略的取舍论文和开源实现里通常能见到四种目标重标注策略我逐个说下实际感受。final取轨迹最后一个状态作为新目标。逻辑最简单但对长轨迹来说末尾状态可能离轨迹前段太远只有后半段的 transition 能获得正信号。future从当前时间步之后的状态里随机挑一个作为新目标。这是论文推荐的主力方案因为它保留了一个重要的因果属性——新目标是在当前时刻之后真实出现的所以“当前动作导致后续某个状态”这条因果链是成立的。episode从整条轨迹任意位置随机挑一个状态作为新目标。覆盖范围最大但可能挑到轨迹开头、与当前动作毫无因果关联的状态训练时奖励信号容易抖动。random从其他轨迹里随机挑状态作目标。几乎没人用因为跨轨迹的因果彻底断裂对学习没有帮助。我自己的实测经验是future 策略在绝大多数任务上最稳final 作为后备方案episode 偶尔在离散状态任务里有点作用。新上手的话直接默认 future 就行。2.3 为什么 future 策略最稳future 策略的稳定性来自它对待因果关系的克制态度。强化学习学的是条件分布在某个状态做出某个动作之后未来可能转移到哪些状态。如果新目标是从当前时刻之后真实发生过的状态里采样出来的那这个转移关系至少真实发生过Q 网络在学习时看到的状态-动作-目标三元组符合数据分布的一致性。反过来如果乱用 random 策略新目标与当前状态完全没有关联Q 网络要去拟合“从这个状态做这个动作就能达到那个完全无关的目标”这种拟合需要极长的震荡才能收敛很多时候根本收敛不了。所以 HER 并不是无限制地捏造成功而是有节制地在真实转移过的状态上做文章这个“节制”正是它能稳定工作的核心原因。2.4 和 off-policy 算法的适配逻辑HER 本身不是一个独立的强化学习算法它是一个经验增强模块需要挂在 off-policy 算法上使用比如 DQN、DDPG、TD3、SAC 这类带经验回放的算法。原因很直接HER 要求大量重标注样本被反复取用而 on-policy 算法每次更新完策略就丢弃旧经验根本没有机会对同一批数据做目标扰动。HER 对 off-policy 方法的价值可以从 Q 网络的角度来理解。Q 网络要评估“某个动作在某个状态下能带来多大收益”。重标注等于给同一个 transition 分配了一个新的虚拟目标这迫使 Q 网络理解“状态转移本身和目标无关但成功与否取决于目标”。训出来的价值函数自然具备了跨目标泛化的能力。这个性质在机器人操作和多目标任务里特别珍贵相当于智能体学会的不是某一条特定轨迹而是“如何把任意状态推向任意目标状态”的抽象技能。3. 从零实现 HER代码结构与实操细节3.1 环境与工具链准备我实际跑过的组合是 Python 3.8、PyTorch 1.10强化学习部分用自定义实现配合 Gym 的 GoalEnv 接口。如果你手头已经有 DDPG 或 SAC 代码把它改成 HER 版本比从零搭框架省力得多。基础依赖是 numpy、torch、gym、tqdm跑机器人仿真还得装 mujoco-py 或 pybullet。强烈建议先拿 Bit Flipping 环境来验证流程。这是个比特翻转游戏状态是长度为 n 的二进制向量目标也是同长度的二进制向量智能体每次翻转一位当前向量与目标完全一致时奖励为 0否则奖励为 -1。它把稀疏奖励的所有特征都浓缩在一个极简环境里又不需要物理引擎跑起来飞快调试体验非常好。3.2 数据结构必须分清楚HER 要求环境把状态显式拆成 observation、achieved_goal、desired_goal 三个字段。在 Gym 的 GoalEnv 里reset 函数和 compute_reward 函数天然提供了这套接口。构造 transition 时除了常规的 (obs, action, reward, next_obs, done)还必须额外记录最初的 desired_goal 和 next_obs 中的 achieved_goal因为重标注时要用 achieved_goal 替换 desired_goal并重新算奖励。我在这个地方踩过一个大坑把 achieved_goal 和 desired_goal 存成了同一个张量导致重标注时根本分不清“原目标”和“实际目标”HER 等于完全失效。建议用字典或命名元组来组织数据别图省事简化结构。3.3 重标注与经验存储的核心代码HER 有两种实现时机一种是在轨迹结束后整条处理另一种是采样过程中逐条处理。我强烈推荐前者。整条轨迹摆在那里future 策略需要的未来状态随取随用逻辑特别直观。下面是 future 策略处理一条轨迹的核心伪代码def relabel_episode(transitions, her_k4): transitions: 长度为 T 的列表每个元素是 (obs, achieved_goal, desired_goal, action, reward, next_obs, done) 返回加入重标注样本后的批量 transition new_transitions [] T len(transitions) for t in range(T): obs, ag, dg, action, reward, next_obs, done transitions[t] # 始终保留原始目标版本 new_transitions.append(transitions[t]) # 额外生成 her_k 个重标注版本 for _ in range(her_k): # future 策略从 t1 到 T-1 随机选一个未来时刻 if t T - 1: future_t T - 1 else: future_t np.random.randint(t 1, T) new_ag transitions[future_t][1] # 未来时刻的 achieved_goal # 以新目标重新计算奖励和 done new_reward, new_done compute_reward_after_goal(new_ag) new_transitions.append({ obs: obs, achieved_goal: ag, desired_goal: new_ag, action: action, reward: new_reward, next_obs: next_obs, done: new_done, }) return new_transitions这段代码里最重要的一行是new_ag transitions[future_t][1]它把未来某个真实状态拿来做新目标。而compute_reward_after_goal的实现通常非常简洁如果当前 achieved_goal 与新目标一致奖励为 0否则为 -1。别小看这个简单的函数它出问题的概率远超你的想象后面会专门展开讲。3.4 超参数配置与训练流程HER 最关键的额外超参数是 her_k也就是每条 transition 额外生成的重标注样本数量。论文默认 4我实测下来 4 到 8 都合理。设太大经验池里虚拟成功比例过高会干扰对真实失败的判断设太小增益不明显。建议从 4 起步训练曲线稳定后可以试着调大看看有没有收益。完整训练流程大概是这样的初始化策略网络、Q 网络以及各自的 target 网络设置一个容量充足的 replay buffer。我建议至少 100 万条容量不够后面会说有多难受。每轮 episode 开始前随机采样一个 desired_goal重置环境记录初始状态。智能体执行动作采集完整轨迹实时把原始 transition 临时存到列表。轨迹结束后调用 relabel_episode把原始样本和重标注样本一起写入 replay buffer。从 buffer 采样一个 batch更新 Q 网络和策略网络。注意 batch 里混着原始目标和重标注目标这是一个混合学习的过程。定时软更新 target 网络。如果一切正常在 Bit Flipping 上普通 DDPG 几万步成功率可能还是 0而 HERDDPG 几千步就能看到成功率往上走。我在机械臂任务上同样有限时间预算里只有 HER 版本训练成功纯 DDPG 几乎完全没动静。这并不代表 DDPG 不行而是稀疏奖励下传统经验回放根本喂不动 Q 网络。3.5 观察指标与效果验证除了成功率强烈建议额外记录平均到达距离也就是实际状态和目标状态的差距。成功率指标在早期很长一段时间都是 0看起来像什么都没发生而平均到达距离是连续值能更早地反映策略是否在向目标靠近。我在多个任务里都观察到相同的规律先看到到达距离开始下降再过一段训练成功率才真正升起来。训练结束后还有一个很好的验证手段不要急着清空 buffer拿 buffer 里那些被重标注过的样本做一次离线策略评估。你会看到即便轨迹原本全是失败的重标注后的 Q 值分布依然能给出有效的价值信号。这个诊断方法在切换新任务时特别有用能快速告诉你问题出在环境、HER 还是底层算法。4. 我踩过的 HER 坑常见问题与排查技巧4.1 重标注后的奖励函数不正确最常见的坑出在 compute_reward 上。很多人直接调用环境的compute_reward(achieved_goal, desired_goal)计算新目标下的奖励却忘了 done 信号也需要同步更新。如果只是改了 reward 没改 done智能体可能在同一段轨迹里连续多次触发“成功结束”训练瞬间崩溃。排查方法是写一个单元测试专门验证重标注后的 transition 里 reward 和 done 是否逻辑一致。另外奖励尺度很关键。HER 内置的稀疏奖励通常是 -1/0如果给“新目标达成”分配过大的正奖励Q 网络的价值尺度会漂移设太小又区分度不够。我建议一开始坚持用 -1/0 的二元指示函数不要叠加距离惩罚。距离惩罚会让 HER 偏离“纯稀疏奖励解决方案”的定位还容易和重标注逻辑互相打架。4.2 目标维度与观测维度不对齐HER 要求 achieved_goal 和 desired_goal 必须在同一个表征空间里。这个空间可以是一段坐标、一组关节角、一个抓取状态关键是两者维度必须完全一致否则 compute_reward 无法判断“是否到达”。我在做一个末端执行器位置任务时环境的 achieved_goal 是三维坐标desired_goal 却不知怎么被写成了四维齐次坐标维度对不上导致所有奖励恒为 -1HER 形同虚设。排查这类问题最简单的办法是在训练前打印一条 transition 各字段的 shape确认 achieved_goal 和 desired_goal 的维度一致。遇到不一致时优先改环境接口别到模型里强行 reshape 糊弄过去。4.3 探索策略太弱导致重标注目标过于集中HER 是从失败经验里创造成功但如果随机策略本身太弱产生的轨迹很短且密集拥挤在起点附近重标注出来的虚拟目标也都挨着初始位置网络很容易学会“原地微调就算成功”后期泛化能力很差。这种情况在真实机械臂上尤其明显因为前期探索产生的轨迹往往被安全限制约束在很小的空间里。我尝试过的解决办法是先不急着上 HER而是让策略用纯随机探索做一轮 warmup采集一批覆盖度足够的数据之后再开启正式训练。这样做的稳定性比从零开始边探索边训练好得多也避免了前期低质量的无效数据反复污染经验池。4.4 经验池容量不足HER 的本质代价是倍增存储每条轨迹要多存 K 倍的样本。如果经验池容量卡在几十万条前期某一批低质量数据很快占满整个缓冲区后期真正有价值的高质量样本反而存不进来。我在一台 24G 内存的服务器上把 buffer 容量开到 200 万条毫无压力所以除非运行环境极度受限否则一步到位给够容量。采样比例上原始样本和重标注样本混在一个 batch 里不需要刻意设计比例。只要你确认 relabel_episode 严格保留了原始版本就不会出现“只学虚拟目标、忘了真实目标”的严重失衡。4.5 训练震荡与冷启动失败不少人第一次跑 HER 会看到成功率曲线呈锯齿状刚升上去又掉回来。这种情况十有八九不是 HER 的问题而是底层 off-policy 算法的 target 网络软更新系数太大或者 batch size 太小。把软更新系数从 0.05 降到 0.005batch size 从 64 提成 128 或 256震荡通常立刻缓解。如果训练从一开始就完全不动先确认 replay buffer 里是否存在足够多的正样本也就是重标注后 reward 为 0 的样本。最直接的验证方式是每隔 100 轮打印一次 buffer 中正负样本的比例。如果正样本占比长期为 0说明重标注逻辑有 bug或者探索范围太窄。这个检查点非常实用建议直接写进日志模块。5. 实装感受与后续扩展方向我在实际项目里用 HER 解决过两个棘手的稀疏奖励问题一个是多指机械臂的物体姿态调整另一个是欠驱动小车的长距离导航。前者的观测空间很复杂HER 让 Q 网络学会了在目标空间里做插值后者因为探索覆盖不足卡了很久最后靠 warmup 和加长轨迹长度解决了。这两段经历让我深刻体会到HER 不是万能钥匙它的价值在于把“失败经验变废为宝”这个思路系统化真正的上限依然取决于你采到的数据质量和状态空间覆盖度。顺便整理一个 HER 相对标准 RL 流程的改动对比方便你评估接入成本。核心思想是环境接口、transition 结构、buffer 写入口这三处是雷打不动必须改的剩下的都可以复用已有算法。组件普通经验回放HER 版本transition 结构状态、动作、奖励、下一状态额外存放 achieved_goal、desired_goal经验写入直接存储轨迹结束后先重标注再批量写入奖励计算只需原始目标同时保存原始目标和重标注目标两套奖励目标空间不需单独定义必须显式定义 achieved_goal 与 desired_goal底层算法不限仅限 off-policy 算法再分享一个值得尝试的扩展方向把 HER 和 transformer 类结构结合。在重标注过程中HER 天然会生成大量“目标-轨迹”对这些数据非常适合做序列建模。我在一个抓取场景里试过用轻量级 transformer 替代原来的全连接 Q 网络发现跨目标泛化能力又上了一个台阶。当然这只是实验性的方向不代表所有任务都适用但你如果已经在工程里跑通了基础版 HER不妨把它当成一个有意思的试验田。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门