恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
稀疏奖励强化学习无解?HER事后经验回放原理与实战解析
首页
资讯中心
/
稀疏奖励强化学习无解?HER事后经验回放原理与实战解析
稀疏奖励强化学习无解?HER事后经验回放原理与实战解析
发布时间:2026/10/3 5:06:43
几个月前我在调一个机械臂抓取任务训练了上万个回合奖励函数没毛病网络结构也正常可智能体就是死活学不会。后来把拆装好的经验回放逻辑换成hindsight思路出一轮效果立刻不一样训练曲线从一条平线变成了陡峭上升。那次之后我就认定hindsight这种事后视角不仅仅是一个套路它直接扭转了稀疏奖励下强化学习的困局。这篇内容就是围绕hindsight展开的确切说是它在强化学习里的典型实现——事后经验回放Hindsight Experience Replay简称HER。我会从问题源头、核心原理、代码实现到参数调整、踩坑记录全部过一遍适合正在做机器人控制、游戏智能体、导航规划或者任何稀疏奖励任务的算法工程师、研究人员、学生。基础一般也没关系我会把关键逻辑说得比较清楚读完你至少能自己动手改一个HER出来。1. 一个失败的回合也是训练机会1.1 稀疏奖励下的绝望强化学习里最让人头疼的场景之一是奖励函数极度稀疏。拿机械臂抓取来说完整流程一般是移动末端到物体上方、闭合夹爪、抓稳、提起来。如果定义最终奖励是物体被提起并保持在目标高度那么在整个几十步的决策序列里只有最后一步能拿到一个1其余全是0。这会导致一个致命问题随机探索时智能体几乎不可能碰到那个1。拿不到任何正反馈策略梯度算出来的信号全是噪声网络参数怎么更新都像是原地踏步。我见过很多人在这种任务上死磕调学习率、改网络结构、加探索噪声效果都不明显。本质原因是样本利用率太低——成百上千个完整回合全被当做失败数据扔掉。但换个角度想这些失败数据真的没用吗一个回合虽然没有达成我们指定的目标A但智能体确实到达了某个状态B。如果我们把目标临时改成B这个回合就是一次成功的尝试它产生的轨迹就变成了珍贵的正样本。这就是hindsight的核心直觉人类在复盘时很容易发现虽然没做到最初想做的事但也得到了一个结果这个结果可以作为下次学习的新目标。把这种复盘逻辑搬到经验回放里就是HER。1.2 HER是什么解决了什么问题HER全称是Hindsight Experience Replay最早由OpenAI在2017年前后提出论文里展示的效果非常直接在没有HER时一个七自由度机械臂的抓取任务训练几百万步仍然学不会加了HER之后几十万步内成功率就接近100%。这个对比当时在社区里引发了不小震动因为它提供了一个几乎零额外计算量的方式去提高样本效率。它的核心做法说起来很简单存储经验的时候不只存原始目标g下的转移元组还额外往经验池里塞入替换目标g下的转移元组。g通常取轨迹中实际到达的某个未来状态。这样一来原本是失败的轨迹在另一个目标维度上变成了成功轨迹策略就能从中获取如何达成某个状态的有用梯度信息。很多人可能会想这不就是变相增加正样本吗其实没那么简单。HER最大的贡献在于解决了目标条件策略中的credit assignment问题。当目标从g被替换成g后我们实际上在告诉价值网络如果未来目标是g那么当前动作产生了正面结果。同时原始目标g下的经验也保留着最终让同一个策略既学会了达成原始目标又学会了达成任何可达状态的泛化知识。两套经验配合训练过程一下子稳定了。2. hindsight核心思路拆解2.1 目标重标注的逆向逻辑假设一个回合轨迹是$\tau {s_0, a_0, s_1, a_1, ..., s_T}$原始目标为g。未达成g意味着$\phi(s_T) \ne g$$\phi$是状态到目标表征的映射函数。HER对这条轨迹做这样的处理选择轨迹末尾或者未来某个时间步的状态$\phi(s_t)$作为新目标g然后把轨迹里的每个转移$(s_i, a_i, r_i, s_{i1})$里的目标字段从g换成g同时根据g重新计算奖励r。这里有个微妙点轨迹中在状态$s_t$之前的转移新目标都是未来会到达的状态所以这些转移在辅助目标下可能也是失败的比如$s_{t}$与$s_t$不同但在$s_t$附近的转移或者在最终状态等于g时奖励就变正了。需要注意HER在存储时通常会保存整个完整轨迹的转移样本每个转移都会重新计算reward。并不是只存最后一步。我做Hindsight时习惯用一个统一写法对一个回合生成N个额外目标每个额外目标对应一组转移样本。这样经验池里同一个原始回合的样本会被复制成N1份一份原始目标N份新目标。这直接增加了样本多样性训练时每个mini-batch里的经验都混合了多种目标下的事后视角。2.2 为什么改写目标能产生有效梯度深层原因在于策略本身是目标条件的即$\pi(a|s,g)$。当目标被替换为g后处于状态s且策略在当前参数下看到了通往g的轨迹这会引导策略在后续类似状态下向更接近g的方向移动。对整个训练来说即使原始目标g一直难以达成但g附近的状态空间被充分采样了价值函数在这些区域学会了准确估计进而在原始目标g下也能更好推断。可以打个比方一个人本来想学钢琴考级结果每次练习都弹得磕磕绊绊但如果把目标临时改成把这首曲子开头两个小节弹顺那每一次练习都有明确的反馈。把这些小的顺滑片段记住长期积累下来整首曲子也能弹顺。HER就是不断给自己设定够得着的小目标让失败也具有正反馈价值。具体到实现目标重标注的粒度也很关键。如果目标是离散的比如迷宫中的某个格子替换目标要选轨迹实际访问过的格子如果目标是连续的比如3D空间中的坐标那么替换目标一般取某个时间步的状态坐标。总体来说HER不要求目标空间连续它只是要求状态可以映射到目标空间并且能够计算距离或判断相等。3. 实操从零实现HER3.1 算法主流程与伪代码先说整体框架。HER不是独立算法它是经验回放模块的改造方案。基础算法可以是DQN、DDPG、SAC、TD3等任意off-policy方法。平时最常用的是DDPG或SAC加HER因为连续控制任务多。下面给一段伪代码风格的流程用Python语义描述# 假设基础算法是DDPG带有actor和critic class HindsightReplayBuffer: def __init__(self, capacity, relabel_fraction0.8, k_goals4): ... def add_episode(self, episode_transitions, original_goal): # episode_transitions: list of (s, a, r, s_next, done) # 先存原始目标下的经验 for transition in episode_transitions: self.store(transition, original_goal) # 从轨迹中采样k个新目标 relabeled_goals self.sample_alternative_goals(episode_transitions, k_goals) for new_goal in relabeled_goals: for transition in episode_transitions: new_reward self.compute_reward(transition.next_state, new_goal) self.store((transition.s, transition.a, new_reward, transition.s_next, transition.done), new_goal)这里的关键函数sample_alternative_goals有很多策略。最基础的是均匀随机从轨迹中选未来时间步的状态还有future策略更常用对每个转移样本$s_t$从它后续时间步$[t1, T]$中随机选一个状态作为额外目标这样trajectory内的转移会看到未来自己能到达的状态从而学到逐步趋近目标。OpenAI的论文里对比了几种策略future策略是效果最好的之一。3.2 关键参数k值、目标选择策略HER里最常见的参数有三个新目标数量k、替换概率、目标采样方式。先说k值。一般取4左右。如果我一个回合有50条转移k4就额外生成4套转移样本经验池总量变成原来的5倍。k太大会让经验池里虚拟成功经验过多冲淡原始目标下的经验导致真正要解决的任务学得慢k太小起不到事后视角的效果。我在实验中会让k在2~8之间调一般4是甜点。替换概率这里要留个心眼。通常在存经验时对一个回合按概率决定是否做重标注而不是对单个转移做。常见的做法是固定概率p0.8即80%的回合会被额外重标注20%只保留原始经验。这个概率可以防止经验池被完全虚拟化。目标采样方式强烈建议优先用future策略。它和后续时间步的顺序有关具体操作是对轨迹中每个时间步t从均匀分布$\mathcal{U}(t1, T)$采样一个索引future_idx然后把$s_{future_idx}$的状态表征作为该转移的替换目标。这样做比随机整条轨迹采一个目标更精细因为它保留了轨迹内部的因果关系——越早的转移可选的未来状态越多学习到的策略越有过程感。除此之外还有final策略只用轨迹最后状态作为新目标、random策略从整段轨迹随机抽状态、episode策略从所有历史成功状态中抽。我实测下来future和final差异不大但对特别长的轨迹future更稳。如果你只关心最终是否能达成目标final就够用如果你想学得更细future更合适。3.3 与DDPG等算法结合HER最常和DDPG搭配因为机械臂操作普遍用DDPG。DDPG本身对超参数敏感加入HER后需要调整的地方并不多但有几个细节要额外注意。第一critic的输入通常含有目标即$Q(s, a, g)$。当重标注目标后critic看到的目标分布变了要确保训练时batch里同时混有原始目标和重标注目标否则价值估计会产生偏差。我的做法是让每个epoch的batch都由三部分构成一部分原始目标经验、一部分future重标注经验、一部分随机重标注经验。比例大概是3:6:1效果比较稳定。第二actor在更新时也要用到目标。对于DDPGactor的目标是最大化$Q(s, \pi(s, g), g)$。在同一个batch里目标字段对每条样本都不同这没问题只需要把g作为网络额外输入。需要保证state和goal的维度拼接正确。例如状态是$s \in \mathbb{R}^{d_s}$目标也是$d_s$维比如目标就是位置坐标那拼接后actor输入维度是$d_s d_g$。第三奖励函数要和目标表征一致。比如目标定义为末端位置与目标位置距离小于0.05奖励就是$r -\mathbb{1}[d 0.05]$或$r -(d 0.05)$重标注后距离变了奖励跟着变。注意奖励最好只依赖于$s_{t1}$和$g$不依赖于动作和原始状态否则重标注会错乱。下面给一个DDPGHER的update片段展示如何在一个batch内统一处理原始经验和重标注经验def train_step(batch): # batch包含 fields: state, action, reward, next_state, goal, done current_q critic(state, action, goal) target_q target_critic(next_state, target_actor(next_state, goal), goal) critic_loss mse(reward gamma * (1 - done) * target_q, current_q) # 更新critic # 更新actor: 最大化Q actor_loss -critic(state, actor(state, goal), goal).mean()整套代码改动量很小如果原本有off-policy训练框架加个HER buffer大概半天就能完成。这也是当初大家迅速跟进的原因。4. 踩坑实录我调HER时遇到的问题4.1 目标空间必须连续吗很多人误以为HER只能处理连续目标实际上不是。离散目标一样能用HER。举个例子迷宫导航的目标是第几个格子轨迹实际经过的格子就是新的离散目标完全可行。HER真正的要求是目标空间和状态空间能对齐且能判断是否达成目标。如果状态映射到目标空间有歧义比如多个不同状态对应同一个目标但奖励取决于状态细节重标注就会引入误导。我踩过的一个坑是在无人机悬停任务中目标定义为3D坐标状态是9维向量含速度和姿态角。替换目标时我直接把状态向量后三维换成目标坐标看起来没问题但critic同时观察了速度信息导致价值函数对目标坐标不敏感。正确做法是设计独立的目标表征比如一个几何坐标并且奖励只按照这个坐标计算不把完整状态塞进目标。记住一句话目标定义越干净HER越好用。4.2 奖励函数设计偏差HER要求我们能在新的目标下重新计算奖励。如果奖励函数是稀疏的0/1没问题。但如果是稠密奖励比如$r -distance(s, g)$那么重标注后也要基于新的距离重算。这里有个坑distance的定义和单位可能导致奖励尺度在不同目标下差异巨大。假设机械臂末端范围是0~1米而目标坐标跨度很大那么重标注目标选得离当前状态很远奖励负值会很大反而抑制学习。解决方法是把距离归一化比如用$r -\min(d, d_{max})/d_{max}$或者干脆用稀疏奖励。我自己的经验是HER的最佳搭配就是0/1稀疏奖励。不要尝试在HER上叠加复杂稠密奖励容易把事后视角的清晰正反馈弄混。你只需要在达成目标条件上做判断其他信息交给网络去学。4.3 采样比例乱调整导致崩溃一开始我图省事让HER的替换概率1.0即所有经验都是重标注的结果策略学到的基本是瞬间移动到未来状态对原始目标毫无进步。原因很好理解经验池里全是成功经验网络以为成功很容易就不需要规划了。后来我把替换概率调到0.8同时把k从4提到6才稳定下来。还有一次我把future策略的采样范围只在轨迹尾部取导致前半段转移的重设目标全都很接近终点后半段又全是终点整个轨迹的因果关系断裂。future策略一定要从$t1$之后的时间步里采不能只采最后几步否则相当于人为缩短了轨迹的长度价值函数对远距离目标的推断会失真。另外经验池容量也要注意。HER会增加样本量如果你原本容量是100万保证对象的priority采样依然有效但替换目标多了之后容量可以不变因为同一个回合的经验对应不同目标训练效果等价于数据增强。不要为了存更多数据盲目扩容量容量过大会让新策略产生的经验占比过低旧经验过于老旧也会影响学习。5. 适用场景与效果边界5.1 典型成功场景HER在哪些任务上几乎必然有用我总结了三个特征目标可以事后判断是否达成、目标空间与状态空间有映射关系、没有复杂的时间逻辑依赖。第一个是机器人操作。典型的七自由度机械臂抓取、推动、放置任务目标是物体的位置或姿态轨迹失败也能看到物体被挪到了哪HER效果极其明显。OpenAI论文里实际任务就是从初始随机位置把方块抓起来放入目标位置HER让成功率从几乎为0提升到80%以上。第二个是导航与路径规划。仿真环境里的点目标导航智能体跑了很远但没到指定点HER可以把实际到达的位置作为伪目标这样就等于每个回合都在学习如何到达自己走过的地方。用在未知环境探索上有奇效。第三个是带有明显阶段性的游戏。比如需要先开门再进入目标房间如果开门失败目标替换为到达门附近后续策略也能学到靠近门的行为。虽然不能完全处理长时依赖但比纯粹的稀疏奖励好了太多。持久化策略目标时HER也常用在模仿学习和课程学习里。比如先用HER学到一些低难度目标再逐渐提高原始目标的难度。这个思路在后来的很多工作中是作为baseline的。5.2 什么时候HER会失效HER不是万能药有几个情景它表现不好。首先是目标空间和状态空间几乎无关联的情况。比如目标是赢棋状态是棋盘落子序列这种目标没法从轨迹里自然采样因为新目标根本不代表一个可学习的棋盘状态此时HER就无从下手。第二是存在动态环境干扰的情况。如果环境中有随机移动的障碍物或者传感器噪声极大轨迹到达的状态本身就不稳定用不稳定状态作为目标会让策略学习震荡。当然可以通过多采样取平均来缓解但HER的优势会下降。第三是目标数量极少且目标分布与状态分布差异极大。比如目标是特定位置的特定物体而轨迹中很难碰到物体那么替换目标采样出的都是空的状态无法引导智能体靠近物体。这种情况建议先做预训练或引入课程任务。我说这些边界并不是劝退而是想强调选型时要多考虑环境结构。如果你面临的问题符合特征一HER几乎是一剂猛药不符合的话就要靠其他技巧补充比如逆强化学习、状态空间抽象或数据增强。最后再分享一个小技巧调HER的时候优先画学习成功率曲线而不是loss曲线。Loss下降不代表目标达成成功率才是真章。我见过太多人盯着TD loss看到曲线平稳就以为完了其实智能体已经在悄悄变好了只是成功判定阈值得太严。你可以把判定阈值放宽一点观察趋势然后再把阈值加严调精度这样训练过程会好掌控得多。