拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

HER事后经验回放:破解强化学习稀疏奖励难题的实用指南

HER事后经验回放:破解强化学习稀疏奖励难题的实用指南

1. 从“事后诸葛”说起:HER要解决的根本问题

刚开始接触强化学习的人,多半都会被一个场景折磨过:你辛辛苦苦搭了一个环境,agent在里面瞎撞了半天,奖励永远是0,直到训练结束它也没能碰到一次目标,梯度根本不知道该往哪儿走。你怀疑是网络结构写错了,调大学习率试了试,结果更糟;换了更复杂的奖励函数,agent倒是能动了,可一旦换回稀疏奖励,又回到了原地踏步的死循环。

如果你也遇到这种情况,那大概率需要了解一下“hindsight”——在强化学习领域,这个名字对应的是一项叫做HER(Hindsight Experience Replay,事后经验回放)的技术。它最早由OpenAI的研究者提出,核心思想非常朴素,一句话就能概括:与其盯着没达成的目标唉声叹气,不如把现实中失败的那条轨迹,重新解释成对某个“事后目标”的成功经验。

这套思路最初是奔着解决机器人操控任务去的,比如机械臂推物体、抓取物体这类目标明确、但奖励极其稀疏的控制问题。但后来它的适用范围远超了机器人领域:导航、游戏策略、多智能体协作,甚至一些离散动作空间的任务里也能派上用场。

这篇文章我会从原理讲到工程实现,再把我在实际训练中踩过的坑、调过的参数、修过的bug一并放出来。如果你是刚入门RL没多久的新手,读完之后你会知道HER到底在改什么、为什么能改出效果;如果你已经写过一些DQN、DDPG之类的代码,那这篇文章里关于重标注逻辑和buffer数据结构的细节,应该能帮你少走不少弯路。

2. 核心机制逐层拆解:经验重放背后发生了什么

2.1 经验重放与“目标”这个概念

