新闻详情

新闻详情

首页 / 资讯中心 / 详情

HER算法详解:用事后经验重标注解决稀疏奖励难题

发布时间:2026/10/2 11:29:08来源:尧图网络
HER算法详解:用事后经验重标注解决稀疏奖励难题
做强化学习的人多少都被“稀疏奖励”折磨过。训练几十万步奖励曲线纹丝不动agent像个无头苍蝇在环境里乱撞偶尔碰巧完成任务又很快忘掉。那段时间我反复看曲线、调参、加奖励塑形效果都很勉强,后来接触到 Hindsight Experience ReplayHER才算真正理解了“把失败当作另一种成功”这句话。这思路听起来有点反直觉但实测下来效果出奇地好尤其在机器人操作这类目标导向任务里样本效率能提升一个量级。这篇就来把HER的原理、实现和踩坑心得完整梳理一遍适合已经接触过DQN或DDPG、正在为稀疏奖励发愁的读者。1. 稀疏奖励困境与“事后视角”的灵感来源1.1 强化学习里最让人头疼的问题先还原一下典型场景。假设你想让一个机械臂学会“把方块推到指定位置”奖励函数很自然地设置成方块到达目标区域给1否则给0。这个设置简洁、符合直觉但实际训练时你会发现绝大多数episode里agent从头到尾都在随机试探一次正向奖励都拿不到。梯度信号为零价值网络完全学不到东西。奖励塑形是一种常见解法比如根据“方块与目标的距离”给一个连续惩罚让agent有梯度可循。但塑形函数的形状很难设计权重太大agent会钻漏洞比如绕圈子骗距离奖励权重太小又等于没有。另一种思路是课程学习先让agent学简单的目标再逐步加大难度。这个方法有效但需要人工设计课程还容易引入偏差。真正让我对HER产生兴趣的是它完全绕开了这些复杂设计用一种极简的思路就把稀疏奖励问题解决了大半。1.2 “事后视角”失败里其实藏着成功HER的核心想法来自一个很朴素的观察在一次episode中agent没能到达预定目标但如果把“它实际到达的位置”当作目标那么这个轨迹就是一条完美成功的演示。比如机械臂想把方块推到坐标A结果推到了坐标B。从原来的目标看这是一次失败但从“推到B”这个目标看这条轨迹全程都做对了。于是HER做了一件很简单的事在把轨迹存入经验回放池时额外生成几条“重标注”的版本把这些版本的目标改成轨迹中实际访问过的状态并用新目标重新计算奖励。这样一来原本奖励全为0的失败轨迹被转化成了一批带有正奖励的成功经验。强化学习算法就能从这些“事后看来成功了”的轨迹里学到东西不再依赖运气碰出的稀罕奖励。这个思路之所以有效是因为目标条件化强化学习里同一个状态转移对不同的目标有完全不同的学习价值。用一组目标的失败经验去教会agent完成另一组目标本质上是把探索过程中的每一次尝试都榨取出学习信号。2. 目标重标注HER的核心原理深度拆解2.1 目标重标注的数学逻辑先明确一下问题形式。目标条件化强化学习里策略是 π(a|s, g)即根据状态 s 和目标 g 来决定动作。奖励函数写成 r(s, a, g)在稀疏奖励下通常就是 r 1_{s 满足 g}也就是说只有转移后的 next state 达成目标才给正奖励。HER的典型做法是对于采样到的一条轨迹 τ (s_0, a_0, r_0, s_1, a_1, r_1, ..., s_T)除了保留原始目标 g 下的转换样本外额外生成若干条重标注样本。重标注过程分两步第一步确定新目标集合。四种常用策略final用轨迹末状态 s_T 作为新目标一个episode只生成一组future对时间步 t从未来状态集合 {s_{t1}, s_{t2}, ..., s_T} 里随机采样 k 个状态作为新目标episode从整条轨迹的所有状态里随机采样random从环境中随机采样状态。OpenAI在Fetch系列机器人任务上的对比实验显示future策略效果最好。原因也好理解future策略选的目标和当前状态在时间上靠近意味着这个目标大概率是当前策略“差一步就能达成”的相当于给了agent一串连续的、难度递进的阶段性目标学起来自然更顺。第二步计算重标注后的奖励。注意这里要用转移后的 next state 去判断是否达成新目标即 r 1_{s_{t1} 满足 g}而不是用当前状态 s_t。这个细节很多人会写错一旦把目标达成判断放在错误的时刻整个重标注逻辑就废了。2.2 与DDPG/SAC这类离策略算法的配合逻辑HER本身不是一个完整的强化学习算法而是一种经验回放的改造方案必须搭配离策略off-policy算法使用。原因是重标注需要反复利用历史轨迹只有离策略算法能从经验回放池里反复采样旧数据来更新网络。DDPG、TD3、SAC、DQN都满足这个条件实际项目里最常见的组合是DDPGHER和SACHER。配合方式也很直接回放池里同时保存原始样本和重标注样本采样时按比例混合。通常每个原始转换额外生成 k 个重标注转换k 取4左右比较常见。这样每次梯度更新时batch里既有真实目标下的经验帮助agent记住真正的任务又有重标注目标下的经验提供丰富的正反馈信号。这里有一个容易被忽略的点目标也要变成网络的输入。值函数从 Q(s, a) 变成 Q(s, a, g)这就是所谓的通用值函数近似UVFA。网络结构上通常会把 s 和 g 拼接后一起输入或者在特征层做融合。如果只是简单替换奖励而没有把目标引入输入算法就会在重标注和原始目标之间来回横跳根本学不到稳定的策略。2.3 为什么HER能显著提升样本效率传统稀疏奖励训练之所以慢本质是正样本太少。一个episode只有最终达成目标的那一步才有 1其余全是0价值网络很难从大量零奖励样本里学到有意义的梯度。HER把奖励密度提升了一个维度通过重标注一条200步的失败轨迹可以产生一组“从某一步开始达成新目标”的正样本正样本的覆盖率大大增加。更关键的是这些正样本不是靠随机碰巧产生的而是来自agent自己探索出的真实状态分布上更接近当前策略的可达状态空间学习信号因此更可靠。打个不严谨的比方传统方法像是让一个从没学过数学的人直接做高考大题错了也不知道哪里错HER相当于把每道没做出来的题都重新改个设问让他发现自己其实已经掌握了不少步骤只需要补齐最后的几步。学习自然快得多。3. 从零实现HER的关键环节与代码解析3.1 环境设计与目标函数构造想把HER用好环境必须先设计成目标条件化的形式。推荐用OpenAI Gym的接口定义observation是一个dict包含 observation当前状态和 achieved_goal / desired_goal 两类字段。achieved_goal表示当前实际达成的目标desired_goal表示期望目标奖励函数根据这两个字段是否匹配来计算。class FetchPushEnv(gym.Env): def reset(self): # 初始化机械臂、方块位置并随机采样一个目标 self.desired_goal self._sample_goal() return self._get_obs() def _get_obs(self): achieved_goal self._get_achieved_goal() return { observation: self._get_state_vector(), achieved_goal: achieved_goal, desired_goal: self.desired_goal } def compute_reward(self, achieved_goal, desired_goal, info): # 稀疏奖励距离小于阈值即成功 distance np.linalg.norm(achieved_goal - desired_goal, axis-1) return (distance 0.05).astype(np.float32)这个结构是HER能跑通的基础。注意一个关键细节:compute_reward的输入是achieved_goal和desired_goal而不是原始状态。这样重标注时只需要替换desired_goal就能重新计算奖励不需要动其他任何东西。3.2 重标注逻辑的代码实现HER的代码核心不复杂但细节决定成败。我最常用的写法是在一个episode结束后对轨迹中的每个转换做一次“批量重标注”把生成的样本统一塞进回放池。def store_episode(self, episode, her_ratio4, strategyfuture): # episode 包含 (obs_seq, action_seq, reward_seq) obs_seq, action_seq, reward_seq episode T len(action_seq) original_goal obs_seq[0][desired_goal] for t in range(T): obs obs_seq[t] action action_seq[t] reward reward_seq[t] next_obs obs_seq[t 1] if t 1 T else obs_seq[-1] done (t T - 1) # 1. 保存原始样本 self.buffer.add(obs, action, reward, next_obs, done) # 2. 生成 her 重标注样本 if strategy future: # 从未来状态中随机采样目标只取 achieved_goal 字段 future_states obs_seq[t 1:] if len(future_states) 0: for _ in range(her_ratio): sample_index np.random.randint(len(future_states)) new_goal future_states[sample_index][achieved_goal] new_reward self.env.compute_reward( next_obs[achieved_goal], new_goal, None) new_obs dict(obs, desired_goalnew_goal) new_next_obs dict(next_obs, desired_goalnew_goal) self.buffer.add(new_obs, action, new_reward, new_next_obs, done)说几个实现时容易踩的坑。第一new_goal要取future state的achieved_goal字段而不是desired_goal否则等于换了个没意义的目标。第二重标注后的obs里desired_goal要同步替换但achieved_goal保持原样这俩字段千万别搞混。第三用dict(obs, desired_goalnew_goal)这种方式创建新样本时如果后续代码要修改obs里的字段容易造成原样本被意外污染建议用copy.deepcopy或者显式构造新字典。3.3 超参数选择与训练策略HER本身对超参数不算特别敏感但有几个值直接影响效果her_ratio重标注比例每个原始转换额外生成的重标注样本数OpenAI默认是4我试过1和81的时候训练偏慢8的时候回放池里重标注样本占比过高原始目标下的经验被稀释反而影响最终任务达成率future采样范围k步之外的状态也可以作为目标候选但如果目标距离当前状态太远生成的“成功样本”对agent来说几乎不可能一步达成学习信号太弱实践中还是建议从最近未来状态采样回放池大小因为重标注会让样本量膨胀4倍池子要相应设大通常设1e6量级否则早期的成功经验会被挤出去探索噪声搭配DDPG时探索主要靠动作噪声。我用的高斯噪声标准差从0.2慢慢衰减到0.05前期多探索、后期少扰动。训练策略上我习惯把HER的损失曲线和“验证集目标达成率”一起监控。只盯奖励曲线容易产生错觉——重标注样本是人为制造的正奖励会推高平均奖励但真实任务的目标达成率才是真正要优化的指标。4. 实战中的常见问题与排查实录4.1 训练不收敛奖励曲线一直趴在零附近这是我被问得最多的情况。如果你确认代码逻辑没问题第一件事检查重标注样本有没有真的进回放池。很多新人会犯一个低级错误只在episode结束后调用一次store_episode但函数内部忘记更新回放池的存储计数导致学习过程中采到的全是原始样本HER等于没开。第二个常见原因是目标字段没进网络输入。我见过有人用DDPG框架只改了奖励函数Q网络的输入还是只有state和action这种配置下重标注样本对网络来说和噪声无异。务必确认Q(s, a, g)和策略π(a|s, g)的输入都包含目标。第三个原因比较隐蔽探索噪声设置得太小导致前期几乎没有多样化探索。稀疏奖励环境里agent必须靠随机探索碰出一些“接近目标”的状态HER才能把这些状态重标注成可学习的经验。如果噪声过小agent永远在起点附近打转就没有“事后成功”可言。我一般建议前期噪声不低于0.15等目标达成率超过一定阈值后再开始衰减。4.2 重标注带来的分布偏移问题HER虽然好用但它有一个内在的理论缺陷训练时采样的目标分布和测试时的目标分布不一致。训练时很多目标来自重标注这些目标的分布偏向agent实际能到达的状态测试时目标是真随机采样的难度可能高得多。这个分布偏移在实践中的表现是训练曲线很漂亮目标达成率超过90%但换一批新目标测试时成功率掉到一半以下。应对办法有两个层面。一个是保证回放池里始终保留足够比例的原始目标样本原始目标分布和测试分布更接近网络不至于完全忘掉真实任务的难度。另一个是在训练后期适当降低her_ratio让模型逐步“收窄”到真实目标分布上。我在FetchPush上试过后期把her_ratio从4降到2测试泛化成功率能提升5到8个百分点。4.3 重标注暴露出奖励函数设计的问题HER有一个容易被忽略的副作用它对奖励函数特别“诚实”。因为重标注会让agent频繁看到正奖励样本如果奖励函数本身有漏洞这些漏洞会被放大训练出来。举个例子如果你在稀疏奖励之外加了一个“距离惩罚”那么重标注样本计算新奖励时也要用同一个函数。但新的目标是从轨迹未来状态采出来的距离惩罚天然偏小因为next_state离未来状态很近这会让agent学会“靠近自己去过的地方”而不是“达成目标”行为完全跑偏。所以我的经验是用HER时奖励函数尽量保持硬性稀疏距离惩罚之类的塑形项要么去掉要么只在原始样本上生效。HER本身就是为了替代奖励塑形而设计的再叠加上去反而破坏它的信号结构。5. 应用场景与扩展思路5.1 机器人操作任务Fetch系列HER最经典的应用场景是OpenAI的Fetch机器人操作环境Reach够到目标点、Push把物体推到目标位置、Slide击打物体滑到目标、PickAndPlace抓取并搬运。这些任务统一具备两个特征目标明确、奖励稀疏、状态空间连续。恰好是HER的主场。我实际跑下来在FetchPush上DDPGHER大概3到5万步就能看到明显的目标达成率上升而纯DDPG在这种稀疏奖励下基本学不动。FetchPickAndPlace稍微难一些需要更长训练时间和更大的回放池但HER依然能把任务从“几乎学不会”拉到80%以上的成功率。一组可参考的关键参数回放池25万batch size 128actor/critic学习率1e-3目标网络软更新系数0.05her_ratio 4future采样k4训练总步数50万。5.2 HER的适用边界HER不是万能的。它的有效性建立在“目标可以通过状态子集来表示”这个假设上。如果任务的目标没法从状态直接读出比如“写出一段符合语法的话”或者目标空间巨大而状态访问极其稀疏重标注就没法生成有意义的训练信号。另外HER对探索的依赖很高。如果环境的探索空间太大或者初始策略完全无法产生任何“接近目标”的状态那么重标注也是巧妇难为无米之炊。这类场景更适合先做预训练、模仿学习或者更好的探索策略把基础行为教会再上HER做精细优化。5.3 后续可以怎么扩展回头看我觉得有几条特别有价值的扩展方向。一个是把HER和课程学习结合先让agent在简单目标上学会基础运动技能再用HER在困难目标上精调两者互补比单独用效果都稳。另一个是HER的思想可以迁移到离线强化学习里对静态数据集做目标重标注给离线训练造出更多正样本。还有就是在分层强化学习里用HER生成子目标的监督信号帮助高层策略学习目标分配。我从第一次跑通HER到现在最大的体会是很多看似困难的学习问题缺的往往不是更复杂的算法而是更聪明的数据利用方式。HER把“失败经验”做了重解释这个思路本身也提醒我调模型的时候别只盯着最终目标多看看中间过程里已经做对的部分很多成功其实已经藏在里面了。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Beckhoff EK1100 与 LabVIEW 集成:TwinCAT 配置与 ADS 通信实战指南 2026/10/2 12:29:52

