news 2026/9/30 4:25:23

事后经验回放HER:解决稀疏奖励与多目标任务难训练的强化学习利器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
事后经验回放HER:解决稀疏奖励与多目标任务难训练的强化学习利器

看到“hindsight”这个词,我先想到的是认知心理学里那个经典概念——后见之明偏差,也就是我们常说的“事后诸葛亮”。但在强化学习圈,这个词还有另一个让我条件反射般兴奋的对应:Hindsight Experience Replay,事后经验回放,简称HER。这是OpenAI在2017年提出的一项技术,专门解决稀疏奖励环境下多目标任务“学不动”的问题。

如果你正在用DDPG、SAC、TD3这类off-policy算法调机械臂抓取、物体推动、目标导航,或者任何“目标本身是一组参数”的任务,并且明显感觉样本利用率低、奖励常年为负、训练曲线像心电图一样毫无进展,那HER几乎是必须掌握的一项工具。这篇文章会从问题本身出发,把HER的原理、目标重标注的四种策略、和DDPG这类算法集成的实操步骤,以及我真实踩过的坑,一次讲清楚。无论你是刚入门RL的研一学生,还是被机器人抓取任务折磨了几个月的工程师,这篇内容都值得你花十分钟读完。

1. 从“稀疏奖励”说起:HER到底在解决什么问题

1.1 稀疏奖励为什么让RL学不动

先看一个最典型的多目标场景:机械臂学习推一个物体到目标位置。目标是一组三维坐标,比如(0.5, 0.3, 0.1)。奖励函数如果写成“到达目标给0,否则给-1”,这就是标准的稀疏二值奖励。从算法的角度看,它在绝大多数时间步里拿到的都是一个恒定的负奖励,梯度信息几乎为零,策略只能靠随机探索撞大运。

我做个类比你就明白了。想象一个完全不懂投篮的小孩,你告诉他“投进篮筐就奖励一颗糖”,然后让他自由发挥。他前几百次出手大概率连篮板都碰不到,没有一次成功,于是没有得到任何关于“怎么调整手型、力度、弧线”的反馈。如果这个世界只有“进”和“不进”两个状态,他练一天也学不会投篮。RL算法面临的正是这种窘境。

更麻烦的是,稀疏奖励还会带来一个“探索悖论”:越是在奖励稀薄的环境里,策略越容易收敛到“什么都不做”或者“重复固定动作”的局部最优,因为这样做至少不会得到更糟的结果。DDPG这类确定性策略算法尤其容易陷入这种模式,动作空间稍微大一点,随机噪声带来的探索几乎约等于碰运气。

1.2 多目标任务:HER发挥作用的前提

但并不是所有带稀疏奖励的任务都适合HER。HER能发挥作用,关键前提是任务具有“多目标属性”——也就是说,我们面对的不是一个固定终点,而是一个目标空间。每次episode开始时,环境会采样一个目标g,智能体的任务是把当前状态导向这个g。只要这个目标空间足够丰富,那么无论智能体最后完成了什么,总能找到“它实际上达成了什么”。

举个具体的例子。FetchPickAndPlace这类机械臂环境里,目标就是物体需要被送达的三维位置。如果原定目标是把物体放到(0.5, 0.3, 0.1),但智能体最终把物体推到了(0.4, 0.3, 0.1),按照原始目标来评价,这是失败,奖励-1。但从经验利用的角度看,这整条轨迹是“完整走完了一个把物体从初始位置移动到(0.4, 0.3, 0.1)再配合一系列动作的过程”。如果此刻我们换一个角度,把这条轨迹的目标重新定义为“移动到(0.4, 0.3, 0.1)”,那它就是一条成功轨迹。

这就是HER最朴素的思想:如果没能完成原定目标,那就把这段经历重新解释为完成了某个实际达成的目标,并且把这个“事后”视角下构建的成功经验存进回放缓冲区,让智能体从“失败”中学到东西。

1.3 事后视角为什么能从失败样本中提取信息

这里值得深挖一层:为什么替换目标之后,原本无用的失败经验突然就变得有价值了?

