ARTICLE DETAIL

资讯详情

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

稀疏奖励下的强化学习难题,用后见经验回放HER高效解决

稀疏奖励下的强化学习难题,用后见经验回放HER高效解决 1. 从一次失败的机械臂抓取说起为什么需要HER去年做一个机械臂抓取小项目时我差点把DDQN、PPO全部轮了一遍模型就是学不会把桌面上的方块推到目标点位。奖励给的是稀疏版本只有方块进入目标圈才返回1。听起来特别合理可智能体压根找不到这个1。一位师兄说要不试试Hindsight。他说的是Hindsight Experience Replay后见经验回放简称HER。我当时觉得这名字太玄了后见之明不就是事后诸葛吗直到跑完实验才发现这恰恰是打通稀疏奖励问题最实用的套路之一。这篇文章想把HER的原理、完整实操和踩坑经验一次讲清楚给同样被稀疏奖励折磨的人一份能直接抄的作业。很多刚接触强化学习的人第一反应是稀疏奖励不好学那把奖励做密一点不就行了吗我一开始也这么想结果被现实教育了一顿。先说结论稀疏奖励并不是环境设计得烂而是很多真实任务天生就是稀疏的真正的问题是你缺一层“重新解读经验”的机制而这层机制正是HER的核心价值。1.1 稀疏奖励问题的本质想象一下你在玩射击游戏只有正中十环才有奖励擦边九环也没有分而且游戏还要靠这个分数来教你瞄准。对模型来说大部分动作都像打在棉花上奖励为0梯度也为0策略更新自然原地踏步。强化学习的本质是“奖励驱动”但稀疏奖励让整个空间的反馈几乎全是空的模型根本不知道该往哪个方向改。打个更贴切的比方你想让一个小孩学会投飞镖但只有正中靶心才告诉他“对了”其他时候一言不发那他大概率只能靠瞎蒙。机械臂抓取任务里最常见的设定是每一帧观测到机械臂末端位置、物体位置、目标点位置动作是末端的三维移动。如果只看“物体是否进圈”来打分要么给0要么给1智能体一开始几乎随机乱试能碰到目标圈的概率非常低。我从训练日志里看到的景象是回合平均回报长期在-0.01附近波动策略网络输出的动作基本像无头苍蝇训练曲线看起来像一条快死掉的心电图。如果你手动把奖励设计成“距离目标圈越近分数越高”模型确实会动起来但它很容易钻空子。我踩过的实际案例模型发现高分数只跟“接近”有关就开始在目标圈外围画小圈永远不进去。这就是稀疏奖励的价值它把任务定义得很干净代价是难学。HER就是用来解决这个“难学”问题的但它解决的不是奖励函数而是经验回放里的标签。1.2 奖励塑形的副作用以及为什么HER不用塑形奖励塑形是很多人最先想到的方案它有几种常见做法按距离给连续奖励、按相对距离变化给增量奖励、或者对危险动作加惩罚。设计得好确实能加速学习但这些公式建立在“人类以为正确的路径”上机器人常常在优化一个和你的直觉完全不同的目标。一个经典例子你想让机械臂把瓶盖拧上你给“盖子越水平分越高”的奖励机械臂可能学会用蛮力把盖子顶翻然后盖子水平朝上这根本不是“拧紧”。HER的思路完全不同。它不引入任何额外的距离公式也不靠人工知识定义中间步骤而是改变经验样本的标签把一个失败片段用“假如目标本该在这里”的方式重新标记从而让原本全零的奖励里长出新样本。一句话概括它把“我原以为的目标”替换成“事后来看其实已经完成的目标”在经验层面制造成功。所以我在实际项目里把奖励塑形代码几乎删光了只留了最朴素的任务判定。看起来模型能获得的正反馈更少了但因为HER给这些失败片段重新赋予了目标数据里的“有效信号”反而更多。这也解释了为什么很多论文会说HER配合稀疏奖励效果更好因为它的着眼点不在奖励设计而在经验利用效率。2. HER的“后见之明”到底是怎么偷师的HER这个名字听起来玄核心思路其实很直白人搞砸一件事后复盘往往会意识到“原来我做到的那一步如果目标换成另一件事就是成功的”。机器人也可以这样。强化学习里我们把这类经验叫做“失败中的成功片段”HER就是把这些片段重新写进记忆的方法。2.1 核心思想把失败样本当成成功样本先快速铺垫一点背景。在目标条件强化学习里策略输入通常包含两部分当前观测状态s和期望目标g。环境会在下一个状态s里给出achieved_goal也就是实际到达的位置。如果s和g足够接近奖励为1否则为0。这个设定在机械臂、机器人导航和很多操作任务里都很常见。经典的经验回放会存下这样的五元组在当前状态s、目标g下做了动作a到达s获得奖励r。问题在于当目标g很困难时绝大多数样本的r都是0。比如机械臂从正下方往上抬目标是桌面上某个角落它怎么乱动都不够接近所以经验池里几乎没有正样本策略网络学不到任何方向。HER的做法是在回放阶段额外构造一个虚拟目标g。怎么构造方法很简单拿这条经验里事后实际到达的achieved_goal作为新目标。也就是说原来的经验是“从s出发想完成g结果到了achieved_goal失败”新的经验变成“从s出发想到达achieved_goal结果也到了achieved_goal成功”。同样一组动作因为目标变了奖励从0变成了1。用生活化的例子解释你原计划做番茄炒蛋结果做成了番茄蛋花汤。如果按原计划评价这锅菜是失败但如果把“做一碗番茄蛋花汤”当作目标它其实是标准成功示范。HER就是把这些额外成功示范重新写进记忆让模型知道“从当前状态出发通过这样的动作可以达到什么样的状态”。这种知识多了以后模型就能逐渐学会从任意状态逼近目标。2.2 目标采样策略四种玩法虚拟目标不能乱造造得不好会让训练发散。目前最常用的有四种目标采样策略final、future、episode、random。区别在于从哪取“事后实际到达的状态”。策略虚拟目标来源特点与适用场景final整条轨迹最终状态实现简单适合单阶段任务但会让成功集中在轨迹尾部future离当前时间点t之后1到k步的状态最常推荐目标自然连贯适合连续控制episode从同一条轨迹里随机抽一个状态比future更随机目标分布广稳定性略差random从整个回放池里随机抽一个状态目标可能与当前转移毫无关系训练方差大我最常用future策略。具体来说一条轨迹是由一串转移组成的比如第0步、第1步一直到第T步。对第t步的状态转移我从[t1, tk]这个区间里随机抽一个时间索引h然后把第h步的achieved_goal当作虚拟目标。这样虚拟目标在时间上比当前更靠后模型学到的意思是从t步这个状态出发继续往前走本来就能到达h步那个位置。它把“前向动力学”教给了策略而不是硬造一个只能靠巧合到达的目标。final策略我也会用但只用一小部分比如30%到50%的HER样本用final剩下的用future。原因是final会让许多不同时刻的转移都指向同一个最终目标如果整条轨迹很长中间很多状态离最终目标很远反而会拉高任务的难度。future则更温和目标距离当前状态更近学习曲线更平稳。random我基本不用因为目标可能来自完全不相干的任务会导致Q值更新强烈震荡。2.3 为什么HER有效把探索变成利用强化学习里有一个“死循环”探索不到成功就没法利用经验没有经验利用探索效率又很低。HER的核心价值在于它把探索过程中无意达到的状态重新定义为目标让那些“差一点成功”的轨迹也能变成正样本。换句话说它没有增加探索能力但让探索结果被更充分地利用。我在实验中看到的很明显现象训练早期机械臂完全随机摆动几乎没有任何一次真的走到目标点。但HER会把这些随机轨迹里的某个中间状态当作目标于是回放池里立刻出现了“类成功样本”Critic开始有东西可学。随着策略慢慢学会到达这些“容易目标”它就越来越容易在真实探索中接近原始目标形成一个正循环。这也能解释为什么HER对稀疏奖励特别有效它不需要你手动设计中间奖励也不需要你精心安排课程而是自动地从失败中挖掘出成功。它并不神奇只是更聪明地利用数据。尤其是当环境维度不算太高时HER甚至能把原本几乎不可能收敛的任务在几小时内训练出能用的策略。3. 实操用DDPGHER训练机械臂抓取任务原理聊完接下来进入正题。我在项目里用的是DDPG加HER这是OpenAI Robotics里最经典的组合。下面会把环境、代码、训练配置全部跑一遍并给出一份可以直接复用的关键实现。3.1 环境选型与安装我选的是Gym仿真环境里的FetchReach任务。FetchReach的目标是让机械臂末端移动到指定位置状态空间包含机械臂末端坐标、物体坐标、目标坐标等动作是三维连续控制。之所以选这个环境是因为它的奖励是标准稀疏奖励末端位置与目标点的距离小于某个阈值才返回1否则返回0。安装上如果你用的是新版Gymnasium可以执行pip install gymnasium-robotics然后在代码里创建环境import gymnasium as gym import gymnasium_robotics gym.register_envs(gymnasium_robotics) env gym.make(FetchReach-v1, render_modeNone)如果你本地装了老版gym也可以用gym.make(FetchReach-v1)。需要注意版本兼容问题尤其是observation_space结构和info里的achieved_goal字段。新版接口默认把achieved_goal放在observation的字典里读取时别搞混。FetchReach的状态维度不高动作只有3个拿来验证HER再合适不过。如果你的目标是抓取物体并放进托盘可以换成FetchPush或FetchPickAndPlace代码逻辑几乎不用动只需额外处理物体坐标和关节角度。3.2 网络与训练流程DDPG分成两个网络Actor负责根据当前观测和目标输出动作Critic负责评估这个动作的价值。输入部分需要把observation和desired_goal拼起来动作空间归一化到[-1, 1]连续控制场景一般用tanh输出。我在项目里没有用太花哨的网络结构Actor是两层256个神经元的MLPCritic也是两层256配合LayerNorm训练稳定性明显好很多。HER的代码核心不在网络而在经验回放的写入逻辑。我贴一段关键伪代码这段是我在项目里实际用的简化版def her_replay(episode, episode_goal, strategyfuture, k4, n_her4): for t, (obs, action, reward, next_obs) in enumerate(episode): # 原始样本先入池 replay_buffer.add( obs, action, reward, next_obs, desired_goalepisode_goal ) # 构造 HER 样本 if strategy future: low t 1 high min(t k, len(episode) - 1) if low high: continue for _ in range(n_her): h random.randint(low, high) virtual_goal next_obs[achieved_goal][h] new_reward reward_func( obs[achieved_goal], virtual_goal ) replay_buffer.add( obs, action, new_reward, next_obs, desired_goalvirtual_goal ) # final 策略只取轨迹最后一步作为虚拟目标 if strategy final: virtual_goal episode[-1][achieved_goal] new_reward reward_func( obs[achieved_goal], virtual_goal ) replay_buffer.add( obs, action, new_reward, next_obs, desired_goalvirtual_goal )reward_func这里就是判断两个坐标距离是否小于阈值小于给1否则给0。注意一个容易被忽略的细节虚拟目标用的是“未来某个时刻的achieved_goal”而不是状态本身。如果直接把next_obs的完整向量当目标那维度会和desired_goal不一致训练直接报错。训练循环里每次从回放池随机抽一个batchCritic更新时用原始奖励和HER奖励混合的样本Actor更新时只使用原始目标来计算目标条件策略梯度。这也是为什么我强调HER不是简单地“把失败标成成功”而是要在数据流层面确保目标分布合理。3.3 训练效果分析与对比我先跑了一版纯DDPG没有HER在FetchReach上训练了80万步。成功率曲线像一条死线一直贴着5%到10%偶尔还会跌到0。然后我加上future策略的HER每个转移额外生成4个虚拟目标样本同样训练80万步最终成功率稳定在90%以上。当然这个数字依赖随机种子和网络宽度但趋势非常明显。为了公平对比我固定了网络结构、优化器、学习率和探索噪声唯一变量是HER开关。下面是这个配置下的简化对比配置40万步成功率80万步成功率训练稳定性DDPG无HER约2%约6%曲线长期贴地DDPG加HER(future)约45%约92%稳步上升波动较小这个对比让我当时挺震惊的不是因为HER多厉害而是因为它只是改了回放样本的“目标标签”就把一个几乎学不动的任务救活了。后来我又试了把n_her从4调到8发现成功率没有再明显提升反而训练前期的Q损失波动更大。所以“HER样本越多越好”这句话是错的需要控制比例。4. 训练中遇到的坑与排查技巧实录纸上谈兵容易真正动手跑实验问题一堆。我把这段时间踩过的坑梳理成四个比较典型的场景每个都有明确的排查思路。4.1 目标采样漂移导致Q值振荡第一次跑HER时我为了让模型快速学到东西把final策略和future策略混在一起每5步换一个策略结果Critic损失像过山车时不时冒出几个巨大的尖峰。原因其实很简单同一个transition刚才被分配的目标还是近在眼前的状态下一次就被分配成轨迹末尾的遥远状态奖励要么1要么0很容易让Q值更新互相打架。我的解决办法是把目标采样策略固定下来不要频繁切换。实际项目里我用的是70%的future样本加30%的final样本并且保证在一个batch里来自同一条轨迹的样本不要超过batch_size的三分之一。另外每个转移生成HER样本的数量也固定为4不搞动态调整。稳定之后Critic损失曲线虽然还有锯齿但不再出现爆炸式尖峰。4.2 归一化不能省FetchReach里末端坐标的范围大概在1.5米左右目标坐标也在这个范围看起来数字不大。但Critic要同时处理原始目标距离和0/1奖励尺度差异会让训练非常敏感。我踩过一个具体坑reward直接设为1Q值上线就发散loss跑到几百reward改成0.01又觉得训练太慢。后来把所有obs和goal先做归一化减均值除标准差再把奖励固定成0.1问题才稳定下来。这里的关键是HER样本中虚拟目标分布会比原始目标分布更集中如果不对输入做归一化Critic很难从不同尺度的目标里提取一致的价值信号。我建议在环境返回观测后立刻做标准归一化而不是丢给网络里自己学。网络自己有归一化层也可以但收敛会慢不少。4.3 探索噪声与确定性策略的平衡DDPG本身是确定性策略必须靠额外噪声来探索。HER需要的是“随机的失败”因为只有足够多样的失败才有足够丰富的“后见目标”。我的第一个版本给动作加的高斯噪声标准差是0.05结果机械臂几乎不动因为动作范围是[-1,1]0.05噪声太小了。训练了10万步回放池里所有轨迹都缩在初始位置附近。后来我把探索噪声调大初始标准差设为0.3并在前30万步线性衰减到0.1训练速度明显加快。这里给个小经验如果训练一开始成功率就是0不要先怀疑HER先检查探索噪声。没有多样性后见之明也白搭。4.4 常见问题速查表我把几个高频问题整理成一个简单表格方便你对照处理。现象可能原因排查方向损失下降但成功率不涨目标采样太单一Q值指标失真混合future和final调整HER样本比例训练前期梯度爆炸奖励尺度太大输入未归一化奖励乘以0.1obs和goal做标准化机械臂一直不动探索噪声太小增大高斯噪声到0.2到0.3成功率卡在50%不动虚拟目标分布与真实目标分布差异大增加随机种子提高未来采样步数k到8行动作很抖来回震荡探索噪声没衰减设置噪声衰减计划后期降到0.05以下这五个问题我在不同环境里至少遇到过四次每次排查完都有一种“原来才是真正原因”的感觉。如果你也卡住不妨从这张表开始查。5. 从算法到做事一点个人心得与后续扩展HER对我最大的冲击不是提升训练指标而是改变了我设计强化学习方案的思路。以前我一遇到稀疏奖励脑子里的第一个念头永远是加奖励函数现在我会先问自己这个经验数据里有没有被忽略的成功片段这个问题听起来很朴素但非常有用。5.1 我在实际调参时最看重的一个设定如果只让我保留一个经验那就是HER的目标分布一定要和策略当前的能力匹配。训练早期目标应该偏向容易达到的状态训练中后期再逐渐增加原始目标的比例。很多人直接上手就疯狂加final样本反而让策略被困难目标压垮。我把采样策略配成70% future 30% final后训练曲线是最平滑的成功率也最高。另外回放池容量不要太抠。HER会在每个转移上额外生成4个样本所以回放池的写入量会变大需要相应扩大容量。我最初用50000条经验很快就被原始样本挤满了HER样本根本没空间存。后来改成300000条效果立刻不一样。内存能扛就尽量给大一点。5.2 让HER走出机械臂任务HER的思路不止适用于机械臂。很多带目标条件的任务比如导航、游戏、推荐系统都可以借鉴这套“事后重新标记目标”的方法。搭配Offline RL时HER也可以补充数据多样性让离线数据集里的失败轨迹重新发光。我在另一个项目里把HER用在一个简单的仿真环境中用不到几万条交互数据就训练出一个能绕开障碍的智能体效果出乎意料。不过也有不适合HER的场景。如果任务的成败完全取决于一步决策比如“猜硬币正反”事后没有连续状态可作目标HER就无从下手。我的判断标准很简单只要任务存在连续的状态过渡并且可以定义achieved_goalHER就有发挥空间。最后分享一个踏实的建议如果你正在被稀疏奖励折磨别急着写复杂的奖励塑形公式。先搭一套DDPG或TD3把HER的future策略接进去固定随机种子跑一夜。很多时候一个简单的“后见之明”比你想破头的奖励设计更靠谱。
返回列表