Beckhoff EK1100 与 LabVIEW 集成:TwinCAT 配置与 ADS 通信实战指南

1. 为什么EK1100接LabVIEW这件事值得单独拿出来说Beckhoff EK1100这个耦合器模块,在EtherCAT圈子里算是入门级标配了。它本身不复杂,一头是EtherCAT输入,一头是E-bus输出,后面挂一堆EL系列的IO模块,24V供电&#xff0c…

阅读更多 →
DRV8818+TM4C129机械臂驱动板实战:从电路到固件全解析 2026/10/2 12:29:46

DRV8818+TM4C129机械臂驱动板实战:从电路到固件全解析

前一阵子做一台桌面级六轴机械臂,驱动部分试过集成步进、也试过用 A4988 这类模块,最后在载重和稳定性要求更高的工业验证版本里,改成了 DRV8818PWPR TM4C129ENCPDT 这套组合。DRV8818PWPR 是 TI 的双极步进电机驱动器,内置双 H …

阅读更多 →
U-Boot移植全流程:从启动链路到板级配置与内核引导实战指南 2026/10/2 12:29:46

U-Boot移植全流程:从启动链路到板级配置与内核引导实战指南

聊到U-Boot移植,很多做嵌入式的朋友第一反应就是“水太深,坑太多”。我在这个行当里泡了十来年,从早期的AT91RM9200一路折腾到现在的ARM64平台,U-Boot移植这件事其实有非常清晰的套路。所谓基础,不是要你把整个U-Boot源…