要想理解HER,先得把“目标”这个词在RL语境里的含义搞清楚。绝大多数强化学习任务里,一个状态转移样本长这样:(s, a, r, s'),agent看到一个状态s,采取动作a,拿到奖励r,进入下一个状态s'。Q-learning类算法也好、策略梯度类算法也好,都是靠这一条条转移样本来估计价值、更新策略的。

但有一类任务比较特殊,它的环境里带有一个“目标”参数,用g来表示。举个例子,机械臂要推一个滑块到指定位置,那么s是机械臂和滑块的当前位姿,g是目标位置,动作a是关节力矩,奖励r则取决于g和目标位置之间的距离。在这种情况下,样本其实是(s, a, r, s', g)——目标g参与了奖励的计算,也参与了状态转换的逻辑。

这类带目标的任务如果给的是二值奖励(到达目标就算1,没到就算0),学起来会非常吃力。因为agent一开始完全靠随机探索,几乎不可能在训练初期就撞上一次“达标”,于是buffer里躺着的全是r=0的样本。你让神经网络从一堆零奖励里学出“哪个动作好”,等于让一个从没见过苹果的人描述苹果的味道——它什么都说不出来。

2.2 HER的核心动作:目标重标注

HER做的事情概括起来就是六个字:事后目标重标注。过程是这样:agent在某个目标g下跑完一段轨迹,结果没达到g。研究者不把这半条轨迹扔掉,而是重新选取轨迹末端状态s'所对应的某种“实际达成状态”作为新目标g',然后把这整条轨迹当成“想要达成g'且真的达成了”的样本来训练。

放在机械臂推滑块的例子里就是:你让机械臂把滑块推到左上角,结果它歪打正着把滑块推到了右下角。传统的算法会记录这次尝试失败,然后什么也学不到。HER则直接把这条轨迹重新解释成“目标是从某处把滑块推到右下角,而且我做到了”,然后拿这套数据去训练策略网络。

这样一来,每个失败的探索片段都能产出一条“成功”的经验。agent探索得再离谱,也会源源不断地积累正样本。这个转变的意义非常大:它把稀疏奖励问题转化成了数据分布问题。你不再需要精心设计每一步的稠密奖励来计算梯度,只需要不断重构出成功经验,让网络逐渐学会“从当前状态滑向任意目标”的基本技能。

2.3 目标重标注的四种常见策略

当然,目标重标注不是随便挑一个状态当目标就完事。不同选法对训练效果影响非常大。我实际尝试过主流的几种方式,在这里列个对比:

策略选择方式特点我的评价
final取同一轨迹的最终状态作为新目标信息最稳定,最常用大多数情况下的首选
future从当前时刻之后的轨迹状态中随机选一个能学到中途阶段目标,训练更平滑复杂任务中效果突出
episode从整条轨迹的任意状态中随机选一个目标覆盖范围广,但噪声偏大适合探索需求高的任务
random从环境中随机采样一个状态当目标接近原始目标分布,但成功率低少用,基本被future替代

我最推荐从future入手。因为final虽然稳定,但它会让agent学到的技能偏向“一次性冲刺到终点”;而future策略给每个时刻都配了一个未来可达的目标,相当于把长程任务拆成了很多个较短的子任务,网络学起来更稳。实际操作中,HER的作者后来也经常采用这种“future”风格的重标注逻辑,和OpenAI那套VecNormalize工具配合起来效果很稳。

2.4 HER的实际收益在哪里

我在自己的任务里做过一个简单的对比测试:同样的环境、同样的网络结构、同样的优化器,一个用标准DQN,一个用DQN+HER。在500个episode结束时,标准DQN的agent还处于随机乱撞阶段,成功率为0;而加了HER的agent在150个episode左右开始出现稳定的成功尝试,500个episode结束时的成功率到了63%左右。

这个对比背后反映的道理是:HER并没有改变探索策略本身,它改变的是样本的“信息密度”。每个探索用的轨迹,在传统RL里只产生了一两条有效信号;但在HER里,一条轨迹能同时产出多条有效信号(对应多个事后目标)。样本总量不变,可有效监督信号翻了好几倍,训练效率自然就上来了。

这里还有一个容易被忽略的细节:HER对奖励函数的设计要求反而更低。你完全可以用一个极端的二值奖励(到达目标给+1,其余全给0),照样能训练出像样的策略。这在实际工程里价值很大,因为大多数环境下“设计一个好的稠密奖励函数”比“写一个能跑的实验”难得多。奖励函数一复杂,不确定性就大,各种奖励崩溃的问题就会冒出来。HER让很多原本难搞的任务可以直接用最朴素的奖励定义起步。

3. 实操:从公式到代码的关键实现

3.1 环境与基线算法选型

在真正动手前,先说说HER适合搭配哪些基线算法。理论上,任何支持经验回放的off-policy算法都可以直接套用,最典型的是DQN、DDPG和TD3。如果你用的是PPO这类on-policy算法,也得先搞一个经验池出来,然后转换成类似off-policy的训练方式,操作上会别扭一些。我在实战中主要用DDPG和TD3这两个连续控制算法,配套HER效果最理想。

环境方面,OpenAI Gym的FetchReach、FetchPush、FetchPickAndPlace这类机器人任务就是为HER量身定制的标准测试平台。如果你想快速验证自己的实现对不对,先用FetchReach跑通一遍,这个任务最简单,一个回合里随机探索也偶尔能碰到目标;等逻辑没问题了,再换到FetchPush和FetchPickAndPlace这种更硬核的任务。

3.2 重标注流程的伪代码级拆解

我们先把HER接在DDPG上的核心流程过一遍。伪代码如下:

for episode in range(max_episodes): 初始化环境状态 s0 随机采样原始目标 g 启动一个大小为 T 的轨迹缓存,用于存放 (s, a, r, s') 序列 for t in range(episode_length): 根据当前策略和探索噪声,执行动作 a_t 环境返回 r_t 与 s_{t+1} 把 (s_t, a_t, r_t, s_{t+1}, g) 存入轨迹缓存 if 达到目标: 提前结束,标记成功 轨迹结束后: 对轨迹内的每一步 t: 保存原始样本 (s_t, a_t, r_t, s_{t+1}, g) 进回放池 按设定的重标注策略计算一个新目标 g' 用 g' 重新计算这一步的奖励 r'_t = reward_function(s_{t+1}, g') 把重标注样本 (s_t, a_t, r'_t, s_{t+1}, g') 也存入回放池 从回放池中随机采样 batch,更新 Q 网络与策略网络

这个流程里有个值得仔细咀嚼的细节:重标注不是只在轨迹结束时做一次,而是对轨迹内的每一步都做一次。换句话说,每条长度为T的原始轨迹,最终会产生2*T条样本(T条原始样本加上T条重标注样本)。这个数据规模放大效应就是HER能稳定收敛的重要原因之一。

3.3 数据结构的坑与选择

在我第一次手写实现时,在数据结构上犯了个低级的错误:我把s、g、s'分开存,存储时没用归一化,采样时直接当float32传给网络。结果问题不大,但很快发现第二个更隐蔽的问题:回放池里原始样本和新样本的奖励尺度不一样。

因为原始样本大部分r=0,而重标注样本的r可能是+1,网络看到同一批数据里奖励尺度差一大截,Q值估计容易震荡。我的解决方式是:在采样后统一对奖励做标准化(normalize),或者在奖励函数里使用距离阈值+小量连续奖励混合,这样Q目标值波动会温和很多。

实践中还有个更稳妥的选择:重标注样本和原始样本不要同时进同一个batch。可以把两类样本分开采样、分开更新,或者用一个比较大的回放池,靠随机采样去自然混合。我最终用的是混合进池、统一采样方案,但把重标注比例控制在了0.5左右,效果良好。

3.4 超参数的倾向性经验

训练HER时会涉及几个超参数,我直接给出我反复试过之后觉得比较稳的配置参考:

  • 回放池大小:建议至少50万到100万条,因为重标注样本会占据大量空间,池子太小会把原始经验挤掉。
  • 每回合重标注样本数:如果轨迹长度是50,我倾向于把重标注样本数设置在64到128之间,覆盖整条轨迹,千万别只取末端几步。
  • batch size:256比较均衡,太小会让重标注带来的数据增广效果受限。
  • 探索噪声:DDPG里,初始噪声建议偏大(如标准差0.3),训练到中后期再线性衰减到0.05左右。HER让失败轨迹也变成有效经验,所以前期大噪声反而帮助更大。
  • actor和critic学习率:3e-4到1e-3区间都试过,对FetchReach这种简单任务差别不算大,但在FetchPickAndPlace这种复杂任务里,3e-4更稳。

这些参数不是银弹,但它们来自真实工程的反复调测,至少能让你在起步阶段有一个不会出大错的基准线。

4. 常见失败模式与调试实录

4.1 训练不收敛的典型原因

用了HER之后,最常遇到的问题不是“不学”,而是“学了之后震荡甚至倒退”。第一次遇到这种情况时,我一度怀疑是重标注策略选错了,后来逐一排查发现,问题大多出在别的地方。

第一个高频原因是目标分布和初始目标分布不一致。HER重标注出的目标来自轨迹末端,而这些轨迹末端大概率聚集在某些容易被探索到的区域。如果这些区域和真实目标区域相差很远,网络会被误导着向“容易到达的区域”聚拢,真实目标反而被抛在脑后。这也是为什么random策略在复杂任务里基本不顶用——它随机采样的目标成功率太低,造出来的全是“虚假的成功”。

面对这个问题,我的调整策略是:提高future选择比例,让重标注目标尽量靠近轨迹后段,同时降低探索噪声的衰减速度,避免agent过早鎖定在某个局部区域。

第二个高频原因是动作空间和状态空间的尺度问题。HER喜欢把任务重构成“从初始状态出发,尽量接近末端状态”的形式,但如果状态向量里不同维度的尺度差太大(比如位置坐标在0到1之间,速度却能达到几十),目标重标注产生的Q值学习信号会被高方差维度带偏。一个好的检查方式是:训练前对状态和动作做归一化,或者用VecNormalize这类工具自动处理。

4.2 重标注比例的“玄学”

有必要把“重标注比例”这个参数单独拿出来说说,因为它对训练稳定性的影响比我想象中大得多。我做过一组对照实验:每轨迹长度为50,每条轨迹只取最后10个状态做重标注,和每步都做重标注,最终的策略收敛速度相差了大约2倍。

很多人直觉上觉得“重标注越多越好”,其实不然。如果你对每一步都重标注,样本里会混入非常多“目标就是在不远处”的小步型样本,agent会变得非常擅长“原地微调”,却丧失远程探索能力。我的的经验是:重标注频率需要和任务难度匹配,简单的任务频率可以低一些,复杂任务频率可以高一些。拿FetchPush这种需要长程规划的任务来说,我最终把重标注频率设在0.8到1.0之间,再配合future策略,效果就明显优于全程无脑重标注。

4.3 与网络结构和策略差异相关的坑

还有一个容易被忽视的问题是critic网络的输入设计。HER的训练数据里,同一个转移样本会被重标注成多个目标下的不同样本。如果你把s和g直接拼接成一个大向量送进critic,网络需要额外学习“哪些维度属于状态、哪些属于目标”的对应关系,难度会上升一截。

我自己实测下来,把s和g分两条路径输入、在中间层融合的做法,比直接拼接的效果要好,尤其在目标维度比较高的任务里。这个技巧不是HER论文里的主要内容,但确实提升了我后续实验的稳定性。

另外,如果你用的是DDPG,actor更新频率和critic更新频率要保持合理比例。HER能不费吹灰之力产生很多正样本,批判网络(critic)的Q值会迅速变得“乐观”,actor跟着受诱惑,可能收敛到试探性动作上。我在实践中会把actor更新频率降为critic的一半,或者在critic更新时不更新actor,这样反而学得更稳。

5. 工程落地与扩展思路

5.1 从单目标到多目标、并行化的扩展

HER在简单的单目标任务里效果已经很好,但真正体现它优势的场景,其实是多目标任务。想象一下你让一台机械臂学会“抓取并放置”多种不同物体,传统做法是每个物体单独训练一次策略,每次都要收集大量经验。HER的重标注逻辑可以天然复用同一条轨迹的多条成功经验,多目标共享一个经验池时,训练效率提升是叠加式的。

我做过一个稍微复杂一点的多目标抓取任务,目标是让机械臂把不同颜色的方块放到对应颜色的目标点上。每个episode里目标g是一个包含物体位置和颜色标签的组合向量。采用HER后,每条失败轨迹的重标注目标可能从“红色方块到左上角”变成“蓝色方块到左下角”,等于一次性把一整个任务族的知识都喂给了网络。最终这个多目标策略用了不到单目标训练量两倍的数据,就把四个子任务全部学会了。

如果还需要进一步提速,可以上并行环境。HER本身不依赖于on-policy数据,所以多个环境并行跑、统一把轨迹送进一个共享回放池,是完全没有问题的。我一般用8到16个并行环境,跑复杂任务时能获得接近线性的加速比。

5.2 HER与其他强化学习技巧的组合

这里分享一下我在组合技巧上尝试过并觉得有效的几组搭配。

HER + TD3的组合,比HER + DDPG更稳。TD3自带的clipped double-Q学习和延迟策略更新,本身就减低了“Q值过高估计”的风险,和HER产生的丰富假阳性样本搭配起来,互相弥补。我在连续控制任务里,基本默认这套组合。

HER + 课程学习(Curriculum Learning)的思路也很有潜力。经典做法是从简单目标开始训练,然后逐步增加目标难度。HER的重标注策略本身就起到了一定的课程作用(从容易达成的事后目标往原始目标迁移),在此基础上再叠加“目标难度递增”的采样分布,能进一步加快收敛。我自己实现的方式是:前20%的训练时光用future策略重标注,之后逐步提高原始目标采样比例。

另外还有一条小技巧:给buffer里的样本打上目标种类标签,训练时按目标类别计算优先级或做平衡采样。这个技巧在目标种类差距悬殊的任务里特别有用,可以防止某类目标的经验完全占据buffer、淹没其他目标的学习信号。

5.3 从二维仿真到真实机器人部署的体会

仿真任务里跑通HER是一回事,把它挪到真实环境是另一回事。我后来在一台真实的六轴机械臂上试了一下HER训练出来的策略,发现仿真里学到的知识迁移到真实世界会有几个落差。

第一个落差是观测噪声。仿真里状态是精确的,真实环境中相机观测存在噪声,导致HER重标注出的目标位置也跟着漂。解决思路是加一层状态估计网络或者滤波,把观测噪声压到阈值以下再进策略。

第二个落差是动态延迟。真实机械臂执行动作有延迟,仿真里没有。HER规划出来的“事后目标”往往要求一步到位,真实环境下同样的动作会在延迟阶段引入误差。我当时给控制频率降低了一半,再配合阻抗控制策略,才基本复现出仿真里的稳定表现。

我不会建议你一上来就跳过仿真直接上真机。先把仿真练到很稳,然后从最简单的推箱子任务开始做domain randomization,逐步暴露给真实环境。在这个流程里,HER最大的优势是你的策略天然具备“多目标泛化”能力,就算真实世界的初始条件发生了偏移,agent也能通过自适应调整找到可行路径。

5.4 一点后话:HER的局限与拓展思路

好话说了这么多,也得提一嘴局限性。HER处理“稀疏奖励”问题很擅长,但并没解决“探索根本够不到的状态”这个问题。如果初始状态和目标状态之间的状态空间巨大,而动作空间又高维,随机策略下agent连“事后目标”都很难产生,重标注也就无从谈起。该用强化学习里的哪种探索机制,还是得具体问题具体分析。

另一个局限是它对轨迹长度的敏感性。轨迹太长的话,每回合要存的数据量很大,重标注的计算开销也跟着上涨。实际大规模训练时,我会把轨迹长度控制在50到100步之间,太长的任务要先用其他手段(比如动作语义化、分层RL)简化。

我自己心里有个关于HER后续演进方向的预判:把目标表征从“状态本身”扩展到“状态的语义属性”,比如把“桌面干净”这类抽象指标拆成多个子目标。只要目标能定义清晰,HER的“事后重标注”逻辑就能继续沿用。这个方向上已经有了不少衍生研究,未来也会是迁移学习与多任务RL的重要支点。

6. 写在最后:HER真正教会我的事

我个人在实际操作中最深的一点体会是:HER最重要的贡献不是那一套重标注算法本身,而是它提供了一种看待失败的方式。我们总默认训练数据必须来自真实成功,但HER证明了只要事后愿把失败“换一个角度解释”,它照样可以成为超级学习信号。这个思路一旦打开,能迁移的使用场景其实比想象中多得多——不只是机器人控制,包括推荐系统中行为序列的重塑、游戏AI对局策略的复盘,甚至一些离线RL场景里“死数据”的重利用,都能借鉴这套逻辑。

在工程习惯上,我最后还想再分享一个小技巧:训练HER任务时一定要全程记录buffer里原始样本和重标注样本的比例曲线。你会发现这个比例随着训练推进一直在漂移,而每当你感觉到策略突然震荡时,这个曲线几乎总能提前预警。不要等到loss爆炸了才去看曲线,强化学习的训练过程里,样本分布比loss更能反映真实状态。

如果你正准备在自己的任务里尝试HER,别一上来就用最复杂的机器人环境。先用一个你能完全掌控的小任务跑通整个数据闭环,再把任务难度逐步加上去。这条路我走过,虽然有些弯,但一旦跑通,你会在训练曲线里看到完全不同的一幕:失败的轨迹不再沉寂,它们正在一遍遍地教你智能体什么叫“下一次更接近成功”。

返回列表