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

Stable Baselines3 PPO无学习效果:2D推车环境智能体无动作求助

问题分析与修复建议

你的代码存在几个关键问题,导致智能体无法学习到有效行为:

1. 观测状态类型不一致

在reset方法中,self.observation被初始化为numpy数组,但在step方法最后,你将它赋值为tuple(x_c, y_c, x_o, y_o),后续step调用时虽然能解包,但状态类型的不一致会干扰强化学习算法的状态表示与梯度计算。

2. 边界惩罚条件完全失效

if bool(any(self.observation) >= THRESHOLD)这行代码逻辑错误:any(self.observation)会将数组转换为布尔值(只要有非零元素就返回True),而True >= 50永远为False,导致边界惩罚从未触发。正确的判断应该是检查是否有观测值超出[-THRESHOLD, THRESHOLD]范围。

3. 奖励函数引导性不足

当前纯负向奖励的设计梯度信号太弱,智能体难以区分“靠近目标/物体”和“远离”的行为差异,应该增加正向奖励项强化正确行为,比如:

  • 推车接触物体时给予小额奖励
  • 物体每靠近目标一步给予奖励
  • 完成任务时给予大额奖励

4. 目标位置的作用域问题

GOAL定义在环境类外部,训练过程中始终固定同一个目标,限制了智能体的泛化能力,应该将目标改为环境实例变量,每次reset时随机生成新目标。

修复后的代码示例

import math
import numpy as np

import gym
from gym import spaces
from stable_baselines3 import PPO

THRESHOLD = 50

class CartPushEnv2D(gym.Env):
    metadata = {"render_modes": ["human", "rgb_array"]}

    def __init__(self):
        self.action_space = spaces.Discrete(8)
        self.observation_space = spaces.Box(
            low=-THRESHOLD, high=THRESHOLD, shape=(4,), dtype=np.float32
        )

    def step(self, action):
        x_c, y_c, x_o, y_o = self.observation

        # 移动推车
        if action == 0:
            x_c, y_c = x_c - 1, y_c - 1
        elif action == 1:
            x_c, y_c = x_c - 1, y_c + 1
        elif action == 2:
            x_c, y_c = x_c + 1, y_c - 1
        elif action == 3:
            x_c, y_c = x_c + 1, y_c + 1
        elif action == 4:
            x_c += 1
        elif action == 5:
            x_c -= 1
        elif action == 6:
            y_c += 1
        else:
            y_c -= 1

        # 检查是否推动物体
        pushed = False
        cart_pos = np.array([x_c, y_c])
        obj_pos = np.array([x_o, y_o])
        if np.linalg.norm(cart_pos - obj_pos) <= math.sqrt(2):
            pushed = True
            if action == 0:
                x_o, y_o = x_o - 1, y_o - 1
            elif action == 1:
                x_o, y_o = x_o - 1, y_o + 1
            elif action == 2:
                x_o, y_o = x_o + 1, y_o - 1
            elif action == 3:
                x_o, y_o = x_o + 1, y_o + 1
            elif action == 4:
                x_o += 1
            elif action == 5:
                x_o -= 1
            elif action == 6:
                y_o += 1
            else:
                y_o -= 1

        # 更新观测(保持numpy数组类型)
        self.observation = np.array([x_c, y_c, x_o, y_o], dtype=np.float32)

        # 判断任务完成
        done = np.linalg.norm(np.array([x_o, y_o]) - self.goal) <= math.sqrt(2)

        # 计算奖励
        reward = 0.0
        # 边界惩罚:超出范围给予大额负奖励
        if np.any(self.observation > THRESHOLD) or np.any(self.observation < -THRESHOLD):
            reward -= 10 * THRESHOLD
        else:
            # 惩罚物体到目标的距离,鼓励靠近目标
            obj_to_goal_dist = np.linalg.norm([x_o, y_o] - self.goal)
            reward -= obj_to_goal_dist * 0.1
            # 惩罚推车到物体的距离,鼓励推车靠近物体
            cart_to_obj_dist = np.linalg.norm(cart_pos - obj_pos)
            reward -= cart_to_obj_dist * 0.05
            # 推车推动物体时给予正向奖励
            if pushed:
                reward += 5
            # 完成任务给予大额奖励
            if done:
                reward += 100

        info = {}
        return self.observation, reward, done, info

    def reset(self):
        # 随机生成推车、物体和目标位置
        self.observation = np.random.uniform(-THRESHOLD, THRESHOLD, 4).astype(np.float32)
        self.goal = np.random.uniform(-THRESHOLD, THRESHOLD, 2).astype(np.float32)
        return self.observation

# 训练与测试
env = CartPushEnv2D()
# 调整PPO参数,增加训练稳定性
model = PPO(
    'MlpPolicy',
    env,
    verbose=1,
    learning_rate=3e-4,
    n_steps=2048,
    batch_size=64,
    gamma=0.99
)
model.learn(total_timesteps=200000)

# 测试训练后的模型
obs = env.reset()
done = False
while not done:
    action, _ = model.predict(obs, deterministic=True)
    obs, reward, done, info = env.step(action)
    print(f"目标: {env.goal}, 观测: {obs}, 奖励: {reward:.2f}, 完成状态: {done}")

额外建议

  • 增加可视化:实现render方法,直观观察推车和物体的移动过程,方便调试
  • 调整奖励权重:根据训练效果微调各项奖励的权重,找到最优的引导信号
  • 尝试不同算法:如果PPO效果不佳,可以尝试DQN(适合离散动作空间)或SAC等算法

内容的提问来源于stack exchange,提问作者H-Man

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:55:02