阅读更多 →
基于MK64与DRV8818的双极步进电机运动控制方案设计与调试 2026/10/2 12:29:39

基于MK64与DRV8818的双极步进电机运动控制方案设计与调试

搞过步进电机控制的工程师,应该都体会过那种感觉:低速发抖、高速丢步、驱动芯片烫到不敢摸、现场一跑起来就 nFAULT。这些坑我基本都踩过一遍。这阵子在整理一套工业和机器人辅助轴的运动控制单元,主控用了 NXP 的 MK64FN1M0VDC12&#xff0c…

阅读更多 →
RFID标签批量编码数据校验实战:从原理到避坑指南 2026/10/2 12:29:39

RFID标签批量编码数据校验实战:从原理到避坑指南

1. 从一个真实场景说起:为什么你的RFID标签会“莫名其妙”读不出来做过RFID项目的人,大概率都遇到过这种让人抓狂的情况:一批标签明明在写码环节显示“写入成功”,到了客户现场,有几张就是读不出来,或者读出…

阅读更多 →
Codex+ClaudeDesktop+DeepSeekV4——AI编程双核驱动配置指南:TaoToken统一Key接入实战 2026/10/2 12:29:32

Codex+ClaudeDesktop+DeepSeekV4——AI编程双核驱动配置指南:TaoToken统一Key接入实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