因为一条经验里面其实包含两类信息。第一类是“在这个状态下,采取这个动作,环境会转移到哪个状态”,这是环境动态信息,它和目标是哪个完全无关。第二类是“这个转移对于某个目标来说是否有利”,这是目标相关信号。传统经验回放只用了第一类信息,目标信号则由奖励函数在采样时给出。如果当前目标一直没达成,第二类信息就一直处于“无效”状态。

HER做的事情就相当于:既然第二类信息在原定目标下是无效的,那我们直接给它换一个能匹配上的目标,让原本“失败”的转移变成“成功”的转移。这样环境动态信息被完整保留,目标相关信号也被激活,一条样本变成多条可学习的样本。

用改作业来类比可能更直观。老师按原题目标准给一份作业打分,学生全做错了,打零分。但如果老师换一个角度,把题目重新定义成“学生实际写出答案的那个问题”,发现他的解题过程其实相当完整,于是这份作业就变成了高分样本。学生的动作没有变,变的是评价标准。

2. 核心机制拆解:目标重标注的四种策略与有效性分析

2.1 目标重标注的基本流程

HER在实现层面做的事情非常简单,可以概括为三步。

第一步,正常跑一个episode,记录下完整轨迹,包括每个时间步的状态、动作、奖励、下一状态,以及原始目标。第二步,从轨迹中选取一个“替代目标”,也就是智能体实际抵达的某个状态。第三步,针对这个替代目标,重新计算每个时间步的奖励,然后把整条轨迹(或者其中某些transition)连同新目标和新奖励一起存入回放缓冲区。

注意一个关键点:动作不需要重新计算。因为智能体的动作确实是在环境中真实执行过的,只是在事后视角里,我们把这些动作解释成“为了达成另一个目标而做的”。这在数据层面是完全合法的,也是HER能提升样本利用率的核心所在——它不产生新数据,只是给旧数据换了标签。

2.2 final、future、episode、random四种策略怎么选

那么,替代目标从哪里来?论文里给出了四种策略,实践中我用得最多的是future,其次会混一些episode和random。

final策略最简单:每完成一条episode,就拿最终状态作为替代目标。它的优点是实现简单、不引入额外随机性,适用于那些“目标范围较宽、最终状态往往有信息量”的任务。但缺点也很明显,如果episode很长,最终状态和早期时间步在物理上相距甚远,早期经验被标记成“朝向最终状态成功”的数据,学起来会很牵强。

future策略是我最推荐的:在时间步t之后,从(t+1, t+2, ..., t+k)这些未来状态中随机挑一个作为替代目标。这样做的好处是目标不会离执行动作太远,每个transition都能得到一个“近在咫尺”的目标,学习信号更贴近实际。论文里的默认k=4,实践下来这个值相当均衡,后面细说。

episode策略是从当前episode的所有状态里随机挑一个当目标。它的覆盖面更广,能产生更多样化的虚拟目标,但有些目标可能过于遥远,训练早期会给策略带来困惑。random策略则是从所有已知状态里随机抽,相当于给目标空间做覆盖。

我的建议是:不要只用一个策略,最好按比例混合。实践中比较均衡的配比是50%的future、25%的episode、25%的原始目标。注意保留一部分原始目标经验非常重要,这个原因我放到第四章讲,它是HER最容易踩的坑之一。

2.3 HER为什么有效:相当于免费的课程学习

HER之所以能在大量论文中稳定提升效果,除了“提高样本利用率”之外,还有一个更深层的效果:它自动构建了一种类似课程学习(curriculum learning)的训练节奏。

课程学习的核心思路是“先易后难”。人类学习也是这个逻辑,先学走再学跑,先抓静止目标再抓运动目标。HER生成虚拟目标时,目标往往是当前episode中真实被“触碰”过的状态,这天然就构成了一条从易到难的路径。训练早期,策略探索能力差,能碰到的状态少,虚拟目标就集中在那些容易抵达的区域;随着探索能力增强,访问到的状态变多,虚拟目标也开始覆盖更远的位置,相当于课程难度在自动提升。你完全不用手动设计课程,HER在幕后帮你做了这件事。

这一点在机械臂抓取任务中体现得特别明显。普通DDPG在稀疏奖励下可能要跑几百万步才能看到一次正奖励,而加上HER之后,奖励曲线的上升会快一个数量级,因为智能体把每次“没抓到”的经历都转化成了“朝另一个方向移动成功”的正样本。

