You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RLlib训练的1维动作空间PPO模型推理输出2维张量问题排查

RLlib训练的1维动作空间PPO模型推理输出2维张量问题排查

嗨,我来帮你捋清楚这个问题~你遇到的2维张量输出其实是RLlib对连续动作空间的默认处理逻辑导致的,咱们一步步来解决:

问题根源

你的动作空间定义的是1维连续Box空间(gym.spaces.Box(-1, 1, (1,), data_type)),而RLlib的PPO算法默认会用对角高斯分布(DiagGaussian)来建模连续动作。这个分布需要两个核心参数:均值和对数标准差,所以forward_inference返回的action_dist_inputs其实包含了这两个参数,形状就是[batch_size, 2*动作维度]——对你的1维动作来说,就是[1,2]的张量,这就是你看到“2维输出”的原因。

解决方法

你需要从这些分布参数中生成符合动作空间的1维动作,这里有两种稳妥的方式:

方法一:通过动作分布类生成动作(推荐)

RLlib提供了封装好的动作分布类,可以直接用action_dist_inputs构建分布,然后采样动作或者取均值(确定性动作),还会自动帮你把动作裁剪到[-1,1]的范围内:

修改你的test函数中获取动作的部分:

# 先导入需要的分布类
from ray.rllib.models.distributions import TorchDiagGaussian

# ... 其他代码 ...

inference_result = rl_module.forward_inference(
    {"obs": torch.from_numpy(obs).unsqueeze(0)}
)
# 用分布参数构建高斯分布
dist = TorchDiagGaussian(
    inference_result["action_dist_inputs"],
    model=rl_module,
    low=-1.0,  # 对应你动作空间的下限
    high=1.0   # 对应你动作空间的上限
)
# 采样一个动作(随机策略),或者用dist.mean取均值(确定性策略)
action = dist.sample().numpy()[0]

方法二:直接提取均值参数(简单但需手动裁剪)

如果你只需要确定性动作,也可以直接从action_dist_inputs中提取前动作维度个元素(也就是均值),记得手动把结果限制在动作空间范围内:

inference_result = rl_module.forward_inference(
    {"obs": torch.from_numpy(obs).unsqueeze(0)}
)
# 提取前1个元素(动作均值),并裁剪到[-1,1]
action = np.clip(
    inference_result["action_dist_inputs"][:, :1].numpy()[0],
    -1.0, 1.0
)

额外的小建议

你的SimpleCorridor环境的step函数中,直接用数组action和阈值比较,虽然numpy会自动处理,但最好显式取数组的第一个元素(因为动作是1维数组),避免潜在的警告或逻辑问题:

def step(self, action):
    print(action)
    # 显式取动作的标量值
    action_val = action[0]
    # Walk left.
    if action_val < -0.1 and self.cur_pos > 0:
        self.cur_pos -= 1
    # Walk right.
    elif action_val > 0.1:
        self.cur_pos += 1
    # ... 其他代码不变 ...

这样修改后,你得到的动作就会完全符合训练时定义的1维动作空间啦~

备注:内容来源于stack exchange,提问作者Altman Jeffry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:48:14