强化学习入门:MDP框架、状态空间与动作空间、奖励函数设计原则
好,咱们正式开始第二讲。上一章我们聊了力矩控制为什么需要强化学习,这一章我们得把地基打牢。说白了,强化学习就是一个「智能体在环境里试错,通过奖励信号学会怎么做决策」的过程。你想想看,这跟训练一只狗学新把戏其实没什么两样——做对了给块肉干,做错了没得吃。
但要把这个直觉变成能跑在机器人上的算法,我们需要一个数学框架。这个框架就是马尔可夫决策过程,也就是 MDP。我当年刚接触 RL 时,觉得 MDP 就是个花哨的数学符号,后来在调力矩控制器时才发现,不懂 MDP 你连问题都描述不清楚。
MDP 框架:强化学习的数学骨架
MDP 由五个要素组成,我习惯用一个五元组来记:(S, A, P, R, γ)。咱们一个一个拆开看。
| 符号 | 名称 | 通俗解释 |
|---|---|---|
| S | 状态空间 | 机器人当前「看到了什么」 |
| A | 动作空间 | 机器人「能做什么」 |
| P | 状态转移概率 | 做了动作后,环境会变成什么样 |
| R | 奖励函数 | 这一步做得好不好,给多少分 |
| γ | 折扣因子 | 未来的奖励值多少钱 |
这里有个关键点:马尔可夫性。意思是未来的状态只取决于当前状态和动作,跟历史无关。嗯,这在实际系统中几乎不可能完全满足,但我们可以近似处理。我在做六轴机械臂抓取时,就把关节角度和角速度作为状态,虽然忽略了电机温度这种历史累积量,但效果已经够用了。
核心公式:强化学习的目标就是找到一个策略 π(a|s),使得累积折扣奖励的期望最大化。
G_t = R_{t+1} + γR_{t+2} + γ²R_{t+3} + ...
为什么会用折扣因子?因为今天的奖励比明天的奖励更确定。你想想看,如果让机器人去抓一个杯子,早一秒抓到就少一分掉落风险。γ 越接近 1,机器人越有「远见」;γ 越接近 0,机器人越「短视」。我一般设 0.95 起步,力矩控制任务里这个值挺稳的。
状态空间设计:你让机器人「看」什么
状态空间决定了机器人能获取多少信息。信息太少,学不会;信息太多,学不动。这是个经典的权衡。
在力矩控制任务中,我常用的状态包括:
- 关节角度 q:当前每个关节的位置
- 关节角速度 q̇:当前每个关节的速度
- 末端执行器位姿:如果是抓取任务,需要知道手爪的位置和姿态
- 目标位置/力:期望到达的位置或期望施加的力
我的经验:状态维度不要超过 20。超过这个数,训练时间会指数级增长。我曾经在一个七轴机械臂上用了 42 维状态,结果训练了三天还没收敛。后来砍到 14 维,半天就出效果了。
还有一个坑:状态归一化。不同物理量的量纲差异巨大——角度是 0~2π,角速度可能是 -10~10 rad/s,力可能是 0~100 N。如果不归一化,神经网络会偏向数值大的特征。我习惯把所有状态缩放到 [-1, 1] 或 [0, 1] 区间。
动作空间设计:机器人能做什么
动作空间分两种:离散和连续。力矩控制天然是连续动作空间——你给每个关节输出一个力矩值。
| 类型 | 例子 | 适用场景 |
|---|---|---|
| 离散动作 | {左转, 右转, 停止} | 游戏、简单决策 |
| 连续动作 | 关节力矩 [-10, 10] N·m | 机器人控制、自动驾驶 |
连续动作空间的处理比离散难得多。离散动作可以用 Q-learning 直接选最大值,连续动作则需要策略梯度方法。我个人习惯用 SAC (Soft Actor-Critic) 算法来处理力矩控制,它在探索和利用之间平衡得比较好。
注意:动作空间一定要做限幅。我曾经有一次忘了给力矩设上限,机器人直接打到硬限位,差点把减速器干报废。安全第一,动作边界必须硬编码在环境中。
奖励函数设计原则:给机器人「指路」
奖励函数是强化学习里最玄学、也最关键的部分。设计得好,训练如丝般顺滑;设计得不好,机器人可能学会「钻空子」。
我总结了四条原则:
- 稀疏 vs 密集:稀疏奖励(只有成功才给 +1)难收敛,密集奖励(每一步都给反馈)容易学。但密集奖励容易引入偏差。我一般先用密集奖励快速训练,再切换到稀疏奖励微调。
- 奖励塑形:用势能函数引导机器人走向目标。比如让机器人靠近目标时获得额外奖励。但要注意,错误的塑形会让机器人学会「原地转圈刷分」。
- 惩罚要适度:力矩控制里,关节超限、碰撞、抖动都需要惩罚。但惩罚太大会让机器人「躺平」——什么都不做,反而得分最高。
- 奖励尺度:奖励值不要太大,也不要太小。我习惯让单步奖励在 [-1, 1] 之间。如果奖励值动辄几百上千,神经网络会很难学。
一个实际的奖励函数例子(力矩跟踪任务):
reward = -w1 * ||τ_desired - τ_actual||² # 力矩跟踪误差
- w2 * ||q̇||² # 速度惩罚(防抖动)
- w3 * 碰撞标志 # 碰撞惩罚
+ w4 * 任务完成标志 # 成功奖励
权重 w1~w4 需要调参。我一般从 w1=1.0, w2=0.1, w3=10.0, w4=100.0 开始试。
你可能会问:这些权重怎么调?说实话,没有标准答案。我自己的做法是:先让机器人跑一个开环轨迹,看看各个项的数值范围,然后让它们量级相当。比如力矩误差项是 0~5,速度项是 0~50,那就把 w2 设成 0.1,让两项贡献差不多。
避坑指南
最后分享几个我踩过的坑:
- 奖励函数不要「太聪明」:我曾经设计了一个奖励函数,让机器人靠近目标时给正奖励,远离时给负奖励。结果机器人学会了「在目标附近来回振荡」——这样既能拿到正奖励,又不会因为远离被罚。后来我改成只奖励「稳定在目标区域」,才解决问题。
- 状态空间不要包含冗余信息:比如你同时用了关节角度和末端位姿,这两者其实是冗余的(通过正运动学可以互相转换)。冗余信息会让网络更难学。
- 别忘了折扣因子:γ=0.9 和 γ=0.99 的训练结果可能天差地别。力矩控制这种需要精细调节的任务,我建议 γ 设大一点,0.98 起步。