2.4 对后续研究的辐射影响

从2017年提出到现在,HER可以说是多目标强化学习(Goal-conditioned RL)领域绕不开的baseline。后来的Hindsight Goal Generation、Hindsight Policy Gradient等一堆方法,本质上都是沿着这条“事后视角”主干长出来的分支。很多机器人操作论文里提到“Multi-goal RL”,默认对比算法里基本都有HER这一项。这个技术的影响范围已经从学术圈扩展到了工程端,但凡涉及真实机器人抓取、推动、堆叠的RL项目,工程师们都会把HER作为一个默认启动选项。

3. 实操复现:把HER集成进DDPG的完整思路

3.1 先确认你的任务真的适合HER

动手写代码之前,我先提醒一句:HER不是万能药。如果任务的目标空间非常狭窄——比如目标是固定的一个点,每次episode起点也固定,那“事后视角”可发挥的空间就比较有限,因为无论怎么替换目标,新目标和原目标差别都不大,生成的虚拟经验多样性不够。HER真正发光发热的场景是:目标是一个有丰富取值的参数空间,比如三维坐标、姿态、物体种类、路径点序列。你先花两分钟确认一下自己任务的goal结构,再决定要不要继续往下看。

常见适合HER的任务有两类。一类是目标参数直接写在observation里的环境,典型如Gym Robotics套件里的Fetch系列环境。另一类是需要自己构造目标空间的定制任务,例如让自动驾驶车辆在模拟器里学习“驶向不同的目标点”,只要你把目标点坐标作为目标向量传给策略就行。

3.2 环境侧改造:目标表示与奖励函数

如果你用的是现成的Gym环境,一般不需要额外改造,但这些环境的目标表示往往是dict结构。

比如FetchPickAndPlace返回的observation长这样:

{ 'observation': 当前机器人的关节角、速度、物体位置等, 'achieved_goal': 当前物体实际位置, 'desired_goal': 本次episode希望物体到达的位置 }

HER操作目标时,实际上是在替换desired_goal这个字段,同时要让achieved_goal保持原样。很多刚上手的人容易在这里犯糊涂,看到obs是一个dict就不知道该把新目标放哪,结果reward和状态对不上。

奖励函数方面,HER并不挑食。你既可以用稀疏二值奖励(达到目标给0,否则给-1),也可以用dense的距离奖励。我的经验是:HER在稀疏奖励下提升效果最明显,因为它的核心能力就是变相制造正样本。如果你已经用了dense奖励,HER也能带来增益,但幅度会小一些,因为原来的奖励里已经包含了可学习的梯度信号。

3.3 回放缓冲区的核心改动:连经验里的goal一起存

将HER集成到DDPG这类算法中时,最大的改动不在策略网络,而在回放缓冲区。

传统off-policy算法里,每个transition一般存五样东西:状态、动作、奖励、下一状态、是否终止。DDPG是(s_t, a_t, r_t, s_{t+1}, done)。但有了goal之后,每个transition还必须带上目标g。如果环境返回的是dict状态,那就要把这个dict整个存下来,或者至少把其中和goal相关的字段单独存一份。

我自己的做法是,buffer里每个条目存成:

transition = { 'obs': obs, 'action': action, 'reward': reward, 'next_obs': next_obs, 'done': done, 'goal': goal }

每次采样训练时,从buffer里随机抽一个batch,直接用其中的goal字段替换掉obs里的desired_goal字段,再送进Q网络和价值网络。这一点一定要提前设计好,否则后续重标注逻辑会越写越乱。

3.4 伪代码与关键实现细节

下面这段伪代码是我在项目里用的版本,可以直接照着改。

def her_relabel(episode, k=4, reward_fn=None): her_transitions = [] for t in range(len(episode) - 1): s_t, a_t, _, s_next, g_orig = episode[t] # 原始经验必须保留 her_transitions.append((s_t, a_t, reward_fn(s_next, g_orig), s_next, g_orig)) # 从未来k步中随机挑k个目标,生成虚拟经验 future_indices = np.random.randint( low=t + 1, high=min(t + 1 + k, len(episode)), size=k ) for idx in future_indices: g_new = episode[idx].state # 用未来某个状态替换目标 r_new = reward_fn(s_next, g_new) # 奖励必须重算 her_transitions.append((s_t, a_t, r_new, s_next, g_new)) return her_transitions

