分阶段奖励塑形+约束多目标强化学习:稳定训练杂技机器人后空翻

发布时间:2026/10/17 12:39:30
分阶段奖励塑形+约束多目标强化学习:稳定训练杂技机器人后空翻
“奖励设计得越细机器人学得越好”——这句话在大部分任务里是成立的但放到杂技机器人身上我第一次按这个思路尝试时得到的不是优美的后空翻而是一台在仿真环境里疯狂转圈、最后把自己“甩”出去的失控体。后来复盘才明白杂技动作的时序极短、动力学耦合极强传统奖励塑形要么让策略陷入局部最优要么干脆被智能体钻了空子。折腾了几个月真正把问题解决掉的思路就是这篇要聊的“分阶段奖励塑形约束多目标强化学习”。这篇文章我会把整个方法的动机、设计框架、实现细节和真机迁移教训完整拆开适合正在做机器人强化学习、尤其是做高动态控制任务的工程师和研究者参考。1. 为什么“奖励越细越好”在杂技任务里不成立1.1 杂技动作的三个硬特征杂技机器人比如做后空翻的足式机器人、做垂直筋斗穿越动作的固定翼无人机和普通抓取、导航任务有本质区别。我把它总结成三个硬特征。第一是极短时序。整个动作往往只有几百毫秒到一两秒。后空翻从起跳到落地真正关键的姿态调整窗口可能只有零点几秒无人机做筋斗动作机翼的姿态角速度可以达到每秒几百度的量级。这意味着策略必须在极短时间内做出一系列高精度决策任何一步延迟或误差都会直接导致任务失败。第二是强动力学耦合。机器人的身体是一个多刚体系统腿部发力会影响躯干角速度躯干姿态又决定了落地的受力点。你很难把动作拆成“先把姿态调好再做下一个动作”——因为每一步都在同时影响多个状态量。这也让奖励设计变得非常棘手你奖励某个状态往往意味着隐式惩罚了另一个状态。第三是高动态范围。杂技动作中机器人会经历接近失重、超重、高速旋转等极端工况控制器必须从“低速精细调节”切换到“大力矩爆发输出”再切回“着陆缓冲”这种大范围的切换让单一策略很难自然涌现。这三个特征叠加在一起恰恰就是稀疏奖励和传统密集奖励都不好使的根本原因。1.2 稀疏奖励学不动手调密集奖励学歪了在杂技任务里稀疏奖励的本质问题是“概率太低”。比如四足机器人后空翻如果你只在“完成翻转且落地稳定”时给1那么随机探索过程中能碰到这个状态的概率几乎为零。策略梯度方法的方差本来就大在这种环境下训练基本上是随机游走几百个epoch下来奖励曲线纹丝不动。于是大家自然想到手调密集奖励。我最早也是这么做的给姿态误差一个负项给身体高度一个正项给落地速度一个负项……听起来很合理实际跑起来却遇到了更隐蔽的问题——奖励欺骗reward hacking。智能体发现只要拼命往下蹲再弹起就能骗到“高度上升”的奖励结果学出来的动作是一个高频弹跳完全不是后空翻。这背后的原因在于手调奖励函数本质上是人为定义了一个“最优路径”。但我们并不知道后空翻过程中的最优中间状态长什么样也不知道各项误差该以什么权重组合。一旦权重不合理智能体就会沿着奖励梯度找到一条“看起来分数高、实际上不是人类想要的”路径。1.3 单一标量奖励表达不了“又快又稳又安全”再进一步想杂技任务天然就是一个多目标优化问题希望动作完成度高比如翻转角度精确到位、希望姿态偏差小、希望落地冲击小、还希望时刻不超出机械安全边界。这些目标之间是矛盾的。举个直接例子翻转角度精确到位往往需要更高的角速度这会让落地冲击变大落地冲击小需要预留缓冲空间但会牺牲动作的利落度。如果我强行把这些矛盾目标加权求和成一个标量奖励等于强迫系统找出一个固定权重妥协。而且这个妥协在动作的不同阶段应该是不一样的——起跳阶段姿态误差可以放宽落地阶段却必须严格约束。因此思路必须转变不把“安全”“稳定”放进奖励里让智能体“权衡”而是把关键的安全条件单独抽出来当作约束强化学习只负责在满足约束的可行域内最大化那几个真正要优化的目标。这就是约束多目标强化学习的核心动机。2. 分阶段奖励塑形的设计框架把后空翻拆成五步来学2.1 阶段划分的逻辑不是按时间切而是按“控制意图”切提到“分阶段”很多人直觉上是按时间切片比如前0.2秒一个阶段0.2到0.4秒一个阶段。我在实践中发现这是错的时间切片的边界对策略极不友好因为机器人状态并不是恰好按时间对齐的。正确的切法是按“控制意图”划分。以后空翻为例完整的动作可以拆成五个阶段下蹲蓄力阶段重心降低、关节储存弹性势能蹬地起跳阶段腿部爆发伸展身体获得向上的线速度和翻滚角速度空中收腿翻转阶段身体收紧、减少转动惯量实现快速翻转伸展探测阶段通过前馈和反馈判断是否接近落地姿态缓冲落地阶段腿部主动柔顺控制吸收冲击并恢复平衡。每一个阶段的“控制意图”完全不同蓄力阶段要的是慢、稳、不提前触发起跳阶段要的是猛、准、力矩足够大空中阶段要的是姿态控制的主权转换落地阶段要的是柔顺和安全。2.2 各阶段奖励函数的具体写法划分好阶段之后每一阶段单独设计奖励函数。注意这些奖励函数不需要骗智能体“一步到位完成整个动作”只需要引导它完成本阶段的目标。蓄力阶段主要奖励重心下沉量惩罚提前起跳和姿态偏移。例如 r α·(z_target - z_current) - β·||roll, pitch||其中 z_target 是预定的下蹲深度z_current 是当前高度变化量roll/pitch 是躯干侧倾和俯仰。这里的 α、β 不需要很复杂关键是让智能体学到“蹲到位了再走下一步”。起跳阶段核心奖励是离地速度和目标俯仰角速度的匹配程度。可以写成 r -k1·(v_z_target - v_z)² - k2·(θ_pitch_rate_target - θ_pitch_rate)²。同时设置一个阈值只有起跳高度超过某个值才给额外加成鼓励干脆利落的爆发。空中阶段这个阶段是整个任务最难的。我建议不要直接奖励翻转角度而是设置“翻转窗口奖励”——只要翻转角度从90°到180°之间平滑推进就给稳定的正向奖励同时严厉惩罚角速度饱和也就是电机力矩达到上限且持续卡住。伸展探测阶段奖励基于角速度和预期落地时间的匹配。你可以估算剩余翻转角度和当前角速度得到一个预测落地时间奖励策略让预测时间落在合理区间。缓冲落地阶段奖励落地时刻的冲击力小、关节速度小、机身姿态接近水平。这里甚至可以引入后空翻任务里少有的“速度惩罚”——惩罚落地的接触线速度引导柔顺控制策略涌现。每个阶段奖励函数的量级不要偏差太大因为阶段切换时奖励跳变过大会让价值函数估计不稳定。我在实际代码里会在阶段切换边界附近做 5~10 步的小范围线性混合过渡效果比硬切换稳定得多。2.3 阶段切换与阶段分类器阶段划分好之后训练时如何知道当前处于哪个阶段最简单方案是用自定义状态机判断高度、角速度、接触力等阈值触发切换。比如触地传感器一旦激活就从“空中阶段”强制切换到“缓冲落地阶段”。但阈值状态机在仿真和真机之间迁移会遇到问题真机的接触力噪声、高度估计算法延迟都会导致误触发。更稳的方案是训练一个轻量级分类器输入最近几十步的状态序列关节角、角速度、接触信号输出当前阶段概率再结合阈值状态机做仲裁。我用的是一个两层LSTM加一个全连接头的小网络训练数据直接用仿真中已学会的 rollout 自动标注就好。分类器输出和阈值状态机仲裁的逻辑是只有两者一致时才切换不一致时沿用上一阶段同时给分类器标记一个异常样本下一轮继续修正。这个机制虽然不复杂但极大减少了真机弹跳时“阶段逻辑反复横跳”的问题。2.4 为什么阶段化比全过程课程学习更稳有人会问这跟课程学习curriculum learning有什么区别课程学习是让任务难度渐进但奖励函数里只有一个全局目标。比如先学慢翻、再学快翻、最后学带启动的准备动作——注意这还是用一个跨全过程的奖励在学。阶段化真正的优势是它改变了信用分配的结构。在一个阶段化的MDP里每个阶段的策略只需要对“本阶段的回报”负责每个阶段的价值函数都更局部、方差更低、收敛更快。你可以想象与其让一个agent从一堆杂乱的状态序列里学习“从下蹲到落地的整个过程哪个动作该负责”不如清晰告诉它“你现在阶段1只优化阶段1的奖励阶段2的入口条件会由阶段分类器把握”。从这个视角看阶段化本质上是一种“时间方向的任务分解”它让奖励信号不再需要穿越整个杂技动作的长时程延迟每个阶段内部的延迟窗口非常短。这是它能稳定训练的最根本原因。3. 约束多目标强化学习的核心机制安全必须写进约束里3.1 CMDP框架把“目标”和“安全”彻底分开传统的强化学习建模成马尔可夫决策过程MDP最大化长期奖励期望。而约束马尔可夫决策过程CMDP多了一组约束条件在最大化奖励的同时确保某个累积代价不超过上限。我在实现时对每个阶段都会额外维护一个或多个代价函数 c(s, a)。代价函数表达“安全边界被违反的程度”它不参与奖励优化只用来约束策略。比如关节力矩接近极限的程度质心离地面支撑多边形边界的距离落地时的垂直冲击速度机器人躯干过度倾斜的时间占比。CMDP问题可以用拉格朗日方法求解目标函数变成 max π E[Σγ^t r(s,a)] - λ·(E[Σγ^t c(s,a)] - d)其中 λ 是拉格朗日乘子在学习过程中动态调整。这个λ学习率要比策略学习率慢否则策略还没收敛约束先崩了。我遇到过的一个典型问题是λ更新太快导致策略为了满足约束而“缩”在安全状态里不动动作幅度越来越小最后完全学不出来。解决办法是约束预算 d 不要一开始就设到最终严格值而是先放松 20% 左右等策略能力涨上来之后逐渐收紧。3.2 多目标冲突怎么处理阶段内加权、阶段外约束多目标优化最常见的是加权求和法但在CMDP框架下我对“目标”做了更细致拆分真正进入奖励函数求和的通常是两到三个“相性较好”的目标比如动作完成度和能量效率而把抖动幅度、安全边界这些“相性差”的目标放进约束。以起跳阶段为例奖励函数里只有两项离地速度匹配项和俯仰角速度匹配项。而“力矩不超过限幅”“质心不提前离地”完全放进约束条件。这样做的好处是奖励面的梯度方向很清晰只是向“更快更准”的方向推代价函数则负责划一条底线。跨阶段看还有一个全局约束整个过程的累积代价总和不能超限。我一般会设每个阶段内的预算和全局总预算两层。阶段内预算给了智能体灵活分配的空间比如空中阶段可以稍微多用一点力矩但落地阶段必须预留足够的缓冲能力。3.3 约束的松弛与惩罚如何避免可行域太小CMDP最大的坑是可行域feasible region太窄导致初始化策略无法产生任何有意义的探索。特别是杂技动作起步阶段智能体随机策略几乎必然触碰安全约束如果约束设得过硬所有轨迹都被砍掉策略梯度直接消失。我的经验是采用“双层约束机制”第一层是软约束用小的二次惩罚项引导第二层是硬约束用CMDP的拉格朗日项强制。软约束只在早期阶段启用当策略训练到一定程度可以以阶段完成率超过某个阈值为标志之后软约束逐渐退场由硬约束接管。举个例子空中阶段我最初允许关节角速度超过安全限幅的惩罚项存在但超过幅度会被乘以一个较大的系数。这样agent早期可以稍微越界探索但越界代价很高不至于去走极端路线。等到它能稳定完成翻转后再把越界行为彻底设为硬约束。4. 训练流程与工程实现细节4.1 状态空间、动作空间与网络结构我的状态空间设计原则是“把能测到的都放进去但区分优先级”。以足式机器人后空翻为例状态向量包括机身姿态四元数、机身角速度、关节位置、关节角速度、上一时刻的关节力矩指令、足端接触信号。如果是无人机筋斗场景还会加上风速估计值。这里有一个容易被忽略的点奖励函数里用到的量如果状态里没有直接对应策略就会学得磕磕绊绊。比如你想奖励“离地速度”那状态里最好有质心速度的估计量而不是让网络从关节速度和姿态变化里自行反推。虽然理论上它能学出来但多一层反推意味着多一层方差。动作空间方面我建议用关节力矩/加速度指令不用位置指令。原因在于杂技动作需要的是力控级别的响应速度位置环的延迟和饱和特性会让高动态动作严重失真。网络结构我用的是带残差连接的MLP隐藏层宽度512三层。实测在这个任务规模下没有用到Transformer的必要MLP足够而且训练速度更快、真机部署更简单。4.2 算法选择与超参数为什么用PPO-Lagrangian我把PPO作为基础算法再套上拉格朗日约束项也就是PPO-Lagrangian。选PPO的原因很实际实现成熟、超参数文档丰富、对超参数不敏感而且在持续训练过程中足够稳定。SAC虽然样本效率更高但高维连续控制任务里它的熵系数调节极易影响约束满足度调试成本太高。关键超参数我列一个经验表参数值备注阶段内奖励折扣 γ0.99阶段窗口短不需要更低GAE λ0.95减少方差、保留偏差PPO clip ε0.2前后期保持一致拉格朗日乘子学习率0.005必须远小于策略学习率约束预算 d初期目标值的120%逐步降到100%阶段切换混合步数5~10 步线性混合每阶段并行环境数512CPU仿真即可每阶段训练时长约400万step视任务复杂度浮动训练顺序上我从第一阶段开始逐个训练先固定后续阶段的“演示引导奖励”不可用只让策略学第一阶段第一阶段学好之后固定其参数再开第二阶段。这里要注意每个阶段开始时都要重置拉格朗日乘子不然乘子会延续上一阶段的状态导致新阶段约束判定过松或过紧。4.3 训练中常见的失败模式奖励崩塌、阶段反复、约束震荡训练阶段我总结出三种最常见失败模式也给一下判断信号和应对方法。奖励崩塌reward collapse的表现是奖励曲线前期快速上升然后突然断崖式下降。原因通常是智能体找到了某个高奖励捷径随后陷入局部最优出不来了。判断方法如果把某一步的轨迹可视化会发现动作在特定帧序列上完全锁死。应对方法对奖励函数的稀疏度做微调减少“单帧高回报”的出现概率让奖励“平滑”而不是“尖峰”。阶段反复phase oscillation的表现是阶段分类器在两个阶段之间高频切换甚至一帧内来回跳。这通常说明阶段特征区分不够明显需要调整阶段划分边界条件或增强特征输入。如果分类器和状态机的仲裁逻辑已经启用仍然震荡我会考虑干脆放宽切换条件让状态机优先分类器只作慢速校正。约束震荡constraint oscillation的表现是拉格朗日乘子呈现周期性大起大落。这说明乘子学习率相对策略学习率太快了。乘子本来的作用是平滑地调整策略以满足约束如果它波动太快策略会被反复推来推去。解决办法一方面是调低乘子学习率另一方面是给乘子更新加一个低通滤波用指数滑动平均。5. 从仿真到真机迁移的几个关键坎5.1 物理引擎里学出来的动作为什么到真机就失灵这是所有做这块的人都绕不开的问题。仿真和真机的差异可以归结为动力学参数不准质量分布、摩擦力、关节阻尼、执行器延迟、感知噪声和延迟、以及机械结构的柔性形变。杂技任务对这些问题格外敏感因为动作本身是在极限边缘试探。一个关节阻尼误差 5% 可能在地面行走任务里无所谓但在空中翻转的毫秒级时序里就会导致姿态过冲或不足。解决思路有两个主流方向域随机化randomize dynamics parameters during training和系统辨识仿真校准。我的做法是两者结合在训练期间对质量、惯量、摩擦系数、关节摩擦力做均匀分布的随机化范围约 ±10%同时真机前用一小段系统辨识实验比如扫频激励校准关键惯性参数。不要一开始就追求模型完全精确因为随机化本身已经给了策略一定的鲁棒性。5.2 仿真到真机迁移的具体操作顺序我第一次迁移时直接拿仿真策略上真机结果起跳就翻车还把护栏撞弯了。后来整理出一套稳妥的操作流程先在纯仿真里用固定参数跑通完整动作生成“仿真参考轨迹”用系统辨识实验校准动力学参数回填到仿真环境重新训练一轮做额外的随机化训练把感知延迟也加进随机化范围比如增加30~50ms的随机观测延迟真机测试时先只测第一阶段比如下蹲蓄力确认执行器响应和状态估计精度达标逐阶段串联测试每串联一个新阶段都要回归验证之前阶段的成功率没有退化。步骤4和5容易被跳过但恰恰是避免真机损坏的关键。我有一次在足式机器人上串联起跳空中翻转时发现起跳阶段的力矩输出在真机上比仿真低了约15%导致空中翻转的角速度不够。症结在电池电压降带来的力矩衰减解决办法不是改奖励而是在训练时就把“最大输出力矩×电压系数”这个变量纳入随机化范围。5.3 真机数据如何回流修正阶段奖励真机测试会遇到一个尴尬问题阶段分类器在仿真里准确率很高到了真机却频繁误判。原因是真机接触传感器噪声形态和仿真很不一样。我的做法是收集真机状态序列回放到仿真器的“状态记录器”里做离线分析看阶段分类器在每个时刻的输出概率分布找出错误模式。然后通过两类修正一是给分类器增加真机样本做微调迁移学习用一个真实域的domain adapter二是调整阶段切换阈值比如把“触地判断”从单帧触发改成连续3帧持续触发。这一步很枯燥但每修正一个误判真机串联的成功率都会有肉眼可见的提升。6. 复现与实践中的一些心得6.1 先花一周把“失败”定义清楚如果有人要复现这个方案我第一个建议不是去抠奖励函数参数而是先把“失败”定义清楚。每个阶段都要写清楚什么条件下算成功、什么条件下算失败、失败后是否重置本阶段还是回退到上一阶段。这个定义直接影响回放机制experience replay的效率和课程进度。如果“失败”的定义过于严格正常探索中被中断的轨迹过多策略几乎没有完整体验如果定义过松智能体混过多次“半成功”轨迹学出来的动作边界模糊。我最终在每个阶段加了“成功区间”和“严格失败区间”两个阈值中间区域不计入课程推进统计。6.2 可视化优先级先看关节力矩能量曲线训练过程中最值钱的可视化不是奖励曲线而是关节力矩曲线和系统能量曲线。奖励曲线只能告诉你“分数涨了”但力矩曲线能告诉你“策略是不是在用力过猛硬掰”能量曲线能告诉你“动作是否自然”。我习惯每个阶段训练时同时绘制以下三个图各关节力矩的平均值和最大值随时间变化看是否长期贴着限幅、系统总能量和动能/势能拆分看起跳时机是否合理、阶段切换时间分布直方图看策略是不是在刻意拖延或加速通过某个阶段。如果这三个图表现正常说明策略基本走上正轨如果异常那多半不是调参能解决的而是奖励函数结构本身需要调整。6.3 这类方法还能扩展到什么方向分阶段奖励塑形约束多目标强化学习的组合并不只适用于后空翻或筋斗。我认为它最值钱的地方在于把“长程、高动态、强安全要求”的任务从“一个不可分的黑盒优化”变成“一串可解释、可调试的分步优化”。像乒乓球机器人的人机对拉、机器狗在废墟上的连续跳跃翻越、人形机器人的跌倒自恢复这几个场景都有同样的结构动作时间短、状态变化剧烈、安全边界不可妥协。分阶段奖励把每个子动作的“好坏”信号拉近约束多目标框架把“安全底线”和“优化目标”分离二者组合起来可以让训练稳定性和后期真机迁移调试的颗粒度都大大提升。如果你正要动手做这类项目我的建议是从一个足够简单的杂技动作比如单次前空翻开始先把两个机制在仿真里跑通再逐步加复杂度。第一版不要追求动作花哨先把阶段切换的边界和约束预算的中后期收紧策略跑稳后面的扩展会顺利很多。