HER算法:用“后见之明”破解强化学习稀疏奖励难题
如果只能用一个词概括复盘的力量我会选hindsight。这个词翻译过来叫“后见之明”听起来有点负面的意思——谁都知道事后诸葛亮容易当可真正在算法世界里hindsight被做成了Hindsight Experience Replay也就是HER算法专门负责搞定那些奖励极其稀疏的任务。它做的事情听起来简单学不到东西时把“失败”的轨迹重新标注成通往另一个目标的成功经验再喂给智能体。这既是一套算法也像一种重估过去的方式。这篇文章从一个项目标题出发把hindsight背后的核心思路、技术原理、实操步骤以及它对我们工作方法的启发一次性拆开讲清楚。适合正在研究强化学习、准备用强化学习落地机器人控制的朋友同样适合想把“复盘”做出体系的产品经理和团队负责人。1. 从项目名称说起hindsight到底想解决什么问题先明确一个前提单独提hindsight它是“后见之明”一个带着点遗憾色彩的日常词汇。但在强化学习领域它几乎就是HER算法的代名词。我之所以把这个项目标题拆成技术和方法论两层来看是因为它的核心思想可以平移——算法通过重新解释历史经验来学习人通过重新审视过去来成长。但这一篇技术是主线。1.1 一句话理解hindsight事后聪明也是一种学习信号强化学习的标准范式是智能体在环境里试错根据奖励信号调整策略。问题来了很多真实任务根本不给奖励反馈。你让机械臂去抓杯子它没抓到环境直接返回0没有“接近了”“碰了一下”这种中间反馈。一堆0堆下来策略梯度里啥都学不到因为奖励处处为空智能体就像在黑夜里摸一扇根本不存在的大门。hindsight的想法很反直觉既然当前目标没达到那就别死磕它干脆把“实际达到的状态”当作目标重新看一遍这条轨迹。比如机械臂本想去抓杯子结果手伸到了杯子旁边10厘米处。传统算法会把这次尝试当成纯失败直接丢弃。HER则会说这次轨迹对于一个“移动到手到杯子旁边10厘米处”的目标来说其实是完美成功。把这个新目标写进经验里轨迹就从废料变成了有效训练样本。这就是后见之明的力量当时没有计划但回头看我们确实完成了一件有意义的事。把这个“完成的事”立为目标就能从中学到东西。1.2 为什么稀疏奖励会成为强化学习的拦路虎不是所有任务都稀疏但高难度任务几乎都稀疏。比如让机器人推开一块木板让它自己把奖励函数设计成“木板移动了多少像素”你会发现策略始终停留在原地转圈。原因很简单随机初始化的策略很难碰巧完成一个高难度动作没有中间奖励引导梯度信息接近于零探索就成了无头苍蝇。学术界和工业界为了缓解这个问题用过多阶段课程学习、奖励塑形、模仿学习、逆强化学习各有各的代价。奖励塑形最直接但很容易被钻空子——你设“靠近目标加分”智能体可能学到在目标附近转圈而不是真正操作。HER不需要重新设计奖励也不需要专家示范只要环境能提供“实际达到的状态”它就能自动把失败轨迹重新理解成有用经验。这个优势在机器人控制中被放得很大因为机器人任务天然有明确的状态变量位置、角度、速度都能读出来。1.3 从生活类比到技术映射把失败的经验变成训练样本你可以把HER理解成一位特别会复盘的老员工。项目做砸了大家都很沮丧这位老员工却说虽然我们没搞定A客户但我们找到了一条完全走通的新流程这对搞定B客户、C客户都有价值。于是他把这次“失败”归档成“新流程验证成功”的案例下次面对类似客户直接调用。算法里的实现方式就是目标重标注。原始轨迹里每一步都有一个“原本想要达到的目标”现在替换成一个“实际达到的目标”然后放进经验池。将来更新策略时智能体就会看到在某个状态下采取某个动作确实能达到某个目标。它学到的不是“这件事我做不成”而是“原来我还能做成这件事”。一旦有了这些“伪成功”的经历稀疏奖励被稀释学习信号变稠密策略优化就顺了。2. 核心技术拆解hindsight如何变成HER算法如果只停留在思想层面这篇文章就太虚了。我接下来把HER的技术流程拆开尽量用能看到代码的颗粒度来讲。你不需要一次性记住所有公式但抓住两条主线经验回放怎么用目标重标注怎么做。2.1 经验回放Experience Replay基础在讨论HER之前得先理解普通经验回放。深度学习时代的强化学习会用一个固定大小的缓冲区存储过去的元组状态、动作、奖励、下一个状态、完成标志。训练时随机抽一小批样本用来打破时序相关性让神经网络更新更稳定。传统经验回放里这些样本的语义已经固定“在状态s下做动作a得到奖励r进入状态s”。如果奖励r是0这个样本对梯度的贡献就很小。HER往前走了一步它发现一条轨迹可以被改写改写后的样本可以放进同一个回放缓冲区。缓冲区的角色从“存储历史”变成了“重新解读历史”。这里有个关键前提环境必须提供achieved_goal实际达到的目标。注意这不是让你手动添加中间奖励而是让你读状态。比如机械臂的关节位置、末端位置、物体位置这些信息环境本来就有只是过去只用于判定成败现在多了一个用途——成为新目标。2.2 关键技巧目标重标注Goal Relabeling目标重标注是HER的心脏。一条完整轨迹存储着一系列状态转移假设原始目标是g实际轨迹结束时达到了状态g。现在我们把整条轨迹的目标从g改成g并且重新计算每一步的奖励。这样原本被判定为失败的轨迹在新目标下变成了成功轨迹最后一步的奖励变成了1前面的过渡状态也离目标更近奖励不再是全零。实际操作中你不会只替换成最终状态而是在轨迹内部选几个状态作为额外目标。比如one of the future states。原因是只使用最终状态会让样本单一从整条轨迹上抽样不同时刻的状态可以覆盖更多子目标让模型学会“到达不同目标状态”的动作序列。具体有几种策略值得记住策略做法适用场景final把整条轨迹的目标换成最终状态任务目标单一最终状态有代表性future从当前时间步之后的某个状态作为替换目标数据集增广效果好最推荐episode从同一条轨迹中随机抽一个状态作为替换目标目标分布多样适合多目标场景实际项目里future策略用得最多。因为它每次只把“未来某一时刻的状态”作为当前目标这个目标与当前动作之间存在真实的因果链条在时间上更紧密学习效率最高。2.3 算法流程与伪代码把HER接到任意一个支持离策略的强化学习算法上比如DQN、DDPG、TD3、SAC核心流程如下输入一个离策略强化学习算法一个目标条件环境 初始化回放缓冲区策略网络价值网络 循环每个回合 随机采样一个目标 g 重置环境开始采集轨迹 对于轨迹中的每个时间步 t 根据当前策略选择动作 a_t 执行动作得到 s_{t1} 和 reward_t 轨迹结束后 对轨迹中的每个时间步 t 将 (s_t, a_t, reward_t, s_{t1}, g) 存进回放缓冲区 额外次数 从轨迹中选择一个替代目标 g如 future 策略 重新计算每一步的奖励 将重标注后的四元组存进回放缓冲区 从回放缓冲区采样一批数据更新策略和价值网络看到没有原轨迹本身还是按原始目标存储一份重标注的样本会额外生成若干份。n_sampled_goal这个超参数控制的就是每组样本额外生成多少份。n_sampled_goal越大历史经验利用越充分但计算量也越大容易过拟合到已经达到过的状态上。2.4 为什么HER能变废为宝损失函数与策略梯度视角我换个更学术的说法。强化学习的目标是最大化期望累积奖励。在目标条件设定下策略是π(a|s,g)价值函数是Q(s,a,g)。标准训练里奖励为零的样本会让Q值对目标的泛化能力变得很差因为所有目标的Q值都被压成相似的零。而HER通过重新标注目标把一个零奖励样本变成高奖励样本Q值的监督信号变得多样化。从损失函数看价值网络在优化这种目标L E[(r γ max_a Q(s, a, g) - Q(s, a, g))^2]原始样本中g是原始目标r往往为0。重标注样本中g变成了g最后一个转移的r变成1整体损失中就有了正向监督。策略网络通过最大化Q值来更新它看到“在s下做a可以达到g”于是更倾向于在该状态下激活类似动作。还有一个隐含好处HER学到的是一种目标条件下的广义策略。它不再只针对一个固定目标而是学会“给我任何目标我都能朝它走”。这意味着训练出来的模型天然支持目标泛化换一个相似目标不需要从头训练。这也是为什么HER在机器人抓取、推动、滑动这些多目标任务里表现特别好。3. 从技术到落地一份可以直接参考的实操方案聊完原理必须上手跑一次。很多教程喜欢把HER说得高深其实落地环境已经相当成熟。下面是我个人实践推荐的组合OpenAI Gym的机器人环境、stable-baselines3自带的HER实现、SAC作为底层算法。这套方案能让你在半天内跑通一个稀疏奖励任务。3.1 环境与依赖选择首选是Fetch系列环境比如FetchReach-v1、FetchPush-v1、FetchPickAndPlace-v1。这些环境里机器人需要把末端执行器移动到一个目标位置或者把物体推到指定位置。它们自带achieved_goal字段接口完全匹配HER需求省去自己改环境的麻烦。依赖方面需要三个核心库gym、mujoco或者mujoco-py、stable-baselines3。需要注意Fetch环境依赖MuJoCo引擎而MuJoCo在不同版本下的安装方式不一样。如果不想被MuJoCo折腾可以自己写一个简单的二维点导航环境只要能输出observation、achieved_goal和desired_goalHER照样能跑。我强烈建议第一次接触HER的人先用二自由度点目标任务调试成本低可视化清晰能够直接观察策略是否学会了朝目标移动。等流程通了再切到Fetch环境排查问题会方便很多。3.2 在DQN/SAC等算法上接入HER的步骤stable-baselines3里接入HER非常直接。我以SAC为例from stable_baselines3 import SAC from stable_baselines3.her import HerReplayBuffer from stable_baselines3.common.env_util import make_vec_env vec_env make_vec_env(FetchReach-v1, n_envs1) model SAC( policyMultiInputPolicy, envvec_env, replay_buffer_classHerReplayBuffer, replay_buffer_kwargsdict( n_sampled_goal4, goal_selection_strategyfuture, ), train_freq4, gradient_steps8, learning_starts10000, verbose1, ) model.learn(total_timesteps200_000)几个参数需要特别解释一下。replay_buffer_class指定使用HerReplayBuffer这是关键中的关键。如果漏了它SAC会把字典形式的observation当普通数组处理直接报错。n_sampled_goal4表示每条轨迹除了原样存入外再额外生成4份重标注样本。这个数字不是越大越好我测试下来4到8之间比较平衡。goal_selection_strategyfuture选择future策略因为它在大多数任务里都比final好。train_freq4和gradient_steps8代表每4步环境交互做8轮梯度更新。HER生成的数据多所以需要比普通SAC更多次梯度更新来消耗样本。很多新手只调学习率不调这两个参数结果训练极慢。3.3 关键超参数设置与经验法则如果你要用自己的环境超参数需要重新调节。以下几个参数几乎每次都要动参数建议范围作用我的经验n_sampled_goal2~8每条轨迹重标注次数太少提升不明显太多训练慢future策略时间跨度当前步到轨迹末尾替代目标的来源跨度太远会学得过散回放缓冲区容量100k~1M存储经验稀疏任务建议买大尽量1Mlearning_starts1k~10k预热随机探索太小容易陷入错误经验还有一个容易被忽视的点目标不要取单一状态最好把需要的变量全部拼接进目标向量。比如FetchPickAndPlace里目标包括物体位置和末端位置如果你只设置物体目标模型不知道“手要靠近物体”学起来很累。目标向量信息越充足HER越容易画出从起点到目标的可行通道。3.4 复现过程中我踩过的坑第一回放缓冲区和策略不匹配。我一开始把普通ReplayBuffer传给SAC再用Dict观察空间结果程序直接炸。原因很简单HER需要额外保存achieved_goal和desired_goal普通缓冲区没有这个字段。第二环境返回的observation必须严格区分observation、achieved_goal、desired_goal三部分。很多第三方环境喜欢把目标也塞进observation里导致重标注时算不清奖励。只要出现训练波动特别大第一反应就是检查这三个字段是否重复。第三n_sampled_goal设到16训练变慢而且性能反而下降。因为重标注样本把同一个轨迹反复强化多样性和牺牲了。后来我改成4效果反而更稳。这个经验不一定适合所有任务但大多数人不需要大N。第四总有人问HER能不能用于on-policy算法比如PPO。答案是不能直接接因为HER依赖经验回放PPO每条数据只用一次重标注的意义就不大了。如果想在on-policy上享受后见之明一般得改造算法框架复杂度高很多不建议新手碰。4. 后见之明的另一面不只在算法里也在日常复盘和产品中如果把HER仅仅当成算法库里的一个类那就太可惜了。我后面越来越觉得目标重标注是一种通用思考模型。团队复盘、个人成长、产品迭代本质上都是把过去的事情重新解释成对未来有用的经验。4.1 从算法到工作流把“事后回放”变成团队复盘习惯标准复盘流程一般是回顾目标、评估结果、分析原因、总结规律。听起来和HER的流程很像但有一个致命差别很多团队分析原因是冲着“追责”去的把目标钉得死死的。HER给我们的启发是复盘时不妨做一次目标重标注——如果这次实际达成的结果是一个合理目标那我们对这次行动的评估会有什么变化举个例子。团队做了一个客户增长活动目标是新增5000个注册用户最终只新增了2000个。按原始目标看这是失败。但如果换个目标角度这次活动验证了“通过内容投放能获取超过2000用户”的假设还跑通了一套内容审核流程。下一次发起增长活动时这个经验比“失败”两个字有用得多。复盘时我会让团队做一个“HER加练”在正常结论旁边额外写一条“假如我一开始定的目标是实际发生的这个结果这次行动让我学到了什么”。这个动作强制大家用建设性视角重新审视数据避免陷入自责和甩锅。4.2 案例拆解一个项目延期后的hindsight复盘项目延期是团队复盘里最常见的场景。假设一个APP功能原计划4周上线结果延期2周。常规复盘大概率得出“预估不足、需求变更多、开发效率低”等结论。这些结论没错但不足以改变下一次。用HER思路换一版。记录原始目标6周上线含缓冲。实际结果8周上线但顺手完成了一个数据埋点体系和一个内部代码生成工具。重标注后的目标是“8周内上线并且验证数据埋点体系能支持后续迭代”。按这个目标项目其实是成功的。那么下一阶段要做的事情就变成保持新工具复用、把埋点体系文档化、为下一次更高复杂度项目留出更充裕缓冲。这不是强行自我安慰而是把注意力从“为什么没赶上”转移到“我们确实走了哪些有效的路”。技术里叫credit assignment信用分配团队里叫归因。HER的做法是不把奖励只看成终点而是把轨迹上每一步对“某个有效目标”的贡献都赋上价值。4.3 个人成长中的后见之明如何避免“事后归因”陷阱后见之明在心理学里有另一个名字叫“事后偏差”指人们在知道结果后倾向于认为结果本来就可以预料。这和算法里的HER完全相反。HER是客观地把实际状态当作目标来学习而事后偏差是主观地把不确定性伪装成确定性。个人复盘时要警惕这一点。比如“当初我就觉得这个方向不行”——这类结论没有训练价值。真正有价值的是写下当时看到的信息、能做的选择、实际的结果然后问自己“如果换一个决策规则面对类似信息时会不会有更好结果”。这才是算法的诚实版。我给自己设了一条规则复盘时禁止使用“其实我早就知道”这类句式。一旦出现就说明我在强化错误归因而不是提取有效经验。要逼自己在事后重新找一个“实际达到但没被正视的目标”然后认真复盘这个目标下的路径。这个习惯我坚持了两年对判断力的提升比看十本方法论书都管用。5. 常见问题与排查技巧实录最后把我在实践HER过程中遇到的高频问题整理成速查表方便你踩坑时快速定位。5.1 训练不收敛问题出在哪如果训练曲线完全一动不动先检查奖励是否始终为零。HER再强大也需要一定数量的初始探索样本来提供有效的重标注基础。假如智能体永远停在初始状态没有任何状态变化重标注也无法变出有效目标。这时要做的是降低任务难度比如缩短初始距离、减少动作范围让随机策略能探索出一些不同状态。如果训练曲线有上升但波动剧烈通常是因为n_sampled_goal太大或者学习率太高。HER产生的样本多样性强对价值网络的拟合要求更高建议把学习率降低到原来的四分之一再把n_sampled_goal调小观察两个训练周期内的变化。5.2 HER在哪些任务上效果会打折扣凡是“目标状态定义不清”的任务HER都很难直接生效。比如对话生成、情感控制这类任务什么叫“实际达到的状态”很难形式化成向量。HER更适用于物理状态明确的场景机器人控制、导航、操控这些是它的主场。另外如果任务本身奖励空洞到连achieved_goal都无法改变HER也没戏。比如“猜一个随机数”这种非马氏任务动作与状态变化没有可学习关联重标注无从谈起。5.3 “后见之明偏差”和算法里的HER是同一回事吗不是。这个问题经常被搞混。算法里的HER是一种数据增广技巧利用最终状态重新设定目标是为了让学习过程更高效。心理学的后见之明偏差是一种认知偏见指人们在获得结果后高估了自己事前预知结果的能力。这两者的区别可以概括为HER是主动利用后见之明创造训练信号偏向于建设性而事后偏差是被动被后见之明蒙蔽偏向于自欺。理解这一点后你会发现HER给我们的启示不是“结果已知就轻松找原因”而是“结果已知时去发现当前目标之外的隐藏成就”。5.4 问题排查速查表现象可能原因解决方法训练初期完全没有信号初始探索范围太小增加动作噪声缩短初始距离训练到一半奖励突然下降回放缓冲区里旧目标分布过时灵活调整n_sampled_goal减小学习率效果不如普通算法任务奖励并不稀疏稀疏任务才适合HER稠密任务用普通算法环境报错observation维度不匹配缺少achieved_goal字段检查环境是否继承GoalEnv或自己补字段目标泛化能力差future策略时间跨度太近换episode策略或增加轨迹长度训练缓慢但最终效果还行学习率太高导致震荡学习率调低梯度步数增加多机器人任务训练不稳定共享策略但经验分布不均将多任务数据混合采样或任务切换频率调快这个表不是万能药但能覆盖大多数HER入门者的困境。真正遇到特别诡异的问题时我的习惯是先跑一个没有HER的基线确认算法本身没问题再一步步加入目标重标注这样可以快速定位是哪一环引入的异常。从做这个hindsight项目到写这篇文章我最大的感受是后见之明如果只用来自责那叫后悔如果用来重新定义目标那就成了算法。HER给了我一个很具体的工具让我认识到“失败轨迹里藏着大量可学习信号”。现在我做团队复盘时脑子里总会浮现那个重标注的伪代码每一条经验都可以换一个目标再存一遍。实际生活中的问题很少是线性的但用这个视角重新看过去很多破碎的尝试都能拼接成可复用的路径。最后再分享一个小技巧无论是训练模型还是复盘人生记得把“实际达到的状态”显式地记下来因为它往往比你设定的目标更诚实。下一次当你觉得事情搞砸了不妨先问一句如果这才是目标我学到了什么
上一篇/下一篇内容由系统自动关联
返回资讯列表 →