这里有三个细节值得专门说。

第一,reward_fn传入的第二参数是新目标g_new,不是原始目标。哪怕你觉得“奖励函数都一样”,也一定要显式地把新目标传进去,避免后面改奖励算法时踩坑。第二,future_indices是从t+1开始采的,不包括当前时间步t,因为当前状态已经被“达成”了,再拿它当目标没有信息量。第三,k的值决定虚拟经验膨胀倍数,k=4意味着每条真实经验会额外生成4条虚拟经验,buffer的有效大小变成原来的5倍,训练速度也会变慢,所以不要贪心。

3.5 超参数选择建议

关于目标重标注的那几个超参数,我直接给出实战配置,不绕弯子。

k默认4,建议不要大于8。k越大,虚拟目标覆盖的未来状态越多,但计算量和存储占用也线性上涨,而且过远的未来状态作为目标会引入很大的噪声。目标来源混合比例方面,我上面提过50% future、25% episode、25%原始目标,这是一个相对稳的组合。如果任务目标空间很大,可以把episode比例提高到三分之一,增加目标覆盖度。

探索噪声也要特别注意。DDPG本身需要在动作上叠加OU噪声或高斯噪声。加了HER之后,如果噪声过小,策略每次都访问相似状态,虚拟目标多样性不足,HER效果就会打折扣;如果噪声过大,机器人动作抖动太厉害,环境动态信息被破坏,同样影响学习。我的经验是在训练前5000步用较大噪声配合随机初始化,之后逐步衰减到比较小的稳态值。

4. 避坑指南:HER实战中常见的六个坑与排查思路

4.1 训练完全没起色:先查这四处

我见过太多人跑HER第一版代码,训练几万步奖励纹丝不动,然后怀疑算法有问题。实际上90%的情况是代码实现细节出了错。

最先要查的是奖励有没有用新目标重算。这是个极其隐蔽的bug:你只是在原经验后面追加了新目标,但reward还是原始目标下的reward,结果Q网络学到的目标-奖励对应关系完全错位,训练当然没起色。第二个要查的是obs里的目标字段有没有被正确替换。尤其当obs是dict结构时,你可能只换了desired_goal,却忘了把achieved_goal同步成新目标对应的状态。第三个要查的是虚拟经验有没有真正进入训练采样流程。很多人把her_relabel写好了,但训练时从buffer里采的还是原始经验,HER等于没接上。第四个要查的是目标归一化。如果目标坐标范围很大(比如0到10),而Q网络输入没有做归一化,同样会影响收敛。

4.2 虚拟目标分布偏移:原目标反而变差

这是HER最典型的问题:训练结束后,策略在虚拟目标上表现很好,但换回真实目标分布,成功率却不理想。原因也很直接——如果回放缓冲区里90%都是虚拟经验,目标分布就和真实任务的目标分布产生了偏移,策略被“带偏”了。

解法不复杂:训练时保留足够比例的真实目标经验。我前面说的25%原始目标比例就是这个用意。如果你想更精细一点,可以按训练进度动态调整虚拟经验比例:早期多放虚拟经验加速学习,后期逐步增加原始目标比例,让策略回归真实任务分布。

4.3 episode达到目标后立刻终止的处理

很多环境的episode会在“达到目标”时立刻终止。这时候HER仍然可用,但要注意:如果终止条件是“状态进入目标附近区域”,那最后一步的next_state本身就是目标状态,用它来做future目标非常合适,几乎等价于final策略。但如果终止条件里还包含时间上限,比如“最大步数500”,那你得确保future_indices不会越界,伪代码里那个min(t+1+k, len(episode))就是干这个的。

4.4 探索不足导致虚拟目标太集中

这个问题比较隐蔽,表现是训练中段奖励曲线涨得不错,但后期卡住不动。原因往往是探索噪声衰减太快,策略过早固化,后续episode访问的状态空间变小,虚拟目标都集中在少数区域,样本多样性下降。

