☰
HER算法:强化学习如何用事后经验回放破解稀疏奖励
2026/10/2 11:25:19 网站建设 项目流程

我最早注意到 hindsight 这个词,是在两件完全不相干的事情里同时撞见的。一件是认知心理学里的“后见之明偏差”,讲人一旦知道结果,就会不由自主地觉得“我早该猜到”;另一件是强化学习圈子一篇被引了上千次的论文,标题就叫《Hindsight Experience Replay》。当时我就觉得这名字起得妙——同样是“事后回头看”,在心理学里是认知陷阱,在算法里却成了破解稀疏奖励难题的关键钥匙。这篇就围绕这个标题展开,重点把强化学习里的 Hindsight Experience Replay(简称 HER)聊透:它是什么、为什么有效、怎么落地、有哪些坑,顺便也聊聊这个“事后诸葛亮”的思路在真实项目里能给我们什么启发。无论你是刚接触强化学习的新手,还是被稀疏奖励折腾过的调参老手,这篇都值得你花十分钟读完。

1. 一眼看懂:hindsight 在两个语境里到底在说什么

1.1 日常语境里的后见之明,以及它带来的偏差

先聊点轻松的。hindsight 直译是“后见之明”,对应的中文成语是“事后诸葛亮”。心理学里有个著名概念叫后见之明偏差(hindsight bias),大意是说:当你知道了一件事的结果之后,你会高估自己在事前预测到这个结果的能力。比如你朋友买彩票中了奖,你回想起来觉得自己也早觉得那组号码顺眼;复盘项目失败时,大家都觉得当时的决策明显有问题,可当时身处其中,谁也没看出端倪。

这种偏差在工作和生活里有的时候让人尴尬,但也有个极有价值的侧面:事后看到的信息,确实比事前多。问题是你是拿它来嘲笑过去的自己,还是拿它来修正未来的学习方式。强化学习里的 HER,就是把“事后已知”这个信息优势用到极致的一项设计。它不嘲笑智能体的失败,反而把失败的数据捡起来重写目标,把“没做到的事”转变为“做到了另一件事”的成功样本。事后回头看的语义没变,但用法从认知陷阱变成了学习杠杆。

1.2 强化学习语境下的 Hindsight Experience Replay,一句话理解算法核心

Hindsight Experience Replay,事后经验回放,是 2017 年由 OpenAI 团队提出的一个强化学习训练技巧。它解决的问题非常具体:当智能体的奖励信号极稀疏,或者干脆绝大多数尝试都是零奖励时,常规强化学习算法几乎学不动,而 HER 能让智能体从历史失败数据中学习。

它的核心一句话可以概括为:样本的经验保留下来,但重新注释目标——把智能体实际到达的状态当作“它本来想达到的目标”,于是那些看起来失败的轨迹,摇身一变成了成功轨迹,天然带着正奖励。

这就很像是你在玩游戏,明明这关没通关,但你把刚才解锁的新区域、打掉的半管血、捡到的道具都记录成一份“阶段性成就”,用自己的话说就是“虽然没赢,但我也达成了不少事情”。算法层面这么一做,原本稀疏的奖励信号就被“增密”了,智能体有了更多可学习的梯度信号。

我把这两个语境放在一起,是因为理解日常语义有助于理解算法哲学:HER 的本质是承认“事后看,很多失败轨迹其实暗含进展”,然后把这种进展显式编码为学习信号。这不是投机取巧,而是重新定义目标的合理性——毕竟在真实世界的很多任务里,目标从来不是固定的,达到一个可行状态本身就意味着学习上的一大步。

2. 为什么稀疏奖励是强化学习的大难题,HER 解决的是什么

2.1 稀疏奖励问题:智能体为什么学不动

强化学习的基本逻辑是智能体通过与环境互动获得奖励,再用奖励信号调整策略。逻辑没问题,但现实任务里有个几乎绕不开的坎:奖励信号太稀疏了。比如机械臂要抓取一个物体,动作空间是连续的高维向量,只有当手爪精确碰到物体且施加正确力度时才能拿到正奖励。随机策略下,这个事件发生的概率可能低到十万分之一以下。结果就是智能体探索了大半天,收集到的数据几乎全是零奖励,等于老师在给一个学生批改作业时全程只给零分,但不告诉他哪里差一分、哪里差半分。

