4、奖励塑形技巧:稀疏奖励 vs 密集奖励,如何设计引导性奖励加速收敛
奖励函数设计,说白了就是给机器人“上课”。
你想想看,一个刚出生的婴儿,你告诉他“把积木搭好就给你糖吃”,他根本不知道“搭好”是什么意思。机器人也一样。如果奖励给得太模糊,它学得慢;给得太频繁,它又可能学会偷懒。
我个人习惯把奖励设计分成两个极端:稀疏奖励和密集奖励。今天我们就聊聊怎么在这两者之间找到平衡点。
4.1 稀疏奖励:简单粗暴,但容易“饿死”
稀疏奖励,就是只在任务成功或失败时给一个信号。比如抓取任务:
- 成功抓起物体 → 奖励 +1
- 失败(掉落或超时)→ 奖励 -1 或 0
这种设计的好处是简单、不容易被钻空子。但问题也很明显——探索效率极低。
我记得有一次做机械臂抓取实验,初始策略完全随机。机器人花了整整 3 万步才偶然碰到一次物体。那 3 万步里,它一直在空中乱挥,完全不知道自己在干嘛。这就是典型的“饿死”现象——奖励太稀疏,智能体根本不知道哪些动作是好的。
4.2 密集奖励:引导性强,但容易“作弊”
密集奖励,就是每一步都给反馈。比如:
- 夹爪离物体越近 → 奖励越大
- 夹爪张开角度合适 → 奖励增加
- 物体被提起的高度 → 奖励正比
这样做的好处是学习速度快。智能体每一步都能得到指导,知道“往左走更好”还是“往下走更好”。
但这里有个坑——奖励函数容易被钻空子。我曾经设计过一个奖励:夹爪离物体越近奖励越高。结果你猜怎么着?机器人学会了把夹爪贴在物体旁边来回晃动,就是不抓。因为它发现“靠近”比“抓起”更容易获得稳定奖励。
4.3 引导性奖励:我的实战配方
那到底怎么设计?我个人习惯用分层引导的思路。说白了,就是把一个大任务拆成几个阶段,每个阶段给不同的奖励。
以抓取任务为例,我常用的奖励结构是这样的:
| 阶段 | 奖励信号 | 权重 | 说明 |
|---|---|---|---|
| 接近阶段 | 距离物体中心 < 5cm → +0.1 | 0.3 | 引导机械臂靠近物体 |
| 抓取阶段 | 夹爪闭合且接触物体 → +0.5 | 0.5 | 鼓励正确抓取姿态 |
| 提升阶段 | 物体被提起 > 10cm → +1.0 | 1.0 | 最终成功信号 |
| 惩罚项 | 掉落或超时 → -0.5 | 0.2 | 避免无效行为 |
嗯,这里要注意:权重不能相差太大。我曾经把“接近阶段”的权重设成 0.1,把“提升阶段”设成 1.0,结果机器人直接跳过接近阶段,尝试直接去抓——当然失败了。权重比例要平滑过渡。
4.4 代码示例:一个简单的引导性奖励函数
下面是我在项目中实际用过的奖励函数片段。它结合了距离引导和任务完成信号:
def compute_reward(state, action, next_state, done):
# 提取关键信息
gripper_pos = next_state['gripper_position'] # 夹爪位置
object_pos = next_state['object_position'] # 物体位置
is_grasped = next_state['is_grasped'] # 是否抓住
lift_height = next_state['lift_height'] # 提升高度
reward = 0.0
# 1. 距离引导(密集奖励)
dist = np.linalg.norm(gripper_pos - object_pos)
if dist < 0.05: # 5cm以内
reward += 0.1 * (1 - dist / 0.05) # 越近奖励越高
# 2. 抓取成功(稀疏奖励)
if is_grasped:
reward += 0.5
# 3. 提升成功(最终目标)
if is_grasped and lift_height > 0.1:
reward += 1.0
done = True # 任务完成
# 4. 惩罚掉落
if done and not (is_grasped and lift_height > 0.1):
reward -= 0.5
return reward, done
这个函数里,距离引导是密集的,抓取和提升是稀疏的。两者结合,既不会让机器人饿死,也不会让它学会刷分。
4.5 知识体系图:奖励塑形的核心逻辑
下面这张图总结了我对奖励塑形的理解。你可以把它当作设计时的检查清单:
4.6 实战中的避坑指南
最后分享几个我踩过的坑:
- 不要用单一距离奖励:我曾经只用“夹爪到物体距离”作为奖励,结果机器人学会了把夹爪贴在物体旁边,但从不闭合。因为它发现“靠近”比“抓住”更容易获得稳定奖励。
- 奖励尺度要归一化:不同奖励项的数值范围差异太大,会导致梯度爆炸。我习惯把所有奖励项缩放到 [0, 1] 区间。
- 稀疏奖励不是越少越好:如果任务特别复杂(比如多步操作),完全用稀疏奖励会让训练时间呈指数增长。这时候适当加入中间奖励是必要的。
- 记得加惩罚项:没有惩罚的奖励函数,就像没有红绿灯的十字路口。机器人会尝试各种奇怪的行为。我一般会加一个“时间惩罚”,每步 -0.01,鼓励它尽快完成任务。
奖励塑形没有银弹。每个任务都需要你亲自调试、观察、再调试。但记住一个核心原则:让奖励信号既告诉智能体“你在正确的方向上”,又告诉它“最终目标是什么”。两者缺一不可。