ARTICLE DETAIL

资讯详情

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

HER算法核心解析:用事后经验回放破解稀疏奖励难题

HER算法核心解析:用事后经验回放破解稀疏奖励难题 做强化学习落地的人十有八九都被同一个问题折磨过智能体在稀疏奖励环境里像无头苍蝇一样乱撞训练半天奖励曲线纹丝不动运气好偶尔撞上一次目标运气不好几百个episode全是零收益。这个困境的经典程度不亚于“梯度消失”而我今天想聊的“hindsight”正是针对这个问题最优雅、也最实用的解法之一。hindsight这个词本身的意思是“事后聪明”放到强化学习里它指向一种直觉既然这次没达到目标那我们能不能不把这次经验当成“失败”而是把它当成“用另一个目标换来的成功”从中提取出学习信号这套思路在2017年被Andrychowicz那篇论文正式整理成Hindsight Experience Replay简称HER算法之后迅速变成了多目标强化学习、机器人操作、导航规划等领域的标配工具。如果你想解决“智能体在稀疏奖励下学不动”的问题或者你正在做目标条件策略goal-conditioned policy相关的工作那HER就是你绕不开的一课。这篇文章我不会只念概念而是把它放在实操的炉子上烤一遍先讲清楚它为什么能解决稀疏奖励再拆开算法核心的目标重标记细节然后给出工程落地时的参数配置与训练要点最后盘点我踩过的坑和排查思路希望你读完能直接拿去用而不是停留在“好像懂了”的阶段。1. 为什么稀疏奖励让强化学习寸步难行1.1 一个连人类都会困惑的经典困境先想象一个场景你让机械臂去抓取桌面上一个红色方块并且把它放到蓝色区域。任务成功给奖励1失败奖励0。听起来很简单对吧但对一个从零开始的强化学习智能体来说这简直像是在漆黑的地下室里找一根针。它每一步的动作都是随机的机械臂可能挥来挥去方块可能被碰飞绝大部分时间它连“靠近一点”都做不到更别提把方块送到蓝色区域。真正的问题不是“它学不会”而是“它没有机会学习”。在奖励恒为0的情况下TD误差里只剩下一堆零和零的差价值网络的梯度几乎为零策略网络自然也就没有任何方向可循。你可以把这种情况理解成一个学生每次考试都拿零分试卷上没有任何批注他连自己哪道题做对了都不知道怎么可能进步很多人第一个想法是那就奖励它“靠近目标”一点呗设置一个形状奖励shaped reward比如离蓝色区域越近分数越高。这个思路本身没有错但真正的坑在于手工构造奖励函数是一门玄学需要大量调参和领域知识。你说“靠近”要如何量化距离用什么范数连续奖励的尺度怎么跟稀疏的成功奖励平衡稍微没设计好智能体就会钻奖励函数的空子比如原地转圈、抖动臂膀甚至把方块推走只要能刷出更高的累积分数它就干。1.2 从“事后诸葛亮”到算法设计hindsight的诞生逻辑正是因为这个窘境Andrychowicz他们才提出一个极其反直觉的念头如果一个回合没有达成设定的目标那我们就把这个回合“实际达成的末端状态”当作目标重新构造一个成功样本。说得再直白一点机械臂没能把方块放到蓝色区域A但它在过程中把方块推到了位置B。这个回合如果以A为目标是彻头彻尾的失败但如果把目标临时换成B那这个回合就是彻头彻尾的成功——机械臂确实把方块送到了B。我们把这条经验重新标记一下扔进回放缓冲区它就成了一个带正奖励的训练样本。这个思想之所以叫hindsight就是因为人类自己经常这么干。回想一下你打篮球原本目标是“三分线外直接投进”结果球砸到篮板弹进了一个奇怪的抛物线你虽然没完成任务但你会反思“原来这种弧线能进”而不是把那一次出手经历完全丢掉。智能体也一样它不需要永远只盯着最初的那个目标它可以从每一次“偏离目标”的行动中提取出“如何达成另一个目标”的经验。有人可能会疑惑这难道不是在骗自己吗换个目标算成功这不等于自欺欺人其实不是。关键在于HER并不把“改写后的成功样本”当作原始任务的直接胜利而是把它当作一个辅助训练信号。在这个辅助任务上智能体学会的是“给定某一个目标状态我能做出什么样的动作才能达到它”。这种通用的目标条件映射关系最终会反过来帮助它在原始目标上表现更好因为它对状态和动作的因果理解更深了。2. HER算法核心拆解目标重标记是怎么运转的2.1 数据结构与重标记的完整流程HER不是独立于某个强化学习算法的完全新算法它是一种通用的经验回放技巧可以和DQN、DDPG、TD3、SAC这类离线策略算法搭配使用。它的大前提是你的任务可以被描述成“目标条件任务”也就是状态空间里有一个额外的目标向量g而策略π(a|s, g)要根据当前状态s和目标g来决定动作。在一个episode中智能体从初始状态s0出发带着一个真实目标g不断与环境交互得到轨迹τ (s0, a0, r0, s1, a1, r1, ..., sT-1, aT-1, rT-1, sT)。按常规做法这条轨迹会被拆成一条条四元组(s_t, a_t, r_t, s_{t1})存入回放缓冲区配合(s_t, g)一起作为训练样本。HER的关键改动是在这一步它不会只存原始目标g下的样本还会对轨迹中的每条transition做一次“目标重标记”。怎么重标记拿到这条轨迹之后随机选一个时间点t把“事后真实到达的状态s_{t}”当作新目标g然后重新计算每个transition的奖励r reward(s_{t1}, g)。如果s_{t1}恰好等于或足够接近g那r就是正奖励。这样处理之后原来整条零奖励轨迹里就涌现出大量带正奖励的成功样本。这里有一个很重要的细节新目标g是从“本回合后来某个时刻的状态”里选的而不是随便从整个回放缓冲区里抽。这样做的好处是重标记后的样本仍然保持了时间上的真实性——智能体确实曾经从当前状态到达过那个目标所以这条目标是可达的不包含“画饼”式的幻觉目标。2.2 四种目标重标记策略的区别与选择目标重标记的关键参数是“从哪些状态里挑选新目标”。论文里给了四种策略随机策略random从回放缓冲区中随机抽取一条历史transition的状态当作目标。这个方法不依赖于当前轨迹目标多样性最强但坏处是很多随机目标在当前状态下根本不可达学起来效率低。最终策略final只用这个episode的最终状态s_T当作新目标。实现最简单而且只标记一次计算开销最小但目标种类太单一如果轨迹最后一步状态比较雷同样本多样性就不够。时间线策略episode从当前episode的任意一个后续时间步里选一个状态当作新目标。这条路径比random更可控比final更多样是很多工程实践里比较稳的选择。未来策略future这也是论文里实测效果最好的一个——从当前transition之后的一段窗口内比如之后k步随机选一个状态作为目标。它兼顾了“可达性”和“多样性”目标在当前状态之后的真实轨迹中说明确实能走过去而窗口内有多步可选又保证了目标不是唯一的终点。我自己的使用经验是默认优先选future策略其中k的取值一般在4左右。如果你的环境里目标空间特别复杂或者轨迹特别长可以适当增大k但不要大到接近整个episode的长度否则就几乎退化成final策略了。2.3 为什么事后目标能产生真实的梯度信号从数学角度理解HER会发现它的实质是把原本稀疏的奖励函数在经验回放阶段做了一次隐式的“奖励塑形”。你用一条失败轨迹重新定义了新目标的奖励等价于在目标空间上构造了一条连续的“学习路径”让智能体一步步学会从随机状态走向某个目标。更具体地说原本对g的期望奖励是r(s, a, g)它只在极少数state-action对下非零。而经过重标记后你得到了一批奖励非零的样本对(s, a, g)。这些样本虽然不在原始任务的最优路径上但它们提供了“在这个状态下采取这个动作能使智能体更接近某种状态”的信号。策略网络学习的就是这样一个通用的“状态-目标-动作映射”。所以HER并不是在降低任务难度也不是在弱化奖励信号而是在用一套自动构造的“伪成功样本”弥补探索初期无奖励信号可学的真空期。等到策略网络对目标条件的映射已经有了一定把握它自然会提升原始目标上的命中率而原始目标上的命中又会生成更高质量的真实成功样本形成一条良性循环。3. 实操落地从算法到可复现的训练配置3.1 环境选型与基线设定如果你想快速验证HER的效果我建议从Bitflipping环境开始。这个环境简单得可以用一句话概括有一个n位的二进制向量初始状态是随机生成的某个位模式目标是要把状态变成另一个随机指定的位模式只有完全匹配才给奖励1否则奖励0。n20或n30时随机尝试的成功概率几乎为0而HER在这个环境上能快速达到接近100%的成功率是测试目标重标记逻辑的理想沙盘。有了这个基线之后再去挑战更复杂的机器人操作环境比如FetchReach、FetchPush、FetchPickAndPlace这些MuJoCo任务。它们的共同特点是状态空间大、动作连续、接触动力学复杂、目标空间由三维坐标描述。这类任务最考验HER落地的细节也是论文中机器人抓取效果的核心展示场景。我要提醒一句不要在还没有基线结果的时候就急着上分布式框架或者调并行度。先把单机单卡、小规模网络跑通确认HER确实让成功率曲线起来了再考虑扩展规模。我见过太多人一上来就上Ray、上多进程结果环境串口的bug、buffer竞争的bug、状态归一化的bug全都堆在一起最后根本分不清是HER的问题还是工程架构的问题。3.2 网络结构、超参数与训练策略的关键选择HER通常搭配DDPG或SAC这类连续控制算法网络结构上不需要太花哨。Actor和Critic各用两到三层的MLP即可每层256到512个神经元激活函数ReLU或Tanh都行。真正值得花心思的是状态和目标的编码方式很多环境里状态维度和目标维度不是一回事比如机械臂的关节角加末端位置目标是末端位置你需要把目标和状态拼接起来作为网络的输入并且确保它们各自做了归一化。下面是几个关键超参数的选择思路每一条都是我实测踩出来的经验经验回放缓冲区的大小要足够大。HER的样本中包含了大量重标记后的数据缓冲区至少要能容纳几十万个transition否则多样性会被打折扣。我常用的是1e5到1e6的量级。重标记比例replay ratio的意思是在训练时从一个batch中采的样本里有多少比例来自重标记后的目标。论文里常用的做法是先存一份原始目标版本的样本再为同一个transition存1份重标记版本的样本相当于1:1的比例。如果你把重标记比例提高到2倍或3倍训练可能更快但也要小心策略过于偏向“辅助成功任务”而忽略原始任务。未来策略的k值不要拍脑袋定。k代表从当前transition往后数k步的范围内随机选目标。k太小时目标距离当前状态太近学习信号弱k太大会丢失“近期可达”的优势。我一般先设k4跑几十万步看曲线如果成功率曲线迟迟不涨再往大调。除了上述参数还有两个容易被忽略的地方第一个是取目标时的距离阈值。很多环境里reward函数是用“目标距离小于某个值”来判定的重标记后也要沿用同样的判定逻辑千万不要自己在重标记代码里另写一套距离判断否则会出现奖励不一致的幻觉样本。第二个是目标向量的范围如果目标空间数值范围很大且分布不均匀务必做归一化否则Critic网络很难在目标维度上泛化。3.3 评估方式别被平均成功率骗了评估HER训练效果时一个常见的误区是只盯着训练过程中的平均奖励。由于HER会在训练时注入大量重标记的成功样本平均奖励曲线看起来很可能虚高。更靠谱的做法是每隔固定步数关闭探索噪声让策略以完全确定性方式去执行原始目标统计成功率。具体来说你可以每训练5000步就暂停一下用当前策略跑100个回合每个回合用随机生成的原始目标记录“是否达成”并计算成功率。这样画出来的曲线才是真实能力的反映。我自己的项目里会把这两种曲线都打出来一条是训练时的reward曲线用于调试网络是否稳定另一条是离线评估的成功率曲线用于判断任务的真实完成情况。另外一个评估细节是成功率曲线震荡很常见不要因为单次评估掉了一点就急着改参数。为了减少噪声对连续若干次评估取滑动平均或者每两次评估之间间隔更大一点都会让你更容易看出真实趋势。4. 常见问题与排查实录4.1 训练不收敛先砍问题规模再谈技巧HER虽然强大但它解决的是“稀疏奖励下没有学习信号”的问题不是“任何任务都能硬学”的问题。如果你上了HER之后成功率曲线仍然一条直线我建议你先做一个自检把目标空间和状态空间的可达性画出来看看初始化时随机策略能覆盖多大的区域。最容易出现的情况是你的环境里目标分布太广而随机策略几乎不可能触达大多数目标这时HER重标记出来的目标虽然都存在但都是“近处的目标”无法为“远处的原始目标”提供任何指导。这种时候不要盲目堆算力先把问题拆小——比如缩小初始状态的随机范围、减少任务里目标的自由度、或者给目标空间做一个课程排序从近到远逐渐加大难度。还有一个小技巧当训练不收敛时把目标重标记比例调到0先看“不使用HER”的基线能不能在奖励塑形下学到一点点东西。如果连基线都完全学不动那通常说明问题出在环境设计或奖励函数本身而不在HER的配置上。4.2 样本利用率低回放缓冲区的平衡难题HER的初衷就是提升样本利用率但如果缓冲区里重标记样本的比例过高也会带来新的问题策略开始过度拟合“伪目标”在原始目标上反而变笨。这种症状通常表现为原始目标的成功率曲线涨到某个阈值后回退同时重标记样本的TD误差显著小于原始样本。要解决这个问题你可以做两件事一是调整重标记比例不要让重标记样本在batch中占据压倒性的份额二是训练时对原始目标样本和重标记样本分开统计TD误差发现原始样本的误差远远大于重标记样本时说明策略已经偏向“简单模式”需要把原始样本的权重提上来或者增加探索噪声让策略多接触原始目标的失败轨迹。4.3 目标重标记比例怎么调关于“重标记比例”这个参数很多论文里写的是1比1但实际工程中这个值并不需要永远锁死。我的建议是把它当作一个可调旋钮任务初期可以高一点比如1份原始配2份重标记让策略尽快从失败轨迹中学习基本的目标条件映射训练中后期再逐渐降回1比1或更低让原始目标的真实成功样本在训练中占据主导。曾经遇到过一个实际案例某个导航任务中我把重标记比例设为1比3训练速度确实快但策略学会的只是“从任意位置回到上一个位置”完全没有向远处目标推进的能力。把比例降回1比1并增加future窗口范围后远处的原始目标才开始有命中率。这说明了一个更深的道理HER不是一个“越多越好”的魔法它的本质是设计一个辅助任务分布辅助任务分布必须跟原始任务保持一种“既相关又有差异”的关系。离得太近无法外推离得太远没有学习价值。5. hindsight思维的迁移不止是算法也是工程方法论5.1 从智能体到个人项目复盘机制的普适价值我做了几年强化学习相关项目之后越来越觉得hindsight这个字眼不只是算法层面的设计灵感它在工程管理甚至个人成长里也有强烈的映射关系。想想看我们在做项目时是不是经常把“完成既定目标”当作唯一的成功标准如果上线没达到预期指标这个项目就被判定为失败经验教训也被一笔带过。但实际上那段“失败”的探索过程中往往积累了关于系统瓶颈、用户习惯、基础设施短板的大量一手信息。就像HER把“未达成的目标”重标记为“实际达成的状态”一样项目复盘也可以换一套评价体系不是只问“我有没有做完A”而是问“这段经历让我到达了哪个状态B我对B的了解有多少”。我自己在带队做算法项目时养成了一个习惯每次周会不只看实验结果曲线还会单独留一个环节讨论“这个星期我们虽然没有解决某个问题但是我们确认了哪几条路是走不通的或者意外发现了哪个现象”。这些信息看似是失败样本但在长期视角下它们大大缩短了后期搜索的空间跟HER采样中“从失败轨迹里提取可达目标”的逻辑如出一辙。5.2 把“事后视角”变成可执行的动作当然光有理念不够还得变成可执行的机制。我个人在工程中会做三件事。第一每次跑完一组实验我不只保存最终的模型和曲线而是把训练过程中的“失败轨迹”也抽样存下来。这些轨迹配合重标记逻辑能在以后分析策略缺陷时派上大用场很多时候策略在原始目标上不行但你能从失败轨迹里看出它其实很擅长完成某种“次目标”。第二我会为每个项目维护一个“意外发现清单”。比如某次机械臂实验里发现臂尖速度跟任务成功率之间有强相关关系某次导航实验里发现奖励函数稍微加一个速度惩罚项就能大幅减少原地抖动。这些都不是当期实验的直接目标但在后来的迭代里它们往往是最有价值的一手经验。第三我给自己定了一条规则当实验结果不符合预期时先写三行“这个结果里有什么是新的、可复用的信息”然后再决定下一步动作。这个看似简单的动作其实就是把hindsight从算法映射回思维习惯——你不必每次都逼自己从失败里找价值但一旦找到了下一次实验的起点就不再是零。说实话我不是一个主张把算法概念到处套用的那种人但HER之所以让我印象深刻恰恰在于它把“事后聪明”从一个贬义词变成了一个有严格定义、可工程化操作的学习机制。它让我重新意识到经验的价值不是由“是否完成了预设目标”决定的而是由“是否能从中提取出对后续决策有用的信号”决定的。做实验也好做产品也好带着这个视角去整理每一次“失败”往往能让你走得更稳。
返回列表