我踩过这个坑之后的做法是:把探索噪声的衰减周期拉长到训练总步数的60%以上,同时每隔一段时间重新初始化一部分随机策略用来做探索。或者在训练初期刻意提高随机目标的比例,哪怕这些随机目标暂时完不成,也能让策略多接触不同状态。

4.5 问题速查表

症状可能原因排查方向
训练完全无提升虚拟经验未进入采样流程检查buffer里是否有g_new字段
奖励曲线乱跳reward没有基于新目标重算检查her_relabel第3行
真实目标任务表现差虚拟目标占比过高增加原始目标经验比例
中后期提升停滞探索噪声衰减过快拉长噪声衰减周期
目标空间大但训练慢k取值过大/目标未归一化减小k,加入归一化层
状态是dict结构但报维度错目标字段替换不完整核对achieved_goal和desired_goal

4.6 我个人的实战心得

把HER真正调到好用,我个人的体会是:不要把它当成一个黑盒组件直接挂上去,而是要先想清楚“目标空间是什么、经验怎么存、奖励怎么算”这三件事。HER本身不复杂,复杂的是它和现有代码的衔接。只要你把目标字段、奖励重算、虚拟经验进入训练这三条链路打通,剩下的就只是超参数调试。

我最早跑FetchPush任务的时候,用普通DDPG训练了将近两百万步,成功率一直在个位数徘徊,整个项目几乎要放弃。后来把HER接进去,同样的网络结构、同样的步数,成功率直接翻了好几倍,那种“柳暗花明”的感觉我到现在还记得。这也是我为什么愿意花这么多篇幅去写这个看似简单的技术——它的实现代码可能不到五十行,但对一个RL项目的影响往往是决定性的。

如果你准备在自己项目里尝试HER,最后再分享一个小技巧:先从现有的Gym Robotics环境跑通一个baseline,确认你的HER实现没问题,再迁移到自己的定制任务上。这样遇到问题时你就知道是环境问题还是算法集成问题,排查起来会省掉一大半时间。希望这篇内容能帮你少踩几个坑,早点看到那条漂亮的奖励曲线抬头的瞬间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 4:24:32

Univer 在线表格引擎实战:Canvas 渲染与 Facade API 集成指南

1. Univer 到底是个什么东西,为什么值得单独拿出来聊第一次听到 Univer 这个名字,很多人会以为是某个新出的前端框架或者 UI 组件库。其实不是。Univer 是一套开源的在线电子表格与文档协作引擎,核心定位是让开发者能把“类 Excel”“类 Goog…

作者头像 李华
网站建设 2026/9/30 4:23:15

PHP+uniapp实战:本地生活服务平台开发全流程与踩坑记录

最近在做一个本地生活类的信息服务平台,技术选型是php uniapp,面向城市商铺分类信息、活动发布与展示这类场景,最终产物要覆盖微信小程序和移动端 App。这个组合乍一看不算新潮,但跑完整个开发、打包、上架、适配流程之后&#x…

作者头像 李华
网站建设 2026/9/30 4:22:38

Redis安装部署指南:Windows与Linux从零到生产级配置

1. 写在安装之前做后端开发的,只要项目里用到缓存、session共享、排行榜或者消息队列,Redis基本是绕不开的那一个。不管你用的是Spring Boot、Express还是Gin,Redis装不好,后面写再多代码也跑不起来。这篇文章要解决的就是这个问题…

作者头像 李华
网站建设 2026/9/30 4:21:37

VMware Tools在Ubuntu虚拟机中的安装与问题排查指南

1. 为什么装完Ubuntu虚拟机,一定要先处理VMware Tools先问一句最实在的:你刚装完Ubuntu虚拟机的时候,是不是觉得鼠标怎么都出不了窗口边界?分辨率怎么调都嫌别扭?想把Windows里的文件拖进Ubuntu,直接被系统…

作者头像 李华
网站建设 2026/9/30 4:21:32

基于Next.js的个人IP内容矩阵系统实战

做个人IP最痛苦的事情,不是写不出内容,而是内容生产全靠脑子记、流程全靠人肉盯。公众号写一篇,小红书要改一版,抖音要再拆成短视频脚本,知乎还得整理成问答体,这些改版、排期、素材存档、平台数据回收&…

作者头像 李华