ARTICLE DETAIL

资讯详情

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

稀疏奖励下的强化学习:HER事后经验回放原理与实战

稀疏奖励下的强化学习:HER事后经验回放原理与实战 做强化学习做到机器人控制这个方向你迟早会撞上一个词——稀疏奖励。环境搜遍四面八方给不出一个正反馈智能体像个无头苍蝇训练半天成功率还是零。后来看到OpenAI那篇Hindsight Experience Replay事后经验回放的论文我才真正理解“hindsight”这个标题的妙处它不教智能体怎么成功而是让智能体从每一次失败里硬生生学出点东西来。这篇文章我想把这套方法从直觉、原理到落地实操完整拆一遍适合正在做RL控制、尤其是遇到奖励稀疏问题的朋友参考。我最早接触HER是在一个机械臂抓取项目里。任务要求机械臂把一个方块推到目标点但直到训练结束智能体都没成功过一次。后来换成HER奇迹般地开始慢慢靠近目标。说到底HER干的事非常朴素既然没抓到那就把“抓到”这个目标改成“手到了当前位置”把这次失败当成一次成功的示范来学。就是这么一刀把RL训练从“等老天赏正奖励”变成了“自己给自己造奖励”。1. 项目背景与核心思路拆解1.1 稀疏奖励是个怎样的“训练黑洞”先说清楚为什么稀疏奖励会让人头疼。想象你让一个机器人学走路奖励只有“走到10米外”才算成功其余时候全是0。那机器人初期的随机动作大概率原地打转探索几千步也拿不到一个非零信号梯度根本传不回去策略自然学不动。更糟的是即便偶尔蒙对了一次那一步前后的其他很多动作也未必跟这成功直接相关单靠一条偶然路径很难泛化出正确的行为模式。在Fetch这类机械臂任务里稀疏奖励的表现更具体环境给一个目标坐标机器人只有把方块推到离目标足够近才给奖励否则一律是0。在这种设定下随机策略的成功率低到可以忽略不计训练出来的几乎就是一个“无操作”模型。这也是很多RL项目从仿真到真实的第一道坎——奖励函数据说是设计的艺术而稀疏奖励就等于设计成“没奖励”。业内常用的对策无非三类改良加中间奖励比如离目标越近分数越高、加课程学习先从近距离目标学起、或者直接上一个“能自动从失败中学习”的算法。HER属于最后一类也是我认为在结构上最优雅的一种。它不要求你重新设计机器人的传感器、不做人工分阶段训练只需要调整经验回放的方式就能把环境原有的稀疏奖励变成有效信号。1.2 从“事与愿违”到“事后诸葛亮”“hindsight”在英文里就是“事后才能看清”的意思。一个典型的场景周末想出门跑步结果下雨了你不得不改练瑜伽。从“跑步”这个目标看你是失败的但从“锻炼”这个目标看你是成功的。人类会立刻把这次经历归类为“完成了室内锻炼”的经验下次决策时就会带着这份记忆去考虑备选方案。HER正是把这个逻辑搬进了强化学习。在目标条件goal-conditioned的RL设定里每回合我们都会给智能体一个目标g智能体根据观测和目标准备动作。常规经验回放存的是(状态s、动作a、奖励r、下一状态s‘、目标g)五元组。HER的做法是回合结束后把这一轨数据拿来做“二次包装”。既然原始目标没达成那就从这条轨迹里挑一个实际到达过的状态比如最终位置s_T把它当作“新目标”g再用环境的奖励函数算一遍奖励r。因为g是实际发生的状态此时的奖励几乎不可能还是0。然后把这批改写后的经验也放进回放池。这一下子就把“失败轨迹”转成了“成功轨迹的模拟数据”。机器人没推到目标位置A但它推到了位置B那我们就暂时认为“推到B”才是这回合的目标这份经验就不再是白板而是高质量的训练样本。等回放池里有大量这种“近目标”数据智能体就学到了基本的接近能力、抓取能力之后再逐步朝真实目标逼近就顺理成章。1.3 它与普通经验回放的本质差异很多人第一次接触HER会问这不就是数据增强吗其实还不一样。普通经验回放Experience Replay只负责把旧数据存起来打破样本相关性、提高利用率。它不会改变样本里的奖励和目标只是让同一条数据被反复利用。HER则是在存数据之前主动给数据“换一个目标”重新计算奖励和后续意图。用大白话对比普通回放是“把走过的路都记下来”HER是“把走错的路也脑补成走对的路”。脑补的方法也不是任意编造而是严格从轨迹里挑一个实际到达的状态重新解释。这种改写有一个很大的好处它完全不需要额外的环境交互不需要模拟器额外计算只在一个回合结束之后做一次后处理。所以HER天然是off-policy的玩法通常配合DDPG、SAC、TD3这类算法效果最明显。从数学上看HER改写的样本仍然满足“目标g与轨迹状态信息一致”的条件。因为在目标条件策略下策略把g当作输入轨迹是在“试图达到g”的过程中产生的里面携带了大量关于环境动力学的信息。改成g之后虽然策略输入的目标变了但状态转移部分依然真实只是奖励和目标标签更新了所以本质上还是在利用真实交互数据进行学习只是改变了标签分配。2. 算法细节与原理深度解析2.1 目标条件强化学习的基础知识要把HER真正用起来先得把目标条件下的RL设定补一补。过去普通RL的状态就一个观测s智能体学的是“从状态到动作的映射”。目标条件RL多了一个变量g常见的做法是把g拼进观测里即输入变成(s, g)或者在做图像任务时把两者拼成一个张量。策略π(a|s, g)需要根据目标输出动作奖励函数也变成了r(s, g, a)通常是判断当前状态是否满足目标。典型实现里g和s往往共用一个嵌入编码。比如Fetch任务中g就是目标三维坐标s里也包含机械臂末端坐标两者都归一化到同一个尺度。这样设计的好处是网络能把它们作为同一个特征空间的输入也能让HER改写目标时无需额外做坐标转换直接替换g即可。经验回放在这里承担的任务也更重。除了要存下(s, a, r, s, g)还要在采样时混合原始真实经验和Hindsight改写经验。在OpenAI的原始论文里每一条轨迹会被扩展成k条Hindsight轨迹k一般取4或8。如果选8意味着每次回合结束除了原始目标对应的轨迹还要额外生成7条通过不同策略选定新目标的轨迹全部塞进buffer。总buffer里改写过的数据占比可能高达80%以上所以算法能否稳定很大程度取决于这些改写样本的质量。2.2 HER的经验改写逻辑与关键公式先给出一份简明的伪代码再看具体实现。假设环境返回一个回合的完整轨迹(s0, a0, r1, s1, ..., sT)HER做的是这样几步for each episode: # 原始轨迹先存一份 store_transitions(episode, goalg) # 选定一个新的目标集合 new_goals sample_goals(episode, strategy) for g_prime in new_goals: # 用新目标重算奖励 r_prime reward_func(s_next, g_prime) # 改写后的样本也放入回放池 store_transitions(episode, goalg_prime, rewardr_prime)这里最关键的是reward_func要能把新目标对应的真实奖励算出来。Fetch这类任务常用的是二进制奖励或者带距离裕度的奖励距离小于某个阈值给0否则给-1或者直接给距离的负值。HER对奖励形式并不挑剔只要这个函数“对称”也就是说它给出的奖励能反映“当前状态距离目标到底有多近”改写出来的信号就是合理的。原论文里用二进制稀疏奖励配合HER已经能在Fetch任务上取得成功。这其实超出了很多人的预期——大家都以为奖励必须设计的很细结果HER告诉你只要你能从失败里学到正确方向二进制奖励也够用。不过要提醒一句这里的“二进制”依然是“距离阈值判断”环境内部还是能感知到距离信息只是奖励层不透露。HER从轨迹里挑出来的g恰恰分布在实际到达过的位置所以阈值奖励基本都落在“成功”一侧这正是它能提升样本效率的核心原因。2.3 四种目标选择策略对比选定新目标并不是随便抽一个状态就行。OpenAI在论文里对比了几种策略结论倒是很清楚future策略效果最好。简单解释一下这四种策略策略做法优点不足final只选轨迹最终状态作为目标实现最简单中间状态的多样性不够future从当前时间步后面的状态里随机挑一个既贴近真实可达区又保持了时间因果性数据分布最合理稍微增加一点计算量episode从整个轨迹任意状态中挑一个多样性强可能会把“过去的自己”当成目标导致学习到错误因果关联random从其他回合的状态里挑扩展探索范围容易选到真实分布外的目标导致目标分布过度发散future策略之所以胜出是因为它严格限制“目标出现在当前之后”。这样构造出来的训练样本其隐含的逻辑是“如果我在t时刻就想去到未来某个位置那么现在应该采取什么动作”。这跟奖励函数的因果关系是吻合的智能体学到的是一种“先见之明”而不是对过去的被动模仿。episode策略所选的可能在当前之前这会让智能体学到“回到之前状态”的错误策略等于人为增加了任务难度。参数k也很讲究。k太小改写样本覆盖的目标空间不够广提升不明显k太大buffer里全是“脑补”经验原始目标样本被稀释智能体可能只顾着接近各种离奇目标反而忘了真正的任务目标。我在实际项目里常用k8做简单任务时k4也够用。如果环境本身已经很复杂k8会明显增加训练稳定性和成功率上限。2.4 为什么HER在数学上能让训练更快从原理上拆解HER本质上是在提升“有效奖励密度”。原本一回合只有零个或一个非零奖励信号经过改写之后一回合能产生大量非零奖励样本每个样本都对应一个真实可达的状态。这让梯度更新在时间维度上更加密集相当于把稀疏奖励空间变成了密集奖励空间来训练。另一个角度是探索效率。无模型RL最大的瓶颈是探索尤其在连续动作空间里随机策略能碰巧到达目标附近的概率极低。HER相当于自动收集“探索过程中所有碰巧到过的地方”把它们转成正例。这意味着每次探索都有收获智能体不再需要在黑暗里寻找唯一的灯塔而是把所有走过的路都变成地图的一部分。这种思路和课程学习异曲同工但它不需要人为设计课程而是完全由数据驱动。还有一个容易忽略的点HER减少了价值的方差。稀疏奖励下Q函数的训练本质上是“近乎零信号偶尔大信号”Q值震荡非常剧烈。改写后的数据让Q值更新可以基于平滑的密集奖励来传播学习曲线会显著稳定。很多人实验发现在同样是100万步预算下普通DDPG的success rate基本贴地而DDPGHER能爬到80%以上差距就是这么拉开的。3. 实操落地从论文到能跑起来的代码3.1 环境与框架选型我建议直接拿OpenAI Gym里的MuJoCo Fetch系列任务上手尤其是FetchReach-v1和FetchPush-v1。前者是纯运动控制机械臂末端到达3D坐标即可用来验证HER有没有跑通最直观后者需要推方块涉及接触动力学能感受一下改写样本带来的提升有多大。框架方面自己从零实现HER其实并不复杂但为了效率我推荐直接用stable-baselines3生态。传统做法是配合sb3-contrib的HerReplayBuffer使用它已经实现了HER的核心逻辑你只要选好基类算法SAC或TQC并传入参数。需要注意版本兼容性HerReplayBuffer在较新的sb3版本中已集成到主库可以按你本地的版本来看API。如果你想把HER用于自定义环境关键是让环境遵循GoalEnv接口提供compute_reward(achieved_goal, desired_goal, info)方法并在观测字典里给出observation和achieved_goal。HER需要从轨迹中提取“已达目标”所以这个接口设计得越规范后面越省事。3.2 核心实现代码拆解直接看一份能跑的示例配置。这里用TQC一种SAC的改进变体配合HERReplayBuffer环境选FetchPushimport gym from sb3_contrib import TQC from sb3_contrib.common.replay_buffer import HerReplayBuffer env gym.make(FetchPush-v1) model TQC( MultiInputPolicy, env, replay_buffer_classHerReplayBuffer, replay_buffer_kwargs{ n_sampled_goal: 8, # 也就是论文里的 k goal_selection_strategy: future, online_sampling: False, }, learning_starts1000, buffer_size500_000, batch_size512, gradient_steps1, learning_rate0.001, tau0.05, gamma0.98, policy_kwargsdict(net_arch[256, 256, 256]), verbose1, ) model.learn(total_timesteps500_000, log_interval10) model.save(her_fetch_push)这里几个参数值得细说。n_sampled_goal8决定了每条原始轨迹改写出的样本数量。8是我在实践中比较稳的档位如果提升不明显可以试试16但要注意buffer里真实目标样本会被大量稀释训练后期可能学不到“完成指定目标”的能力。goal_selection_strategyfuture默认推荐绝大多数场景不用改。online_samplingFalse表示使用标准的“先存储整条轨迹再统一改写”的方式这个默认值最省心。learning_starts1000是给buffer一些预热时间。由于前期的随机轨迹没有改写价值此处不宜过小建议不低于1000。batch_size512比较大因为HER的buffer里样本形式丰富batch太小容易让每次更新只看到单一类型的目标训练不稳定。gradient_steps1意味着每采集一步环境数据就更新一次这种设置跟大batch配合收敛比较平滑。3.3 参数选择与调参经验调参这件事没有银弹但有几个指标可以作为参照。奖励阈值。Gym的Fetch任务内部已经给了reward_typesparse的判断逻辑但你自定义环境时一定要想清楚“距离小于多少算成功”。这个阈值直接决定了改写之后奖励的稀疏程度。阈值太严即使改写了目标仍有大量样本无法拿正奖励太松智能体学到的策略精度不足最后一米定位会飘。经验做法是先拿最优策略跑一次统计到达终点的误差分布把阈值设成误差分布的50%分位点再慢慢收紧。目标空间维度。对于Fetch类环境目标是3D坐标范围很小不需要额外归一化。但如果你做的是机械臂抓取目标可能包含位置和姿态姿态空间是SO(3)流形单纯对数值做HER会很别扭。这时要么先把姿态转成轴角并用合理的边界框归一化要么只对位置部分做HER姿态靠别的手段比如夹具吸住后再用插值解决。网络宽度。HER通常建议至少用256x256以上的双层网络。因为目标拼接到观测后输入维度变高输入-目标的组合模式也更多样太窄的网络容量不够特征根本学不出来。我试过128x128效果明显差一截后来统一用256或512。buffer容量。HER需要大量的改写样本buffer太小会让旧经验过快被覆盖导致目标分布随时钟漂移。Fetch任务500k起步如果资源够1M更好。3.4 训练监控与效果评估跑起来之后别只盯着平均回报看HER的训练曲线一开始很丑reward从负值慢慢爬升中途还有可能平台期这都是正常的。我习惯同时记录两个指标一个是环境的真实成功率eval_success_rate另一个是回放池里改写样本的占比。前者衡量最终性能后者能帮判断是不是buffer配置出问题了。评价成功率时一定要定期用独立的评估环境跑不要看训练时episode的返回值。因为训练回合的目标是随机抽的改写过后的奖励会污染对真实能力的判断。比如FetchPush任务在训练500k步后每100回合用一个固定目标集评估成功率到60%以上基本算调通。另外强烈建议记录训练过程中的目标平均距离也就是“智能体所有episode结束位置与真实目标的平均距离”。HER学的本质是让这个距离收敛如果这个值在稳步下降说明改写样本在起作用如果卡住不动就该回去检查目标选择策略或网络容量。4. 常见问题与排查技巧实录4.1 Q值震荡导致训练发散HER让buffer里的奖励分布变密集这会让Q网络在初期非常活跃有时候Q值直接爆掉策略也跟着崩。现象就是前几百步reward看起来正常突然猛掉到一个很负的值然后一蹶不振。排查路径很明确先看Q值的绝对值范围如果瞬间上千上万基本是Q网络过拟合了那些密集的改写样本。解决办法是调低学习率到1e-4以下同时把tau调小soft update速率比如0.002。还有个偏门但好用的招把奖励放大或缩小一个固定倍数。因为HER改写后的奖励往往是-1和0量纲很小Q网络更新时需要匹配这个scale。实战中我用reward_scale系数0.1或者10来调节配合上面两个参数基本都能稳住。4.2 目标达成率过高反而学不到全局策略这是个反直觉的现象。如果环境偏简单智能体很容易完成原始目标那么HER改写样本的“新目标”基本都落在成功区域附近此时扩充样本多样性这个功能就失效了。而且如果成功率太高训练样本里“真实正样本”占绝对优势Hindsight的伪成功样本几乎被淹没等于白加了这个模块。遇到这种情况建议把环境难度适当调高比如把目标范围扩大或者把距离阈值收紧拉回一点挑战性。HER最适合的区间是初始成功率在1%~10%之间的环境成功率到50%以上它带来的边际提升就很小了。反过来如果成功率一直是0且经验曲线纹丝不动可能是探索空间太大建议先检查动作范围是否合理或者先做几轮随机策略数据收集来预热。4.3 改写目标与真实目标分布偏离太远HER选定目标虽然从轨迹里来但如果轨迹本身的质量很低比如全是机械臂原地发抖那么改写出来的目标基本都聚在一个很小的区域智能体学到的就是“抖动手臂”。这个问题在训练早期特别常见。我的办法是用future策略但加一条约束新目标的采样范围尽量往后靠。比如直接选final或者在做future时用指数分布偏向后期状态这样至少目标离真实任务点更近一些。如果偏得太厉害可以考虑把n_sampled_goal暂时调低让真实目标样本多占一些比重稳定早期训练。4.4 回放池中真实目标经验被淹没当k16或者更高时回放池里改写样本可能占到90%以上。这会导致策略对“完成指定目标”这件事在学习中权重极低所有样本都在学“如何去到达过的位置”本质上是陷入了另一个局部最优。排查方法是看training reward:如果训练期平均奖励稳定在某个不错的值但eval成功率极低基本就是被淹没。解决办法很简单调低k值或者把buffer里的改写样本做限制比如每批次采样时强制至少30%来自原始目标数据。我后期还会在buffer里额外多存一些真实目标轨迹把online_samplingTrue打开也可以改善因为online模式下每条经验都即时改写改写样本与真实经验的分布更加接近。4.5 问题速查表现象可能原因快速解决方法Q值爆炸发散学习率过高 / tau过大 / 奖励尺度不佳调低lr至1e-4调小tau调整reward_scaleeval成功率低但训练reward不错改写样本占比过高降低n_sampled_goal强制原始目标样本占比训练曲线停滞目标空间过大 / 探索不足先做随机数据预热扩大buffer考虑课程学习学到原地抖动目标分布过于集中换future策略并偏向后期状态降低batch_size收敛精度不足距离阈值过松导致目标不需要精确达成收紧reward阈值增加训练步数结尾的一点个人体会HER看起来轻巧真正跑起来才会发现它把很多脏活都往前挪了一步——奖励不用你设计得费尽心思课程不用你手动安排你只需要保证环境的GoalEnv接口规范、目标空间合理它就能在大部分稀疏奖励任务里交出漂亮的成绩单。我个人的实际感受是HER不只是一个算法更像一种“看待失败数据”的视角转变在强化学习里一次失败的尝试从来不是浪费时间而是收集了一条关于“到达过哪里”的宝贵轨迹把它换种标签存起来就变成了成功经验。踩过几次坑之后我现在做新任务的第一反应都是先跑一套HER基线再考虑要不要花大力气设计奖励。如果你也在稀疏奖励的泥潭里挣扎真心建议直接动手复现一次FetchPush那份从0到1的成功率曲线会让你印象深刻的。
返回列表