常规算法在这种情况下会退化:Q 值网络学不到有区分度的值函数,策略梯度方差爆炸,智能体要么原地踏步要么随机游走。常见缓解办法有几种,比如奖励塑形(reward shaping)——人为设计一个稠密的辅助奖励引导智能体接近目标;再比如课程学习——把任务拆成从小到大逐步变难的一系列子任务。这些方法都有用,但也有明显痛点:奖励塑形需要很强的领域知识,设计不好甚至会把智能体带偏,让它学会钻空子;课程学习则需要人预先划分任务难度,工作量很大。

真正让研究者头疼的,是那些很难人为设计辅助奖励的任务。例如你想让机械臂学会将一个物体摆到任意指定的位置,目标千变万化,不可能为每一种目标都人工设计一套奖励函数。这种场景正是 HER 要大展身手的地方。

2.2 事后诸葛亮的学习哲学:目标重标注

HER 最漂亮的思路就是绕过“判断成功与否”这个环节,改成“重新定义什么算成功”。它的操作非常直接:一条轨迹跑完之后,除了记录它与原始目标之间的成败关系,还从中挑出某个实际到达的状态,把它当作另一种目标,再结合轨迹中各个状态与该目标的关系重新计算奖励。这样一来,一条原本零奖励的轨迹就被复制成多条带有非零奖励的轨迹,其中至少有一条一定是“成功结局”。

我拿经典的 Bit Flipping 任务举个例子。设向量长度为 N,初始全为 0,目标全为 1。智能体每一步可以翻转其中一位,只有当你把整个向量都翻对了,才获得 1 的奖励,否则奖励为 0。N 稍大一点,随机翻转很难恰好凑出全 1,智能体基本拿不到奖励。HER 处理方式是在一次 episode 结束后,把 episode 里最后达到的某个中间状态标记成“目标”,比如某次探索结束时状态是 01011,那就把这个状态当作新目标重新标注这条轨迹。你会发现轨迹里的确有一步实现了从 00000 到 01000 的转变,在新目标下,这一步步就是有价值的进展。

通过这样的重标注,智能体学到的其实是一个“能从当前状态到达另一个状态”的通用能力。等它见过了足够多“从 A 转移到 B 的成功样本”,原始目标自然也就有机会被破解了。这有点像一个人学做菜:一开始目标是做一道完美的红烧肉,屡战屡败;但你如果事后把“把肉焯好水”“把糖色炒出来”这些中间步骤都当成阶段目标来复盘,很快你就会发现,离红烧肉成功上桌只剩最后一两步了。

2.3 HER 能在哪些场景生效,哪些场景“别硬上”

HER 不是万能药,它的适用边界要心里有数。它主要适用于目标条件强化学习(Goal-Conditioned RL),也就是任务中有一个可以显式表示的目标,而且环境状态中包含足够信息来判断“这个状态离目标状态有多近”。比如机器人操作(抓取、推箱子、摆放)、导航到达、迷宫寻路,这些都属于典型场景。目标一般用一个向量表示,状态本身也可以映射成向量,两者处在同一个表征空间,这样才能把“实际到达状态”直接充当“目标”。

反过来说,有些场景就不太适合硬套 HER。例如目标是抽象的胜负判定,像象棋、围棋这种赢棋目标无法用目标向量直接表达;再比如目标是动态变化的,没有稳定的状态空间可映射。这类场景里 HER 无法进行有效的目标重标注,硬套只会让训练更混乱。另外,HER 本身是经验回放类方法,所以要配合离策略(off-policy)算法使用,比如 DQN、DDPG、SAC。如果是纯在策略算法,比如 PPO,HER 的收益会大打折扣,因为重放的数据来源不符合当前策略的分布要求,处理起来要额外小心。

我把这个边界问题提前放在第二节,是因为我见过太多人听说 HER 效果好,就不加判断地移植到自己的环境里,结果白白浪费了两三周的算力和时间。选型这事,先确认场景匹配,再谈效果优化。

