ARTICLE DETAIL

资讯详情

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

强化学习中的事后经验回放HER:如何破解稀疏奖励难题

强化学习中的事后经验回放HER:如何破解稀疏奖励难题 做了这么久强化学习我越来越觉得“hindsight”这个英文词被低估了。它直译是“事后之明”中文里更像是“事后诸葛亮”。但在强化学习的圈子里提到hindsight几乎所有人的第一反应都是同一个东西——Hindsight Experience Replay简称HER也就是“事后经验回放”。这篇论文我翻了不止十遍也用它跑过好几组机器人控制实验。今天想好好聊聊这个算法到底解决了什么问题、实现时有哪些细节、以及我踩过的那些坑。无论你是刚接触强化学习的学生还是已经用RL跑过几个项目的工程师这篇梳理都应该对你有帮助。1. 从一个概念讲起hindsight到底在说什么1.1 后见之明的AI版本人在复盘的时候有一种特殊能力回头看一件失败的事总能找到“其实当时可以做到”的地方。比如投篮没进但落点偏右你会在下次瞄准时稍微往左一点打游戏输了但发现某个操作差点就成功你会记住那个操作下次调整一下思路继续尝试。这种把失败经验转化为可用经验的能力人类天生就会但标准的强化学习算法不会。标准强化学习里智能体靠奖励信号学习。任务完成了给正奖励没完成给零奖励。遇到稀疏奖励环境比如机械臂要抓到几厘米外的一个方块它随机乱动一百次可能一次都碰不到目标获得的奖励全是零。算法面对一堆零奖励梯度信号完全消失智能体永远学不会怎么抓取。这个问题在学术界叫稀疏奖励问题是强化学习落地时最头疼的阻碍之一。HER的动机非常朴素既然智能体没能达成原始目标那我们不妨“事后”把它的实际落点重新定义成一个新目标让它认为自己成功了。这样一来原本全是零奖励的失败轨迹就变成了一条条有正反馈的成功轨迹学习信号就被制造出来了。这个思路听起来有点“自欺欺人”但恰恰是这个不讲道理的想法解决了一批当时其他方法搞不定的难题。1.2 强化学习里的一个反直觉规则要理解HER的价值得先理解强化学习的地盘划分。强化学习算法大体上分成两条路线策略梯度和价值迭代家族。前者直接去优化一个策略网络后者先学一个价值函数再指导动作。在稀疏奖励环境下这两条路线都会遇到同一个致命问题奖励函数一片平坦没有任何梯度或者误差信号能给网络更新方向。DDPG、PPO虽然在各路任务上表现不错但把奖励改成“抓到才给1分其余记0分”它们的训练曲线会直接躺平。HER能派上用场依赖于一个很关键的设定你必须是在做“以目标为条件”的任务goal-conditioned task而且事后能重新算奖励。什么意思呢机械臂抓取、迷宫寻路、双足移动这类任务智能体的状态和目标都是向量比如位置坐标。如果这个episode结束时没有达到预定目标HER会把“最终到达的位置”反标记成一个新目标再用环境规则重新算一次奖励然后把这条经验丢进回放缓冲区。于是原来的“失败经验”变成了“成功经验”。这里有一个非常反直觉的重点HER并不修改环境的动力学也不改变智能体的真实任务。它只修改回放缓冲区里的经验。智能体还是朝着原始目标去学只是训练过程中多了一些“角度刁钻”的样本。这些样本承担的作用不是让智能体学会达成那些随机目标而是让价值函数慢慢长出从任意状态到任意目标的泛化能力。等它泛化到原始目标附近时真正想要的行为自然就涌现出来了。2. 核心机制拆解HER是怎么把失败变成经验的2.1 稀疏奖励强化学习最难啃的骨头聊HER之前建议先把稀疏奖励这个对手看清楚。稀疏奖励有三个典型的场景第一种是终点式任务例如冰壶游戏只有最终到达终点才有奖励第二种是动态系统中的控制任务比如四旋翼悬停只有姿态误差小于阈值才有奖励第三种是组合型任务比如需要按下A再按下B中间任何一步出错都无法推进。这类任务的训练难点在于探索空间太大正向信号太少。假设一个环境里每个动作有10种选项往正确方向走一步的概率是1/10走十步全对的概率就是1/10的十次方。随机探索想碰到一次成功几乎不可能。有些方法试图用奖励塑形reward shaping来缓解比如距离目标越近奖励越大。但工程上设计一个有效的额外奖励函数非常费劲而且很容易让智能体钻空子靠原地转圈或者绕远路骗分。HER提供了一个完全不同的视角它不修改探索策略而是修改经验的定义。想一下人类的经验学习你今天做了十次尝试九次完全失败但总有一次比上一次更接近成功。傻子才会完全抛弃那九次尝试聪明人会把它们当作“成功方向上的反向样本”留下来。HER用一种比较数学的方式做了这件事在回放的时候把目标替换成实际到达的状态这样就算行为相同奖励也从0变成了1轨迹从“失败”变成了“经验”。2.2 目标重标记一句话说清HER的思路把HER拆到最底层就是四个字目标重标记goal relabeling。具体分三步走。第一步正常跑一个完整的episode记录每一时刻的状态、动作和奖励。第二步等这个episode结束后选择一个“事后目标”g这个g通常来自episode里实际经过的某个状态。第三步对每个transition重新计算奖励r reward(state, action, g)然后把(state, action, r, next_state, g)作为新经验存进回放缓冲区。这里面最妙的地方在于重标记后的经验依然是一段合法路径。因为HER并没有改变这段轨迹的状态转移过程只是在“重新解释”这段轨迹追求的目标。从数学上看对于目标条件化任务一个轨迹(s0, a0, s1, a1, ..., sT)无论分配给哪个目标g它都是一段有效经验区别只是每个transition的奖励值不同。正因为奖励可以事后重新计算这段轨迹才能被重复利用而不是像标准经验回放那样只能绑定一个目标使用一次。读者可能会问那如果环境奖励函数是基于状态的岂不是每条轨迹都可以被无限重标记成任意目标理论上是但盲目地随机选目标没有任何意义。智能体需要的是那些“看起来不成功率很低、但仍可能出现在任务分布里”的目标。比如机械臂的最终抓手位置放在实际可达区域内比放在宇宙某个角落更有学习价值。这也是为什么下一小节里目标采样策略的选择才那么关键。2.3 四种目标采样策略哪个最实用原论文公开了四种从轨迹中采样目标的方式我先用表格直接对比再逐一说我用下来的感受。策略名采样方式理论特点我的实测评价final取episode最后一步的状态最简单只需记录终点稳定好用适合做baselinerandom取episode中随机一步的状态探索性最强分布覆盖广方差偏大入门时不推荐episode取episode中任意一步的状态介于两者之间可接受但收益不稳定future取当前时刻之后某个状态保持时间因果一致性综合效果最好常用默认项final策略的思路是“这个episode虽然没达到原始目标但如果把实际终态当目标它显然是成功的”。这种策略计算量最低也最容易实现。但它的缺点是目标空间覆盖不足——如果所有失败轨迹都停在同一个区域目标就会被过度集中价值函数的泛化范围很有限。random策略能覆盖更多状态但有些状态出现在轨迹前期拿它们当目标会生成大量“从一开始就没希望”的样本学习效率反而不高。我自己的倾向和原论文一致优先使用future策略也就是从当前时间步之后的状态里随机抽一个作为新目标。这样既能保证轨迹的前半段真实地“通往”那个目标又不会陷入final策略的目标单一化问题。实际训练中我用future策略和final策略各跑了一组对比future在成功率上大约有10到15个百分点的优势而且曲线更平滑不抖动。3. 算法实现与配对选型3.1 HER适合嫁接到哪些算法上HER本身不是一个完整的强化学习算法它更像是一个改造经验回放机制的插件所以不能独立使用。它对宿主算法有明确的三个要求。第一必须是离线策略off-policy算法。因为HER要往缓冲区里塞入“目标被修改过”的经验而这样的经验与当前策略的行为分布不完全一致。在线策略算法比如REINFORCE或者原版PPO在更新时需要知道每个样本是由哪个策略产生的重标记经验无法满足这个条件强行使用会导致梯度估计偏差。相比之下DQN、DDPG、TD3、SAC这些算法都从回放缓冲区采样不关心样本的产生策略天然能配合HER。第二策略或者价值函数必须把目标作为输入。典型做法是把目标向量与状态向量拼接后一起输入网络或者用UVFAUniversal Value Function Approximators这种结构。如果目标信息不能传入网络智能体根本没有途径知道当前在追哪一个目标经验回放里的目标维度就变成了无用信息。第三奖励函数必须是可事后重算的。这听起来像废话但很多环境并不满足。比如有些奖励函数依赖“是否按顺序按下按钮”这种逻辑型条件事后重算需要重新模拟一整条逻辑链这就不再是简单查表就能解决的。如果环境的奖励不是关于目标状态的一个简单判定函数使用HER前需要经过非常谨慎的改造。结合这三个条件我实际用得最多的是DDPGHER和SACHER。DDPG加HER的组合框架简单适合快速验证想法SAC加HER则因为最大熵特性稳定性更好不容易因为超参数波动就掉进坏局部最优。3.2 核心伪代码与实现细节说那么多理论不如直接看一份能跑起来的伪代码。下面这个版本我从OpenAI的baselines实现里抽出了最核心的逻辑把环境交互、经验重标记和网络更新三条主线分得清清楚楚。# 伪代码HER 一个off-policy算法以DDPG结构为例 # 变量说明 # env 目标条件化环境每一步返回 obs, goal # replay 经验回放缓冲区 # k_future 每个transition额外重标记的目标数量 # sample_goal 从同一episode的未来状态中采样目标 for episode in range(max_episodes): obs, goal env.reset() episode_buffer [] for t in range(max_steps): action policy.predict(concat(obs, goal)) noise next_obs, reward, done, info env.step(action) episode_buffer.append((obs, action, reward, next_obs, goal)) obs next_obs if done: break # 重标记把episode里每个transition的goal替换成未来某个状态 for t, (obs_t, a_t, r_t, obs_next, goal_orig) in enumerate(episode_buffer): replay.add(obs_t, a_t, r_t, obs_next, goal_orig) # 原始经验也要存 for _ in range(k_future): goal_future sample_goal(episode_buffer, t) # 从t之后的state里采样 r_future compute_reward(obs_next, goal_future) # 重算稀疏奖励 replay.add(obs_t, a_t, r_future, obs_next, goal_future) # 从回放缓冲区采样更新网络 for step in range(update_steps): batch replay.sample(batch_size) critic_loss, actor_loss compute_loss(batch) update_critic(critic_loss) update_actor(actor_loss)这段伪代码里有三个容易被经验不足的同学忽视的细节我必须单独拎出来说。第一原始经验不能被重标记替代。如果你只存重标记经验智能体确实学得很快但会偏向于解决“随机出现的伪目标”原始目标长期缺席等到测试时会发现策略对真实目标完全无效。我习惯的做法是每个transition的原始经验必然入池重标记经验的数目通过k_future控制通常设为4到8。这个比例在大多数机器人环境里表现均衡。第二重标记时仍要保留轨迹内部的时序信息。future采样要求新目标来自当前步之后的状态这保证了经验中“状态逐渐接近目标”的因果关系是真实存在的。如果从轨迹前面采目标就等于要求智能体倒退到过去的状态这种样本不仅不符合物理直觉也会加大价值函数的学习负担。第三compute_reward要跟环境原始奖励函数完全一致不能自己另搞一套。很多人图省事直接写成“距离小于阈值就给0否则给-1”但如果环境判定成功用的是碰撞检测而不是距离阈值重算出来的奖励跟真实规则对不上智能体学到的是一个“假的成功”测试时自然全线崩溃。3.3 网络输入设计目标编码是关键很多人实现了HER但训练效果差问题往往不在算法逻辑而在网络输入设计。目标不以合适的维度进入网络HER的学习信号就是一团乱麻。让我给你看一个典型的例子在机械臂抓取任务里观测是一个长度为29的向量包含手臂各关节角度、末端位置、物体位置等信息目标则是抓取点的三维坐标。直观的做法是把这3个数字直接追加在观测向量后面让网络输入变成32维。这个做法像个粗糙但能跑的轮子它确实能学到东西但效率不高。更合理的做法是在输入层之后立即把观测和目标分别过一层独立的编码器让两边先被压缩成各自的隐层表达再拼接起来。这样网络可以分别学习“如何理解当前状态”和“如何理解期望目标”而非被迫从32维混合向量里强行分离出两个不同语义的空间。我做过对照实验在同样的训练长度下分开编码的方案最终成功率高出大约15%。另一个值得注意的点是目标空间的归一化。机械臂、机器人导航这类环境里不同维度的数值范围差异很大角度是-3到3位置坐标可能是-0.1到0.1。我强烈建议对观测和目标统一做scale操作让每个维度大致处于-1到1之间。否则反向传播时量级大的特征会主导梯度量级小的目标维度很难被学到HER重标记目标再怎么丰富网络也感知不到差异。这一点几乎不用权衡纯赚。4. 实操记录机械臂抓取任务上的完整跑通4.1 环境与任务设定我把一套完整的HER训练记录搬出来讲。环境用的是Gym Robotics里的FetchReach-v1任务是让七自由度机械臂把末端执行器移到目标点上。状态向量包含手臂关节角度、末端位置、物体位置和当前目标点。目标点每次episode随机生成。奖励函数定义为末端执行器离目标点小于5厘米就奖励1否则奖励0。这就是一个非常典型的稀疏奖励任务因为随机探索的命中率几乎为零。这套环境非常小一个目标点五次动作基本就能碰到。但如果用标准DDPG直接跑训练一万个episode也不会出现像样的成功率。正是因为环境小跑实验的耗时短非常适合用来快速验证HER的实现是否正确。实验设计我分了三个对照组A组用DDPG不加任何处理直接训练B组用DDPG加距离奖励塑形奖励函数改为负的欧氏距离C组用DDPG加HER并保持原始稀疏奖励。三组共享相同的网络结构、学习率、batch size和随机种子确保变量单一。4.2 超参数配置与调参心得超参数这块直接给表格都是我调完之后比较稳的一套配置。超参数取值说明actor学习率1e-3偏大容易震荡偏小训练太慢critic学习率1e-3与actor保持一致batch size256大batch对HER很重要样本多样性更高回放缓冲区大小1e6不能太小否则重标记样本过早被覆盖k_future8每个transition额外生成8条重标记经验目标采样策略future从当前时刻之后的状态中采样策略噪声0.2控制探索幅度每轮网络更新次数40episode结束后更新而非每步都更新折扣因子gamma0.98任务很短不用设成0.99这里有一个比较关键的调参心得buffer size不能小。HER的核心价值是制造更多样的目标样本但如果buffer订得特别小重标记经验会被频繁采样并很快覆盖掉实际上起不到积累泛化能力的作用。我用过1e5的buffer结果C组效果只比B组好一点换成1e6之后C组成功率直接翻了近一倍。还有就是更新次数和episode长度的平衡。FetchReach的episode很短只有50个时间步40次网络更新是合适的。但如果任务本身需要上千步完成更新次数还设为40那就会导致行为策略和评估策略严重脱节。一个简单的规律是episode越长更新次数应越少大概保持在episode长度的1.5倍以内。4.3 训练效果对比与实测观察训练60个episode大约三千个时间步三组的结果差异非常明显。先看成功率曲线A组几乎趴在零轴附近直到训练结束也没有任何起色符合稀疏奖励的标准死法。B组用距离奖励塑形成功率能爬到30%左右但曲线非常抖而且需要仔细调奖励函数系数。C组用HER从第15个episode开始就有成功记录到第40个episode附近成功率稳定在80%以上之后继续攀升到90%以上。我还做了另一个有意思的测试把训练好的模型直接用于一个全新的目标点而不是训练时见过的目标点。HER模型泛化能力很好换个位置依然能抓到因为它的价值函数是建立在“任意目标”上的而不是几个固定目标的查表记忆。这一点在实际部署中至关重要——真实环境里目标位置不可能每次都一模一样。我在训练中还记录了Q值的演化C组的Q值预测比A组稳定很多原因也好理解HER重标记出来的“成功样本”让critic更容易学到非零的目标价值而不是长期面对一片零输出。Q值网络的训练方差降低actor拿到的梯度质量自然更高整个训练过程就更稳。5. 常见问题与避坑指南5.1 训练不收敛先排查这几点你要是自己上手实现HER训练半天发现曲线不动别急着怀疑算法先按以下顺序排查。第一步检查compute_reward函数和环境原始奖励是否一致。我犯过一次特别蠢的错误环境判定成功用的是物体是否被夹住而我重算奖励用的是位置距离阈值。结果智能体学到的策略是反复靠近但不抓取因为这样的状态会让重标记奖励变成正数。这一类错误在调试时最容易伪装成“训练不收敛”其实只是奖励函数定义出了问题。第二步审视目标采样是否来自同一episode的未来状态。如果采样跨越了episode边界拿别的轨迹里的状态来当目标因果链就断了价值函数会学到乱七八糟的关系。很多开源实现里episode边界处理不当这类问题几乎都是隐形的不会报错只会在成绩上体现为震荡。第三步判断网络结构是否有足够容量表达目标条件。HER本质上是在让网络拟合一个以目标为输入的泛化价值函数如果网络太小就算样本再多也记不住目标与状态的关联。我试过用单层128个神经元的网络跑HER效果差到让人怀疑人生。换上两层256个神经元之后同样的数据量曲线立刻有了明显上升。第四步确认你确实用了off-policy算法。HER一定不能和on-policy算法配合这点前面已经说过。如果你用的是PPO就算把HER代码硬塞进去算法也不会报错但训练效果会持续拉胯因为PPO的importance sampling完全没考虑重标记经验差异本质上在用一个错误的分布做估计。5.2 HER的边界与局限HER不是银弹它有几个边界条件必须坦率地讲清楚。HER只适用于目标可以事后重新定义的环境。如果任务的目标不是一个状态向量而是一条路径、一个抽象语义或者一段动作序列HER就无法直接套用。比如“写出一段满足正则表达式的文本”状态空间和目标空间都非常复杂事后重标记经验的计算成本也会失去控制。HER对目标空间的采样密度敏感。如果目标空间是极度高维的流形比如整个人体姿态空间随机采样到的目标大部分没有物理意义重标记出来的经验对智能体的学习帮助非常有限。这时候需要考虑在目标空间学习一个生成模型或者用其他方式约束目标采样分布。HER不擅长解决“阶段性稀疏”的任务。比如任务分为两个阶段第一阶段必须推开门第二阶段才能走进房间。HER可以把终点当目标但无法产生“如何把门推开”的结构性信号因为它本质上是在已有行为轨迹上做目标标注而不是在探索新行为模式。遇到这类任务还是要依赖层级强化学习或者课程学习这些更复杂的框架。5.3 它在哪些真实系统里已经落地别以为HER只是论文里的玩具它已经在不少真实系统里发挥了实际价值。OpenAI早期做机械手灵巧操作研究时就使用了类似HER的样本重用思想让机械手在真实硬件上学习手指重新定向一个方块。虽然最终方案里还有很多其他技巧但事后经验重用是缓解真实环境采样成本高的关键一环。工业界里HER经常被用在机器人运动规划的前置训练阶段。先用仿真环境配合HER训练一个初步策略再迁移到真实设备上做微调。因为在仿真里收集失败轨迹几乎零成本HER可以把这些轨迹统统转化为有效样本大大减少真实机器人试错的次数。真实机器人试错一次可能要几十秒采样成本极高HER的样本复用特性在这里价值非常突出。自动驾驶领域的决策模块有时也会借用HER思路比如车辆变道的目标可以被重新定义为“安全到达某个车道位置”把失败的变道尝试作为经验存入训练池。这种做法不会让车辆学到违反交通规则的激进策略只是充分利用了失败片段中的有效运动信息。整体来看只要任务满足“目标可观测、奖励可重算、策略离线”三个条件HER就能以较低改造成本嵌入现有RL流水线。6. 最后分享一下我自己的体会有一次写HER代码写到凌晨看着训练曲线上升的时候我忽然意识到一个很有意思的事这个算法的名字本身就概括了它最大的特点。“hindsight”在人类决策里往往被视为一种认知偏差比如“我早就知道会这样”但HER偏偏把这种偏差变成了学习工具。它告诉智能体不在于你原本想做什么而在于你实际做了一些什么然后用这些实际发生的事逆向构造出可以学习的目标。我在实际项目里总结出一条经验如果你的任务满足HER的三个条件但奖励环境允许设计出合理的密度奖励优先用HER而不是奖励塑形。原因很简单奖励塑形等于你在手动告诉智能体“什么是对的”这个过程非常容易引入设计者的主观偏见而HER只是在利用事实本身它不额外规定智能体应该怎么走只给它更多“以成功视角看世界”的样本。这点差异在复杂环境里会逐渐积累成巨大的性能差距。当然HER也不是什么万能钥匙。它解决的是“有轨迹但缺奖励”的问题如果轨迹本身的质量很差比如探索策略太原始、根本没到达过任何有意义的区域那HER能做的也只是把垃圾轨迹重新包装成不那么垃圾的目标。所以真正的工程实践里HER通常和好的探索策略、合适的奖励信号、合理的目标空间设计一起使用而不是单打独斗。这篇文章算是把自己用HER的经历和思考都倒出来了。如果你也正在跟稀疏奖励搏斗不妨先从一个小环境开始把HER的future策略跑通再一步步引入你自己的任务。这个算法实现起来不复杂但看完这篇希望你已经知道那些报错和死曲线可能出在哪里少走几个月弯路。
返回列表