定义奖励函数
奖励函数是强化学习中的核心组件,它定义了智能体在环境中采取动作所获得的反馈机制。奖励可以是正值(鼓励)、负值(惩罚)或零(中性),强化学习的目标就是最大化长期累积奖励,因此奖励函数直接决定了策略的优化方向。
奖励函数的作用机制
在强化学习过程中,智能体通过与环境持续交互来寻找最优策略。在每个时间步,智能体根据当前状态选择动作,接收相应的奖励并转移到新状态。这个过程不断重复,直到达到终止条件。如果策略能够在一系列动作中获得高额累积奖励,就说明找到了较好的决策方案。
因此,奖励函数的设计对强化学习策略的优化至关重要。一个好的奖励函数应该能够:
- 准确反映任务目标
- 引导策略向期望方向学习
- 平衡短期和长期收益
- 避免奖励稀疏或过密的问题
REVIVE 中的奖励函数
REVIVE SDK 支持以 Python 源文件的方式定义奖励函数。奖励函数接收单步决策流数据作为输入,输出当前步策略获得的奖励值。
重要要求
奖励函数的名称必须为 get_reward
,这是 REVIVE 的固定接口规范。
应用示例
示例一:跳跃游戏
假设我们要训练一个智能体玩跳跃游戏,目标是跳过障碍物。奖励函数可以设计为:
import torch
from typing import Dict
def get_reward(data: Dict[str, torch.Tensor]) -> torch.Tensor:
"""跳跃游戏奖励函数
Args:
data: 包含决策流数据的字典
Returns:
torch.Tensor: 每个时间步的奖励值
"""
# 获取是否跳过障碍的状态(假设第一个特征表示障碍通过状态)
is_passed = torch.gt(data['obs'][..., :1], 0.5)
# 定义奖励值
passed_reward = 100 # 成功跳过障碍的奖励
unpassed_reward = -10 # 未跳过障碍的惩罚
# 根据条件计算每个时间步的奖励
reward = torch.where(is_passed, passed_reward, unpassed_reward)
return reward
示例二:机器人导航
对于机器人导航任务,目标是让机器人从起始位置移动到目标位置。奖励函数可以基于距离变化来设计:
import torch
from typing import Dict
def get_reward(data: Dict[str, torch.Tensor]) -> torch.Tensor:
"""机器人导航任务奖励函数
Args:
data: 包含决策流数据的字典
Returns:
torch.Tensor: 每个时间步的奖励值
"""
# 获取机器人在动作前后的位置
current_pos = data['obs'][..., :2] # 执行动作前的位置
next_pos = data['next_obs'][..., :2] # 执行动作后的位置
target_pos = data['target_pos'][..., :2] # 目标位置
# 计算距离变化作为奖励
current_dist = torch.norm(current_pos - target_pos, dim=-1)
next_dist = torch.norm(next_pos - target_pos, dim=-1)
# 距离减少为正奖励,距离增加为负奖励
reward = current_dist - next_dist
return reward
示例三:能源优化
对于能源管理系统,奖励函数可以基于能耗和舒适度的平衡:
import torch
from typing import Dict
def get_reward(data: Dict[str, torch.Tensor]) -> torch.Tensor:
"""能源管理奖励函数
Args:
data: 包含决策流数据的字典
Returns:
torch.Tensor: 每个时间步的奖励值
"""
# 获取能耗和舒适度指标
energy_consumption = data['obs'][..., 0] # 能耗
comfort_level = data['obs'][..., 1] # 舒适度
# 定义权重
energy_weight = -0.1
comfort_weight = 1.0
# 计算综合奖励
reward = energy_weight * energy_consumption + comfort_weight * comfort_level
return reward
技术要点
批量处理
在实际应用中,REVIVE 通常将多个数据按批量(batch)组织起来一次性处理,以提高计算效率。因此,奖励函数需要能够处理多维张量数据。
维度处理
在计算奖励时,我们通常关注最后一维的特征维度。使用切片操作([..., n:m]
)来获取数据的特征:
# 获取 obs 数据的最后两个特征
obs_features = data['obs'][..., :2]
# 获取 action 数据的第一个特征
action_feature = data['action'][..., :1]
返回值要求
奖励函数返回的 Tensor 应该:
- 保持与输入数据相同的 batch 维度
- 最后一维的特征维度为 1
- 数据类型为
torch.Tensor
设计原则
1. 目标导向
奖励函数应该直接反映任务的核心目标,避免引入无关的奖励信号。
2. 稀疏性平衡
- 奖励稀疏:可能导致学习困难,可考虑使用奖励塑形(reward shaping)
- 奖励过密:可能导致局部最优,需要适当调整奖励密度
3. 尺度合理
奖励值的尺度应该合理,避免过大或过小导致训练不稳定。
4. 可解释性
奖励函数应该具有清晰的逻辑,便于调试和优化。
注意事项
使用场景
奖励函数仅在训练策略模型时使用,训练虚拟环境模型时不需要定义奖励函数。REVIVE SDK 支持在训练策略时使用不同的奖励函数训练多个策略模型。
性能考虑
- 避免在奖励函数中进行复杂的计算
- 合理使用向量化操作提高效率
- 注意内存使用,避免创建过大的中间张量
调试技巧
- 可视化奖励分布:绘制奖励值的分布图,检查是否合理
- 分析奖励趋势:观察奖励随时间的变化趋势
- 对比不同策略:比较不同策略获得的奖励差异
- 逐步调试:从简单奖励开始,逐步增加复杂度
通过合理设计奖励函数,您可以有效引导智能体学习期望的行为模式,实现更好的决策效果。