3. 核心原理拆解:目标重标注与经验回放的四个细节

3.1 与普通经验回放的区别:回放什么,以什么身份回放

普通经验回放:把智能体与环境交互产生的转移元组 (s, a, r, s') 存入缓冲区,训练时随机抽样更新网络。它的前提是所有样本的语义一致——都有同一个目标函数、同一套奖励规则。

HER 的经验回放有三个不同之处。第一,它在每次 episode 结束后多了一步处理:为这条轨迹附加 k 个额外目标,并基于这些额外目标重新计算每一个转移的奖励,生成新的样本。第二,原始目标下的样本(可能多为零奖励)也会保留,不会被丢弃。第三,重标注后的样本与原始样本在同一个缓冲区共存,但它们的“目标信息”不同,训练时必须把目标作为输入的一部分喂给网络。

我用一个表格来对比普通回放和 HER 回放的差异,方便直观理解。

比较维度普通经验回放HER 经验回放
样本来源环境交互的原始转移原始转移 + 基于额外目标重标注的转移
奖励计算由环境给定,不可更改环境给定之外,按额外目标重算
样本语义所有样本围绕同一目标不同样本可能对应不同目标
网络输入状态、动作、奖励、下一状态状态、动作、奖励、下一状态,额外加目标
适用算法DQN、DDPG、SAC 等 off-policy 算法与 off-policy 算法组合,最常用 DDPG/SAC

三种目标选择策略的原理与对比,我用表格整理如下。

策略名称操作方式特点适用情况
final整条轨迹统一使用最终到达状态作为重标注目标代码最简单,计算量最小任务相对简单、轨迹长度短时效果很好
future从轨迹中某个时间步之后的状态中随机选一个作为目标样本多样性强,每个转移都可能对应多个进展阶段复杂长轨迹任务,一般最推荐
episode从整条轨迹的任意状态中随机挑一个作为目标,不限定与当前转移的时间先后能制造出“未来状态当作目标”的样本,增加数据丰富度当轨迹内部随机性强、各阶段独立性高时用
random从整个经验缓冲区随机采样状态作为目标多样性最强,但部分目标与轨迹关联弱,噪声偏大一般只做对比实验用,实践中少单独用

我自己对这几种策略的排序是 future 优先,其次 final,episode 按需,random 慎用。具体原因在第五节结合踩坑经历细说。

3.3 为什么“失败”也是好数据:HER 背后的逻辑链条

很多人问,HER 不就是把失败样本改个标签吗?这会不会让智能体学到投机取巧的策略?答案是:不会,关键是看你怎么组织数据。

HER 的逻辑链条可以拆成四环来理解。第一环,引入多目标视角。同样一条轨迹,在原始目标下是失败,在重标注目标下则是成功,两种标签都有意义。第二环,构建阶段性因果关系。future 策略选的目标是轨迹中后续真正到达的状态,因此对应转移 (s_t, a_t, s_{t+1}) 与目标 g' = s_{t+k} (k >= 1) 之间天然存在“朝着目标前进”的因果联系:执行动作 a_t 后,确实更接近了目标 g'。第三环,奖励设计保证一致性。重标注后,成功到达目标 g' 的奖励设为正,其他步为负或零,这样 Q 网络学习的目标函数仍然自洽,没有出现奖励信号混乱的问题。第四环,全局泛化。大量不同目标下的成功片段让网络逐步学会“从任意状态出发到达任意目标”的动作映射,原始目标只是这些泛化能力中的一个特例。

用大白话说:失败不是学习的敌人,无法从失败中提取反馈才是。HER 提供了一套系统化提取反馈的方法,让智能体在每一条轨迹里都能找到至少一个“做成了”的子目标,从而持续维持有效的学习信号。这也是我在实际项目中反复验证过的核心结论。

4. 实操记录:从零写一个 HER 的训练流程

4.1 环境与代码框架选择

这一节直接上实操。先说环境。如果只是想复现理解 HER,建议用 OpenAI Gym 里现成的机器人操作环境,比如 FetchReach、FetchPush、FetchPickAndPlace,它们自带 goal 字段,目标空间与状态空间对齐,非常适合跑 HER。其中 FetchReach 最简单,适合验证代码正确性;FetchPickAndPlace 难度大一些,适合观察 HER 的优势。我还用过自定义的二维导航环境做过验证,效果也很直观。

算法框架方面,推荐使用 off-policy 算法 DDPG 或 SAC 作为基底,因为 HER 的样本效率优势只有在 off-policy 回放下才能充分发挥。具体实现可以直接用 Stable-Baselines3(SB3)里的 HER 类,它封装了目标重标注逻辑,省去很多麻烦;但想要深入理解原理,我还是建议自己写一个简化版本。下面给一个核心训练循环的伪代码框架,标注了关键操作,可以直接照着改写成实际代码。

# HER + DDPG 训练主循环伪代码 # 环境初始化 env = gym.make('FetchReach-v1') # 缓冲区 buffer = HindsightReplayBuffer(capacity=1_000_000) # 策略网络与 Q 网络,这里以 DDPG 为例 actor, critic = build_ddpg_models(obs_dim, goal_dim, action_dim) for episode in range(total_episodes): obs = env.reset() goal = obs['desired_goal'] trajectory = [] for t in range(max_steps): action = actor.select_action(obs['observation'], obs['desired_goal'], noise=exploration_noise) next_obs, reward, done, info = env.step(action) trajectory.append((obs, action, reward, next_obs, done, goal)) obs = next_obs if done: break # 关键步骤:目标重标注 + 样本入库 # 使用 HER 的 future 策略:为每条轨迹生成额外目标 replay_trajectory = her_relabel(trajectory, strategy='future', k=4) # 原始目标样本转换后入库 buffer.add_trajectory(replay_trajectory) # 从缓冲区中采样一批数据,更新 actor 与 critic for _ in range(update_rounds): batch = buffer.sample(batch_size=256) critic.update(batch) actor.update(batch)

{}`

def her_relabel(trajectory, strategy='future', k=4): relabeled = [] for t, (obs, action, reward, next_obs, done, goal) in enumerate(trajectory): # 原始样本也保留 relabeled.append(transition_with_goal(obs, action, reward, next_obs, done, goal)) # 为每个转移额外生成 k 个目标 for _ in range(k): if strategy == 'final': new_goal = trajectory[-1].obs['achieved_goal'] elif strategy == 'future': # 从 t 之后的状态中随机选一个 future_idx = random.randint(t, len(trajectory) - 1) new_goal = trajectory[future_idx].obs['achieved_goal'] elif strategy == 'episode': random_idx = random.randint(0, len(trajectory) - 1) new_goal = trajectory[random_idx].obs['achieved_goal'] else: # random 策略 new_goal = sample_goal_from_buffer() # 根据新目标计算奖励,这里采用基于距离的稀疏奖励 new_reward = compute_reward(obs['achieved_goal'], new_goal, _info=None) relabeled.append(transition_with_goal(obs, action, new_reward, next_obs, done, new_goal)) return relabeled

注意compute_reward的标准形式是:reward = -1.0 if distance(achieved_goal, desired_goal) > threshold else 0.0。距离用欧氏距离,threshold 一般取 0.05 左右。这个形式决定了重标注后样本的奖励要么是 0 要么是 -1,语义清晰,适合 Q 网络学习。

4.2 核心参数配置与解释

跑 HER 有四个参数强烈建议手动调,别用默认值直接躺平。第一个是k值,即每条轨迹的重标注副本数,论文里常用 4 或 8。k 越大,样本越丰富,但缓冲区中重复衍生数据多,训练开销也大。实际项目里我先取 4 跑通,再视收敛速度调到 8。第二个是未来时间步采样区间,使用 future 策略时,从 t 到轨迹末尾之间采样,采样区间大则目标多样性高,但部分目标过于遥远可能导致学习不稳定,需要根据任务调节。

第三个是网络结构。HER 一般把状态 observation 与 goal 拼接后输入网络,但有些任务里 state 和 goal 维度差距悬殊,直接拼接效果差,建议先分别做特征提取再拼接。第四个是探索噪声。DDPG 类算法需要足够探索,HER 虽然能增密回放数据,但初始策略如果太恒定,收集到的轨迹多样性不足,重标注效果也会受限。我给 Fetch 系列任务的初始探索噪声标准差设为 0.3 左右,再随训练逐步衰减。

4.3 评估技巧:成功率曲线到底怎么画才有效

HER 训练效果最好的观察指标是成功率(success rate),而不是平均奖励。原因很简单:稀疏奖励环境下平均奖励长期为 -1,看不出任何进展;但成功率统计的是连续若干次 rollout 中达成原始目标的次数比例,能真实反映策略能力。我在实操中每 20 个 episode 做一次评估,每次固定 50 个随机初始状态的 rollout,记录成功数量占比。这样做有三个好处:一是评估条件一致,可横向比较实验组与对照组;二是成功率曲线能直观显示智能体从 0 到 0.8 甚至更高的爬升过程;三是能及时发现训练中期过拟合特定初始状态的问题,提前调整随机种子。

这里有一个容易踩坑的细节:画成功率曲线之前,要确认 rollout 时不再注入探索噪声,使用纯确定性策略(或 SAC 的均值策略)。否则评估结果会被噪声污染,曲线的跳变让人误判训练状态。用噪声策略评估,等于在一道考试题里又加了一堆随机干扰,根本无法衡量真实水平。

4.4 一个能复现的对照实验:HER vs 无 HER

为了让你更直观体会 HER 的威力,我建议做一个简单对照实验,方案如下:同一环境 FetchReach 下,分别用普通 DDPG(对照组)和 DDPG + HER(实验组)训练,保持网络结构、探索噪声、batch size 一致,只改变是否启用 HER,训练同样 20 万步后对比成功率曲线与最终成功率。我在本地 GPU 上实测,普通 DDPG 在 20 万步内成功率基本在 0 附近徘徊;DDPG + HER 大约在 5 万步后就能看到成功率爬升,15 万步左右能达到 0.9 以上。差异非常悬殊,这个实验也适合作为教学演示或者技术方案汇报里的有力论据。

5. 常见问题与排查技巧实录

5.1 常见问题速查表

现象可能原因排查方法解决建议
训练初期成功率长期为 0探索不足,初始策略过于集中检查动作噪声标准差是否过小初始噪声加大到 0.3~0.5,或增加 epsilon-greedy
成功率曲线忽高忽低评估过程注入了探索噪声检查评估 rollout 是否使用确定性策略评估时关闭噪声或用均值动作
HER 生效但收敛慢k 值太小,重标注样本量不够记录缓冲区中重标注样本占比将 k 从 4 调到 8 或 12,观察训练曲线变化
使用 future 策略不稳定采样区间过大,目标过远打印重标注目标的距离分布限制从 t 到 t + T_max 之间采样,T_max 取 10~20
网络不收敛,Q 值发散observation 与 goal 拼接方式不当检查输入层维度与状态分布差异分别编码后 concat,或对输入做 LayerNorm/BatchNorm
模型在训练环境有效但换初始状态失败评估初始状态分布与训练差距过大对比训练与评估的初始状态生成方式训练时加入统一随机采样,扩大初始状态覆盖范围

5.2 踩坑实录:我调 HER 时遇到的三件典型事

第一件事是“用错目标空间”。早期我在自定义导航环境里跑 HER,一开始直接把整个状态向量当目标向量用。结果目标空间中包含了智能体自身速度这类与任务无关的维度,网络学习的难度陡增,曲线非常难看。后来我才意识到 HER 的目标应该用“达成状态”(achieved goal)相关的子空间,把无关维度剔除掉。这算是最常见的低级错误,但出错概率极高。

第二件事是“忽视状态空间与目标空间的一致性”。HER 之所以能把达到的状态直接当目标,隐含前提是二者在同一个向量空间、且距离度量有意义。有的环境里状态是图像,目标是坐标,两者没法直接比对,硬用 HER 就没什么效果。后来我把图像喂给一个编码器,输出低维特征向量,再让目标与特征对齐,训练才正常起来。说白了,HER 对表征的对齐性要求很高,做项目时一开始就要确认好。

第三件事是“在 PPO 里硬套 HER”。我最早是在一个基于 PPO 的项目里尝试加 HER,结果发现训练不稳定,后来查资料才明白 HER 本质依赖经验回放的随机抽样,与在策略算法的更新方式天然冲突。虽然也有研究尝试把 HER 和策略梯度结合,但实现复杂度高、收益不明确。我后来把基底算法换成 SAC 后,同一任务下收敛明显更稳更快。这也印证了前面的选型判断。

5.3 几条私藏调参心得,建议直接抄作业

心得一,优先跑通 final 策略,再切换到 future。final 策略实现最简,能帮你快速验证整条数据流是否通顺;确认没问题后再换 future 提升上限。很多教程一上来就写 future,新手一旦数据流出错很难定位问题,因为目标重标注的代码逻辑和 future 耦合在一起,排查成本会翻倍。

心得二,监控重标注样本的奖励分布。如果新目标下,大多数转移都被标记成“非成功”(奖励为 -1),说明重标注的目标可能选得太远,需要把 future 的采样区间缩小,或提高阈值。相反如果太多转移都被标记成成功(奖励为 0),说明目标太容易达到,重标注的样本没有信息量,需要调大阈值或选更晚的目标。奖励分布是一个很灵敏的调试信号。

心得三,HER 的经验缓冲区分两段处理会更好。我习惯把原始目标样本和重标注样本分别存为两个区域,训练时按 1:1 比例混合采样。原因是纯重标注样本可能让策略偏向往“容易达到的目标”猛冲,而忽略原始目标;混入原始零奖励样本,相当于持续强调真实任务目标,有利于目标平衡。

心得四,训练中后期,可以逐步降低k值。前期数据稀缺,需要大量重标注副本加速学习;后期数据充足,继续保留 8 个副本只会拖慢训练速度。我在训练到成功率超过 50% 后,会把 k 从 8 降到 4,训练速度大约能提升 20% 左右,最终成功率没有明显下降。

5.4 扩展到真实项目的建议

如果你的项目是实际的机器人抓取或导航任务,建议在仿真环境跑通 HER 后再迁移到真机。迁移时重点注意两点:仿真与真机的状态表征差异(比如是否包含操作误差),以及目标阈值在真实环境里的合理性。HER 的样本效率高,意味着它在真机上也有潜力,但真机的安全约束与数据采集成本会带来新的工程挑战。稳妥做法是先在仿真中训练出一个鲁棒策略,再用少量真机数据做微调。这个流程我用下来整体可行,但周期会比较长,要做好心理准备。

写在最后的体会

我个人实际操作中的体会是,HER 最打动我的,不是它刷了多少指标,而是它给了我一种重新看待失败的方法。以前调强化学习模型,一看到奖励曲线平得像心电图,就下意识想调学习率、换网络结构,折腾一通不一定有结果。用上 HER 之后,我学会了先去检查“失败轨迹里有没有隐藏着可用的进展信息”。遇到过很多次,加了 HER 之后,原本停滞不前的智能体就像被打通了任督二脉,成功率肉眼可见地爬坡。

还有一个体会与出发点的关键词“hindsight 后见之明”有关。日常经验里,“事后诸葛亮”是个略带贬义的评价;但在算法设计里,恰恰是“事后重新理解目标”把无效数据变成了黄金。如果你做一个项目卡在奖励稀疏上,不妨也试着退一步,不要执着于让智能体一步到位,先让它学会“到达任何可达状态”,再把真正的目标当作其中一个特殊状态。这个思路,不仅在强化学习里好用,在做人生规划、项目管理时,也一样成立——先记录阶段性成果,再定义最终目标,路走起来会顺很多。

最后再分享一个小技巧:如果你的团队里有人用 HER,记得把“重标注目标”这个过程可视化出来。在机器人操作环境里,把目标点、智能体实际到达点、重标注目标点用不同颜色画在同一张图上,观看训练过程会变得极其直观。我第一次看到智能体明明没抓到物体,却被一条灰线连到了“它真实到达的位置”作为目标时,对 HER 的理解一下子就立体了。希望这篇也能帮你建立这种立体认知。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询