算法原理与稀疏奖励实战指南)
hindsight这个词在中文语境里最直白的翻译是“事后诸葛亮”。但在强化学习领域它却指代一个极其实用的算法Hindsight Experience Replay也就是HER。我最初接触HER是因为训练机械臂抓取任务时被稀疏奖励折磨得够呛——Agent学了大半天还是一动不动后来换成HER之后训练曲线肉眼可见地活了过来。这篇文章就围绕“hindsight”展开从词义破题重点拆解HER的核心原理、目标重标注策略、超参数调优和落地时的坑同时也聊聊它适用的场景和边界给正在做goal-conditioned reinforcement learning的朋友提供一份可以直接参考的实操记录。1. “hindsight”这词在强化学习里到底指什么1.1 从“事后诸葛亮”说起英文hindsight字面意思是“后见之明”。我们日常用这个词通常带着一点自嘲事情发生之后回头复盘好像一切都有迹可循但站在原地往前看的时候谁也不知道下一步该落在哪里。心理学里有个对应的概念叫“后见偏差”hindsight bias说的是人在得知结果后会倾向于高估自己事前预测的准确性。这个偏差在强化学习里是我们要避开的东西吗恰恰相反HER这个算法的核心思维方式就是故意利用一种“模拟的后见之明”——把失败轨迹的终点当作新目标来学习。它强行把一个没达成原始目标的episode重写成一串“成功达成某个替代目标”的经验然后塞进replay buffer让Agent去学。这种思路听起来有点像自我安慰但实验结果却非常扎实在稀疏奖励的操控任务上HER能做到普通off-policy算法完全做不到的探索效果。1.2 稀疏奖励问题为什么机器人学不会抓取要理解HER的价值得先理解它解决的问题。在典型的机械臂抓取任务里奖励函数通常是这样的如果机械臂末端最终把物体搬运到目标位置给一个1的奖励否则整个episode不管中间过程如何都是0。这种设计叫稀疏奖励sparse reward。问题在于初始状态下机械臂离目标十万八千里Agent随机探索时几乎不可能恰好完成“接近目标、抓取、搬运到位”这一整串动作因此从头到尾拿不到任何一个正奖励信号。没有正奖励就没有梯度方向策略网络无论怎么更新都只是在原地打转。这个现象在实际训练中表现为loss几乎不下降回报恒定为0Agent的动作输出逐渐收敛到某个固定平局值看起来像“彻底摆烂”。1.3 HER的核心逻辑用结局反推过程HER的处理方式很直接如果原始目标在episode结束时没有达成那我们就“骗”一下自己——把实际达到的最终状态当作目标重新标记这条轨迹把这段此前毫无训练价值的数据变成有正奖励的样本。举个例子机械臂的目标是把方块推到坐标(0.5, 0.3)处。结果这次尝试中方块最后停在(0.2, 0.1)的位置离目标远得很。HER不会丢掉这条轨迹而是把它重写成“目标(0.2, 0.1)方块成功到位奖励1”。这样一来Agent就从这次失败中学会了“如何把方块推到(0.2, 0.1)”。虽然这不是原始任务要求的位置但Agent学到的动作模式是有意义的——它学会了推方块这个基本技能。后续多次失败积累起来Agent慢慢学会把方块推到各种位置最终它自然也能推到目标位置。这就是“hindsight”的意义不纠结于“这次没做到我想要的”而是利用“这次做到了什么”来提取学习信号。2. HER的原理拆解目标重标注为什么有效2.1 HER的数学框架与伪算法流程HER是在Hindsight Experience Replay论文中提出的原论文标题是“Hindsight Experience Replay”Andrychowicz et al.2017。它建立在goal-conditioned强化学习的框架之上。这个框架里每个transition不仅包含状态、动作、奖励、下一状态还必须包含一个goal奖励本身是状态-目标对的函数r R(s, g)。HER的算法流程可以用下面的伪代码来表示它是基于off-policy算法的replay buffer改造方案# 伪代码HER训练循环核心逻辑 for episode in range(total_episodes): episode_transitions [] g_original sample_initial_goal() # 采样原始目标 state env.reset() for t in range(max_steps): action policy(state, g_original) # 根据当前状态原始目标选动作 next_state, _, done, info env.step(action) achieved_goal info[achieved_goal] # 从环境信息中获取实际到达的目标 episode_transitions.append( (state, action, achieved_goal, next_state, done) ) state next_state if done: break # 关键步骤目标重标注 final_achieved episode_transitions[-1][achieved_goal] # 最后实际达到的状态 for transition in episode_transitions: state, action, achieved, next_state, done transition # 保留原始目标下的transition store_to_replay_buffer(state, action, g_original, reward(g_original, achieved), next_state) # 为每个transition额外生成一个“替代目标”重写版本 for g_alt in sample_alternative_goals(episode_transitions, k4): store_to_replay_buffer(state, action, g_alt, reward(g_alt, achieved), next_state)这段伪代码是实践中最常见的写法。需要注意的是环境必须在step返回的info里给出achieved_goal也就是“当前这次动作实际把物体/末端执行器送到了哪里”。没有这个信息HER就无从谈起。2.2 为什么把目标改成“最后碰到的位置”就能学到东西很多第一次接触HER的人会产生一个疑问把目标改成最终状态不就等于让Agent“输得不冤”而已吗凭空造出来的正奖励真的有用吗答案是确实有用而且效果显著但需要理解它为什么有用。关键点在于HER的替代目标不是任意采样的而是来源于这个episode实际到达过的状态。这就保证了重标记后的transition满足一个极其重要的性质在真实动力学下可达。状态-动作对和后续状态确实是一致的只有目标被替换了。当Agent的目标从“把方块推到(0.5, 0.3)”变成“把方块推到(0.2, 0.1)时”这条轨迹中前半段的所有动作与状态转换仍然是真实发生的。因此重标记后的样本构成了“某个目标下的成功轨迹”带有明确的策略改善方向。Agent可以从中学到在接近目标位置附近执行某些动作可以达成目标。这个信号虽然不直接指向最终任务却为Agent的探索提供了一个接一个的中间里程碑。更直观地说HER实际上是在为Agent构建一条从简单到复杂的自动课程什么都不会的时候先学会把方块推到起始位置附近再学会推到任意随机位置最后逐渐靠近真正的目标区域。这不是人为设计的课程而是训练过程中由失败经验自动生成的。2.3 边界条件HER并不是万能钥匙我一开始也误以为HER能解决所有稀疏奖励问题实际用下来发现必须满足若干前提条件。第一任务必须是goal-conditioned也就是存在一个明确的goal表示并且这个goal可以用状态特征来编码。如果任务的目标是“把螺丝拧紧30度”这类没有明确可观测状态的抽象目标HER就很难重标记。目标越能被量化距离度量HER越有效。第二奖励函数最好是一个与目标距离单调相关的函数。比如机械臂任务中常用的基于欧氏距离的稀疏奖励距离小于某个阈值就给1否则给0。HER要求我们能够判断“重标记后是否成功”这个判断依赖于距离度量。如果距离度量不准确重标记产生的大量假正样本会误导策略。第三HER本身不解决探索问题而是把已经发生的探索结果重新利用。如果Agent连物体都没碰过最终状态和初始状态几乎一样那HER重标记出来的目标也几乎和初始目标一样意义就有限了。我在机械臂任务里有个直观感受HER对“接近成功但始终差一口气”的任务效果最好对于完全无法触达任务的探索困难环境单独使用HER并不够还是需要引入课程学习或者内置探索奖励。3. 实操落地从环境搭建到训练曲线3.1 环境选择与基线配置如果你想快速体验HER的效果我建议直接从OpenAI Gym的机械臂任务开始也就是FetchReach、FetchPush、FetchPickAndPlace、FetchSlide这套环境。原因很简单这些环境自带achieved_goal不用自己改环境代码去导出这个信息。官方baseline实现OpenAI Baselines里的her分支写得很清楚可以直接跑通。这些任务的奖励本身就是稀疏的最能直观看到HER的作用。我当时用的组合是DDPG HER网络结构是两层256单位的MLPActor和Critic各一个优化器学习率1e-3。算法层面HER是“目标重标记 replay buffer改造”可以搭配任何off-policy算法。DDPG只是默认选择后来我试过SAC HER效果也很稳稳定性和超参数敏感度甚至更好。3.2 目标重标注策略选目标别只会用最终状态HER论文里给了四种替代目标的采样策略这点很多人忽略实际上对训练效果影响非常大final整条轨迹统一使用最终状态作为替代目标样本量小方差大。future(k)从当前时间步之后随机抽取k个状态作为替代目标。episode从整个episode里随机抽取k个状态作为替代目标。random从所有已见过的状态里随机抽取k个目标。我在实操中最常用的是future(k4)。原因很微妙future策略采样的目标来自当前时间步之后的状态这意味着重标记后的transition在下半段轨迹上仍然保持“状态-动作-后续状态”的真实一致性伪目标的密度也更高。用final的时候同一episode里所有transition全部重标成同一个目标buffer里大量样本高度相关训练容易震荡而future(k)每次从后续状态中随机抽相当于给每条轨迹补充了多段不同目标下的子轨迹数据多样性明显更好。3.3 超参数调优k、replay ratio与buffer大小HER引入的超参数不多但每一个都值得认真调。k值决定每条轨迹会额外生成多少条重标记轨迹。k太小重标记样本不够丰富k太大原始目标样本会被稀释Agent对真正任务目标的关注度下降。4是一个比较中庸的值原论文默认是4。我在FetchPush任务上试过k8发现样本多样性增加但训练速度变慢最终效果和k4差别不大但显存和存储开销成倍上涨。replay ratio表示每个新采集到的transition会从buffer里回放多少个transition进行学习。HER需要较大的replay ratio才能发挥优势原因在于重标记样本的“新鲜度”与原始样本不同。我一般设置replay ratio8相当于每个新样本要配合另外7个历史样本一起更新这样目标重标记带来的额外样本才能真正被消化掉。buffer大小对HER来说也特别关键建议至少100万条。HER生成的样本大量是“伪成功”样本数量极多但单条信息密度低buffer太小会导致重复抽样严重训练后期过拟合到重放样本上。我一开始用50万buffer训练FetchPickAndPlace训练曲线反复横跳换到200万buffer之后稳定了很多。还有一个细节replay buffer里存储的每条transition需要包含achieved_goal字段而且原始目标和替代目标必须分开存放。重标记时不是物理改写buffer里的数据而是在采样时临时计算奖励否则会损失数据灵活性。3.4 训练曲线怎么看稀疏奖励环境的诊断技巧看完训练曲线很多新手会犯一个错误只看原始任务的success rate。其实HER训练早期应该看两个指标重标记目标下的成功率也就是Agent完成“任意目标”的成功率和真正目标下的成功率。我习惯把训练日志拆成三列指标含义期望变化原始目标成功率当前策略完成真正任务的比例应该在训练中后期开始上升重标目标成功率当前策略在随机重标记目标下成功比例训练早期就应该快速上升平均回报含重标replay buffer里所有样本的平均奖励反映整体学习稳定性如果重标目标成功率一直上不去说明Agent连“把物体推到某个随机位置”这个基础技能都没掌握这时候调什么超参数都白搭要先检查state和goal的编码方式、网络容量、学习率。如果重标成功率上来了但原始目标成功率纹丝不动说明目标分布与初始目标覆盖度之间有缺口可以尝试加大k或者改用future策略。4. 我踩过的坑和一些直接影响训练效果的决定4.1 坑一目标编码方式不统一HER对目标编码极其敏感。我最初在图神经网络还没流行的年代用过一个简单的状态拼接方式把state和goal直接拼接成一个向量输入网络。这个方式本身没问题真正的问题是goal空间和state空间的量纲不一致——抓取任务里物体坐标是0~1量级但机械臂关节角可能是-3~3量级直接拼接会导致网络训练初期被量纲大的维度主导。解决方法是归一化或者在环境层面把state和goal统一到同一坐标系。Fetch系列环境里state的物体位置信息和goal的编码方式天然一致所以表现好。换到自己写的环境时必须仔细确认state向量和goal向量的物理含义是对齐的否则HER等价于在目标空间引入了系统性噪声。4.2 坑二achieved_goal字段信息不全这个坑更隐蔽。HER依赖achieved_goal来重标记但很多自建环境的achieved_goal只包含末端执行器位置不包含物体位置。这样一来Agent“把物体推走了”这个事实不会反映在achieved_goal里重标记出来的目标就会是“末端执行器到此位置”而不是“物体到此位置”训练出来的策略抓取动作非常奇怪。我在自建环境里踩过这个坑现象是训练很久之后重标成功率很高但原始任务成功率几乎为0。排查发现物体位置没有进入achieved_goalAgent其实在学“把手伸到某个位置”完全没在学“推动物体”。这个问题必须靠仔细检查环境接口解决没有任何超参能弥补。4.3 坑三伪目标分布收敛导致的策略退化HER的一个潜在副作用是目标分布偏移。训练初期buffer里的重标记目标大多是物体停留在起始位置附近的状态因为Agent还没学会移动物体。这些目标构成一个狭窄的目标分布Agent不断在学“把物体推到起始位置附近”的技能这个技能显然不够用。随着训练推进重标记目标逐渐覆盖更广的空间Agent学到的技能也更丰富。但如果训练过程中目标分布的覆盖速度跟不上策略更新速度就可能出现一种退化Agent在探索中永远只到达过很小范围的最终状态因此重标记目标始终局限在这个小范围里训练卡住。对策是在真实目标之外适当增加一些随机采样目标作为监督。OpenAI Baselines的代码里其实没有做额外处理我在实践中发现每100个真实目标样本里额外放10个随机覆盖全目标空间的样本能显著缓解这种退化。这个方法也可以理解为一种不严格的目标课程学习。4.4 坑四HER 环境随机性的相互作用最后这个坑跟仿真环境的设计有关。Fetch系列环境的物理引擎状态重置是确定性的每次reset时物体位置固定这给HER提供了天然稳定的训练条件。如果环境随机性很大比如每次episode物体初始位置完全随机且奖励阈值设置得很紧HER会变得不太稳定。原因是随机性大意味着“距离目标一步之遥”的样本出现的概率更低HER最擅长利用的正是那些“差一点点就成功”的轨迹。奖励阈值设得过紧也会造成类似问题比如抓取任务要求物体位置误差小于1cm才给奖励但机械臂末端控制精度本身只有2cm那HER帮不上任何忙——因为Agent即使在好的动作模式下也永远到不了奖励阈值范围。遇到这种情况我一般会先放宽奖励阈值作为预训练再逐步收紧配合HER让Agent先从“容易达成”的目标学起。5. 应用场景与后续扩展5.1 从机械臂到移动机器人的迁移HER并不只适用于机械臂任务任何有明确状态目标且动作空间连续的goal-conditioned任务都可以试着套用。移动机器人导航就是典型场景目标是“到达某个坐标位置”agent的state是自身位置和局部观测achieved_goal就是自身实际走过的坐标。在稀疏奖励下普通RL算法很难让机器人从随机位置学会长距离导航HER则可以把每条失败轨迹重标记成“到过某个中间位置”的成功经验逐步学会从一个点到另一个点的机动能力。需要额外注意的是移动机器人的状态通常包含局部传感器观测目标往往是绝对坐标。把两者拼接进网络时要确保网络结构具备对两者解耦的能力我倾向用两个独立编码器分别处理state和goal再合并成特征比单纯拼接效果更稳。5.2 与课程学习和内在奖励的联动前面说过HER本身不解决“完全探索不到任何有用状态”的极端稀疏问题。有些任务Agent在episode里压根没移动物体最终状态和初始状态几乎一样此时重标记目标与原始目标高度重合HER几乎没有增益。我遇到这类任务时会叠加两层机制第一层是内在奖励比如ICM或者RND鼓励Agent去访问新奇状态。这样即使外部奖励全为0Agent也会因为“探索了全新区域”而获得正的内部信号从而产生更多样化的最终状态给HER提供更多样化的重标记素材。第二层是课程学习从简单目标开始逐步过渡到困难目标。比如先学“把物体推到离起点30cm以内的任意位置”再逐步扩大目标区域。HER相当于为课程学习提供了免费的自动难度调整先学容易达成目标随着策略增强实际达到的状态变多替代目标覆盖范围自动扩大就像一条不用人工设计的隐式课程。5.3 组合任务HER与更复杂决策框架的配合HER在当前大模型和长时序决策的讨论中又重新被人提起是因为很多high-level任务可以被抽象成“目标序列选择”“子目标达成”的组合。比如一个机器人任务“把杯子从桌上拿到柜子里”可以拆解成拿到杯子、放到目标位置、柜门打开与关闭等子任务。每个子目标本身是可观测的可以使用HER来训练子目标达成策略高层规划器负责选择子目标顺序和切换时机。这种分层方案的实践意义在于HER训练出来的子目标策略天然对“目标输入”敏感即策略能够根据输入goal灵活调整行为而不是学会某个单一技能。这一点和Option框架契合度很好——每个Option以goal为输入用HER高效训练高层策略通过经验学习调度这些Option。从我的实践来看这种方案比直接端到端训练一个长时序任务要稳定得多。因为长时序任务的奖励极其稀疏即使是HER也会因为替代目标的时序距离过远而失效但拆成子目标之后每个子任务都有一段相对密集的“近似成功”经验可以利用。写在最后的一点实操体会做了将近一年goald-conditioned强化学习我最深的体会是HER的成功本质上来自一个简单却被低估的观察失败的轨迹里往往藏着大量“对于别的目标来说恰好成功”的样本关键是要有机制把它们挖出来。这种思路迁移到其他工程问题里也一样成立——很多系统里被当作垃圾数据丢掉的信息重新换个角度标记之后可能立刻变成高价值训练样本。如果你正在被稀疏奖励折磨我的建议很直接先花一天时间搞清楚你的环境能不能导出achieved_goal如果能赶紧试试HER把它搭在DDPG或者SAC上面。超参从k4、replay ratio8开始训练日志里同时盯重标成功率和真实成功率。你会发现原本那个训练曲线死如平地的任务突然就有了一丝生机。这也是我当初第一次看到HER训练日志跑起来时最直观的感受——事后看真的比事前聪明得多。