强化学习HER算法:目标重标注如何让机器人从失败中学会成功
发布时间:2026/10/2 3:51:50来源:尧图网络
标题 hindsight 光看单词很多人第一反应是后见之明事后诸葛觉得这是一篇讲复盘方法论的鸡汤文。但如果你常逛机器学习社区就会知道这个词在研究者眼里还有另一层身份——Hindsight Experience Replay后见之明经验回放简称 HER一个让机器人从失败里硬学出成功经验的强化学习算法。我这次想聊的就是这个既朴素又反直觉的技术。它解决了强化学习里最让人头疼的稀疏奖励问题让智能体在没有明确奖励信号的情况下照样能学会复杂操作。无论你是刚入门强化学习的初学者还是正在调试机器人抓取任务的工程师这篇文章都能给你讲清楚 HER 的来龙去脉、核心机制、代码实现以及我在实际复现中踩过的那些坑。1. 从事后诸葛到机器学习hindsight 到底解决了什么问题1.1 稀疏奖励问题机器人为什么学不会抓取先看一个最常见的场景你让一个机械臂去抓取桌面上的水杯初始位置离杯子还有一段距离。强化学习的逻辑是让智能体通过试错来学习策略但如果它每次尝试都碰不到杯子环境就永远不给奖励智能体收到的反馈全是一串零。奖励全是零意味着什么意味着梯度信息是零策略更新完全失去了方向。这就像让一个从没摸过篮球的人闭着眼睛投篮教练只告诉进了算赢没进算输但从不告诉他球偏左了力道小了。几万次尝试下来他可能连篮筐在哪都不知道。这就是稀疏奖励问题的核心困境——环境提供的反馈太少太晚智能体根本无法建立起行为→结果的因果链。在开源社区里OpenAI Gym 的 Fetch 系列环境就是专门用来测试这类任务的基准。FetchReach 要求机械臂末端移动到目标点FetchPickAndPlace 要求抓取并移动物体FetchPush 要求推动物体到指定位置。这些任务最大的特点就是奖励信号极度稀疏——只有机械臂末端与目标点的距离小于某个阈值通常 0.05 米时才给奖励。如果靠纯随机探索成功率低得令人发指训练曲线基本是一条贴着零的横线。1.2 HER 的核心直觉失败也能成为学习素材HER 的出发点其实是一个特别简单的反问目标没达成这局就真的白玩了吗想象一下你让小朋友练习投篮他这次投偏了球砸在篮板上弹回来。如果只看投进没投进这个目标这是一次失败但如果把目标改成让球碰到篮板他确实做到了。于是你可以对他说你看你刚才成功碰到了篮板下次试着让球擦着篮板边缘进去。——这就是目标重标注goal relabeling的思想。HER 把这个逻辑搬到了强化学习里。它允许一条失败的轨迹在回放时被重新解释为成功。具体做法是把轨迹中某一个实际达到的状态比如机械臂末端到达的位置替换成原始目标然后重新计算奖励。原本奖励全是零的一条轨迹经过重标注后后半段就变成了达成新目标的成功轨迹奖励有了梯度有了策略也就有了前进的方向。这背后的数学直觉非常优美在二进制的稀疏奖励设定下任何轨迹只要把目标改成它实际到达的状态这条轨迹在回放时就是一条中间过程有奖励的信号。智能体实际上是在用自己走过的路径来反推什么样的目标是可以达成的从而逐渐学会把当前状态映射到可达成目标的分布。有人说这是把失败的价值榨干到最后一滴我深以为然。1.3 适用场景与选型判断HER 不是万金油它适用的场景有几个明显特征目标空间容易定义通常是连续向量比如位姿、坐标奖励函数是稀疏的二进制或阈值型而不是稠密的距离惩罚环境具备最终状态是否达成目标的判定能力。举个例子如果你在做自动驾驶的路径规划目标是让车辆到达某个坐标点HER 可以用如果你在训练一个对话机器人目标难以形式化成向量、也没有明确的达成判定HER 基本没法直接用。模型需要从零开始学习目标达成分布这本身的知识表示就决定了方案的可行性。我在实际选型时有个经验如果一个任务你能明显感觉到人类解决它主要靠经验直觉而不是靠逐步规划那 HER 大概率比普通强化学习更适合。因为 HER 的本质就是让智能体从自身经历中总结什么样的状态组合是容易达成的天然贴近直觉型学习方法。2. 核心机制拆解目标重标注是怎么实现的2.1 从轨迹到新目标重标注策略的四种选择HER 论文里提出了四种从轨迹中选择新目标的策略它们的区别决定了训练效果的上限。第一种是 final直接选取轨迹的最终状态作为新目标。这是最符合直觉的做法——这局玩砸了但终点状态确实被达成了。第二种是 future从当前时刻之后的时间步里随机选取 k 个状态作为新目标。第三种是 episode从整条轨迹的所有状态里随机选取 k 个状态。第四种是 random从所有已见过的状态里选。论文报告的结果是 future 策略在大多数任务上表现最好。原因很直观future 选取的是从当前时刻往后某个状态这保证了轨迹中至少存在一段从当前状态到目标状态的连续段这段连续段就相当于一条怎么从 A 到 B的演示。episode 策略有可能选中当前时刻之前的状态导致回放时出现从 B 向 A 倒退的误导信号random 策略选的状态可能和当前轨迹完全无关学习效率更低。我自己的复现体验也验证了这一点FetchPickAndPlace 任务上future 策略配 k4 时训练 100 万步成功率能到 80% 左右换用 episode 策略同样步数下成功率会掉到 50% 上下。这个差距非常明显。2.2 二进制奖励函数与后续目标分布HER 对奖励函数的要求很严格它需要奖励函数能基于状态和目标直接判定成功与否而不能依赖执行过程中的中间反馈。以 FetchReach 为例标准的稀疏奖励是当机械臂末端与目标的欧氏距离小于 0.05 时给一个额外奖励否则每步给 0。重标注之后原本一条 50 步的零奖励轨迹会被改造成一条前半段零奖励、后半段逐渐靠近新目标的递增奖励轨迹。关键在于新目标不是随机挑的而是从轨迹里实际到达的状态里选的所以重标注后的轨迹天然满足奖励函数对目标可判别的要求。这里有个容易踩坑的细节重标注的时候要重新计算整条轨迹里每个时刻的奖励而不是只改最后一步。因为新目标确定后中间每一步是否达到目标的判定都可能变化。比如新目标是轨迹第 20 步的状态那第 30 步时机械臂可能已经超前经过了目标位置附近这一步在原轨迹里是零奖励但换到新目标下应该给奖励。如果只重算最后一步信息损失很大。2.3 为什么随机采样一个未来状态最具代表性有人会问既然 future 策略这么好为什么不直接取终点状态相当于 final问题在于一条轨迹只有 50 步如果每次都用 final 重标注新目标全是轨迹终点目标分布就会过度集中在那些易于到达的远端位置导致策略对中间区域的目标越来越不敏感。future 策略的随机采样 v/s final 的定点采样好比你在练投篮时不仅要练习投进框里这一个目标还要随机练习打到篮板左角碰到篮筐前沿这些子目标训练出的动作才更全面。具体实现时k 值每个状态采样几个未来目标通常取 4 或 8。k 太小目标多样性不足k 太大回放缓冲区里重标注样本占比过高会稀释原始经验训练初期容易震荡。我在 Fetch 系列任务上对比过 k1、4、8 三组k4 的时候训练曲线最平滑k8 时前期容易过拟合到达成目标这个分布上k1 时学习速度又太慢。推荐从 k4 起步稳定后再调整。3. 从论文到代码HER 的完整实操实现3.1 一个可以跑的 HER 伪代码框架论文的核心算法流程用伪代码写出来其实不到 30 行# HER off-policy 算法以 DDPG 为例 for episode in range(total_episodes): # 采样一个目标 g g sample_goal() # 执行 rollout记录轨迹 s_0, s_1, ..., s_T trajectory [] state env.reset() for t in range(max_steps): action policy(state, g) noise next_state, reward, done, _ env.step(action) trajectory.append((state, action, reward, g, done)) state next_state if done: break # 把原始轨迹存进回放缓冲区 replay_buffer.add(trajectory, use_relabelFalse) # 对轨迹做 HER 重标注再存一份 for state, action, _, _, _ in trajectory: for _ in range(k): future_state random.choice(trajectory[current_idx:]) new_goal future_state new_reward compute_reward(state, new_goal) replay_buffer.add((state, action, new_reward, new_goal, done)) # 从回放缓冲区采样更新策略 for _ in range(updates_per_episode): batch replay_buffer.sample(batch_size) update_policy(batch)这段伪代码的核心逻辑就是两条一是 rollout 按原目标执行二是回放时同时喂原始数据和重标注数据。原始数据保证策略不会偏离真实任务重标注数据提供学习信号两者缺一不可。3.2 环境配置与关键参数选择我用的是 Gym 的 FetchReach-v1 环境搭配开源的 Stable-Baselines3 做基准对比再在它的基础上自己实现 HER 的逻辑。这个环境动作空间是 4 维末端 XYZ 位移加夹爪开合状态空间包含机械臂关节角、末端位置、目标位置和物体位置目标空间是 3 维坐标。几个关键超参数我给出我在训练中最终采用的取值和理由参数我的取值选择理由回放缓冲区大小10^6必须足够大容纳多种重标注轨迹否则目标分布不稳定每次 episode 后的更新次数40太少学不动太多会让策略过度拟合最近经验每状态重标注目标数 k4如上文分析k4 在多样性和稳定性之间最佳批量大小256大批量能平滑重标注引入的噪声训练总步数100 万Fetch 系列在这个量级能稳定收敛太少不够用超参数这块我强烈建议不要直接照抄论文因为论文的环境版本、随机种子、网络初始化都和你本地跑的有差异。以批量大小为例论文用的是 128我在某些环境下调到 256 后曲线更稳但显存占用也上去了。先按上表跑通再根据你的实际情况微调。3.3 与 DDPG/DQN 结合时的接口改造HER 本身是一个经验回放机制的改造方案不依赖具体的策略梯度算法所以在代码里它和底层算法的耦合点其实只有一个——经验样本的存储格式。标准 DDPG 存储的是状态、动作、奖励、下一状态、目标、是否终止HER 要做的就是把目标这个通道开放出来。在实际工程里我最常遇到的一个问题是很多人把重标注逻辑写在了 rollout 阶段也就是智能体还在环境里跑的时候就去改目标这会导致探索方向被污染策略学出来的行为全是为了达成临时改的目标而不是在尝试达成真实目标。正确的做法是rollout 全程用固定目标执行重标注只发生在数据回放阶段。这是 HER 实现里最容易错也最致命的一个点。另一个工程细节是向量化。现代强化学习框架通常用 vectorized env 并行跑多个环境但 HER 的重标注逻辑依赖于单条完整轨迹的概念多个环境的数据会混在一起所以要么自己维护轨迹缓冲要么在采样后按环境 ID 分离数据。我在实现时直接用字典结构存储每个环境的轨迹按 env_id 索引采样完成后按轨迹维度做重标注这样不破坏向量化带来的吞吐量优势。3.4 一个极简的 reward 函数重标注示例为了让你直观感受重标注的代码实现这里给一个简化版本import numpy as np def compute_reward(achieved_goal, desired_goal, threshold0.05): # 稀疏奖励距离小于阈值 1否则 0 distance np.linalg.norm(achieved_goal - desired_goal) return 1.0 if distance threshold else 0.0 def relabel_trajectory(trajectory, k4): relabeled [] T len(trajectory) for t, (state, action, _, _) in enumerate(trajectory): # 从当前时刻之后随机选 k 个状态作为新目标 future_indices np.random.choice( np.arange(t, T), sizek, replaceFalse ) for idx in future_indices: new_goal trajectory[idx][0][:3] # 取状态里的 XYZ 作为新目标 new_reward compute_reward(state[:3], new_goal) relabeled.append((state, action, new_reward, new_goal)) return relabeled这个示例里的 [0][:3] 来自状态向量与目标向量的维度约定实际项目中你需要根据环境的 observation 定义调整索引位置。写重标注函数时最容易犯的错就是目标向量索引取错导致重标注后目标和状态根本不是同一个坐标系下的东西训练直接发散。建议在实现后先打印几条重标注样本人工检查一下状态实际位置和重标注目标的距离计算是否合理。4. 训练效果与调试实录4.1 成功率曲线到底该长什么样以 FetchReach 为例我用 HERDDPG 训练了 100 万步前 20 万步成功率几乎是零曲线贴地30 万步左右开始出现零星的成功50 万步时曲线斜率突然变陡成功率跳到 60%80 万步以后稳定在 95% 以上。这个突跃现象很有意思。它不是逐步爬坡而是突然起飞。原因是 HER 重标注的数据在回放缓冲区里积累到一定比例后策略对如何达成目标的泛化能力产生了质变。这就像学生做题大量刷了不同类型的题目之后某一天突然开窍碰到新题也知道怎么解了。如果你训练时发现曲线一直贴地先别急着加训练步数重点检查两件事一是重标注的目标是否正确写入了回放缓冲区二是奖励函数对重标注目标计算时是否还在用原始目标而不是新目标。后一种 bug 在代码合并时特别常见我至少犯过两次。4.2 三个高频坑目标分布偏移、reward hacking、复现性第一个坑是目标分布偏移。HER 重标注会把目标分布逐渐拉向智能体经常访问的状态如果初始策略质量很差经常访问的状态都是一小片区域重标注的目标就会大量集中在这片小区域里导致策略陷入局部最优——它能达成所有重标定目标但对真实目标毫无感知。我的解决方法是给重标定目标加一个优先级偏置让处于远离当前策略擅长区域的新目标采样概率更高这个技巧比单纯调大 k 值更有效。第二个坑是 reward hacking。在 FetchPush 任务里重标注目标是物体到达位置 A但智能体可能学会先把物体推到墙角因为墙角经常出现物体重标定目标在墙角分布密集推过去更容易达成目标。客观结果是训练指标上涨真实成功率没变。发现这个问题的办法是定期用原始目标做评估如果重标定成功率很高但原始目标成功率低下基本可以断定策略在钻重标定目标分布的漏洞。第三个坑是复现性。HER 的随机性来自三个层面环境随机化、目标采样、重标定目标采样。我在同样的超参数下跑三次三次曲线的波动差距能到 20%。这不是代码有 bug而是高维稀疏奖励任务的固有方差。解决办法是把随机种子、环境版本、重采样逻辑全部固定每次调参只改一个变量否则你根本不知道曲线变化是超参数引起的还是噪声引起的。4.3 调参心得幅度太大不如稳中求变关于调参我的建议是先复现、再微调、最后才创新。很多人拿到 HER 就想改成自己的版本结果连论文里的 baseline 都没跑通。我自己的经验是先把论文的原始配置跑通一遍确认项目设置、环境返回值、重标注机制三者正确然后只调一个超参数比如 k 值从 4 调到 8对比曲线差异再逐步增加改动。在 Fetch 系列环境上有一个值得注意的参数是 update_ratio每次 rollout 后更新策略的次数。很多人把这个值调得过大以为学得更快结果策略更新过密经验回放缓冲区还没存够多样化的轨迹策略就开始震荡。我推荐的初始值是 40:140 次更新对应 1 条 episode稳定后可以尝试 20:1 或 80:1但别一上来就跳到 80。5. 从机器人到现实世界hindsight 的扩展应用路径5.1 多任务学习与课程学习的结合尝试HER 的思路天然适合多任务场景因为目标本身就是任务的定义。我最近在做一个多目标抓取实验机械臂要把不同物体放到不同区域每个物体区域组合就是一个任务。传统做法是训练多个策略成本高、管理难。用 HER 改造后把物体位置、目标区域编码进目标向量一个策略就能处理全部组合。重标定目标的多样性让策略在不同任务间自动共享经验一个任务的失败轨迹能转化为另一个任务的成功样本这种跨任务经验复用是普通强化学习很难做到的。课程学习领域也有类似思路——把 HER 的重标定目标当作自动课程生成器初期重标定目标集中在简单可达区域后期策略能力提升后重标定目标自然扩散到困难区域。这比我以前手写课程调度函数稳定得多因为课程不是人为设计的而是从策略自身经验里涌现出来的。5.2 离线强化学习与机器人训练中的变体在真实机器人上做强化学习收集数据的成本很高所以很多团队转向离线强化学习offline RL——用预先收集的数据集训练策略不再在线探索。我在调研时发现HER 的变体已经被用在了离线场景做法是把数据集里每条失败轨迹做目标重标注生成大量达成各种目标的经验用在线的低质量行为策略来生成数据也能训练出可观的成功率。这个场景有个额外的挑战离线数据的覆盖度不够时重标定目标可能落在数据分布之外的区域。解决办法是加一层密度约束只选择那些在数据集附近有足够支撑的轨迹状态作为新目标避免策略去追求真实世界根本达不到的目标。如果你打算把 HER 扩展到真实机器人先在小规模仿真环境里做 domain randomization随机化物理参数、初始位置、光照等确保策略对参数扰动鲁棒再迁移到真实硬件上微调。仿真和现实的 gap 是真实机器人训练最大的坑HER 不背这个锅但它也救不了毫无鲁棒性的策略。5.3 把 hindsight 用在团队管理和学习方法上这里说点题外的但真实的想法。我自己在带项目时发现后见之明这套思维方式对团队也很适用——每次 sprint 结束那些没达成的目标如果只按失败归档团队只会越来越沮丧但换一个角度把没达成的目标重标定为我们实际完成了什么记录为什么做到这里而不是那里下一次规划时目标分布就合理得多。这和 HER 的目标重标定几乎是同一个逻辑不要把失败当作无用数据丢掉把它当作你能更接近目标的信号。技术上的后见之明和生活中的后见之明底层原理都是同一件事从已经发生的事实里提取可复用的判断依据而不是用早知道来否定自己。算法如此人也是如此。这大概也是这个标题最打动我的地方。最后再分享一个小技巧如果你也想在本地复现 HER建议从 OpenAI Baselines 的 her 实现入手它在仓库里单独维护了一个 her.py逻辑相对清晰。先跑通 FetchReach再换 FetchPush。等这两个任务都稳定收敛后再考虑自己写重标注逻辑也不迟。复现阶段少踩一个坑后面省下的调试时间远远超过你最初花在这一个步骤上的十几分钟。
网站建设高端定制企业官网