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
相关产品推荐
相关产品推荐

