最近总结一下之前学习的一个活塞球项目
准备工作
PettingZoo 是一个较新的库,类似于 Gym 的多代理版本。它的基本 API 用法如下
from pettingzoo.butterfly import pistonball_v5
env = pistonball_v5.env()
env.reset()
for agent in env.agent_iter():
observation, reward, done, info = env.last()
action = policy(observation, agent)
env.step(action)
下面总结活塞球的思路
策略单独控制每个活塞(agent)。Observation是活塞上方和旁边的空间
目标是让活塞队学习协同将球滚到左边。如果球向右移动,活塞奖励为负,如果向左,奖励为正,并且在每个单位时间步长都会收到少量负奖励,为了激励尽可能快地向左移动。动作是提升或降低活塞的位置(从 -4 到 4 像素)。
当下可行的方法是在所有代理之间共享策略网络,这样所有代理使用相同的函数来选择一个动作。每个代理都可以使用任何单一代理方法训练这个共享网络,参数共享。此处将用PPO单代理方法。
开导
from stable_baselines3.ppo import CnnPolicy
from stable_baselines3 import PPO
from pettingzoo.butterfly import pistonball_v5
import supersuit as ss
首先,我们初始化 PettingZoo 环境:
env = pistonball_v5.parallel_env(n_pistons=20, time_penalty=-0.1, continuous=True, random_drop=True, random_rotate=True, ball_mass=0.75, ball_friction=0.3, ball_elasticity=1.5, max_cycles=125)
每个参数中都控制环境的运行。
第一个问题是环境的observations是全彩图。但并不需要颜色信息,彩色图的神经网络处理计算成本比灰度图像高。用 SuperSuit 包来处理
env = ss.color_reduction_v0(env, mode=’B’)
B实际上采用图像的蓝色通道,而不是将所有通道转换为灰度,以节省处理时间,因为这将在训练过程中进行数十万次。之后,观察结果如下:
尽管对每个活塞的观测都是灰度级的,但图像仍然非常大,包含的信息还是多。
为了缩小所以设置84x84的大小。使用 SuperSuit 修复如下
env = ss.resize_v0(env, x_size=84, y_size=84)
因为球在动,要为策略网络找查看它的移动速度和加速速度的方法。
最简单的方法是将过去的几帧堆叠在一起作为每个观察的通道。
将 3 堆叠在一起可以提供足够的信息来计算加速度,
env = ss.frame_stack_v1(env, 3)
让 Stable Baselines 在多智能体环境中进行策略网络的参数共享。
env = ss.pettingzoo_env_to_vec_env_v1(env)
最后,需要将环境设置为并行执行,可以加快学习速度
env = ss.concat_vec_envs_v1(env, 8, num_cpus=4, base_class='stable_baselines3')
8 是指复制环境的次数,num_cpus 是这些将在其上运行的 CPU 内核数。这些是超参数。
model = PPO(CnnPolicy, env, verbose=3, gamma=0.95, n_steps=256, ent_coef=0.0905168, learning_rate=0.00062211, vf_coef=0.042202, max_grad_norm=0.9, gae_lambda=0.99, n_epochs=5, clip_range=0.3, batch_size=256)
model.learn(total_timesteps=2000000)
model.save(“policy”)
这会实例化 PPO 学习对象,然后训练策略网络。所有参数都是超参数,learn() 方法中的 timesteps 参数指的是单个代理采取的行动,而不是游戏的总次数。
查看策略的运行
首先重新实例化环境,这次使用普通的 API:
env = pistonball_v5.env()
env = ss.color_reduction_v0(env, mode=’B’)
env = ss.resize_v0(env, x_size=84, y_size=84)
env = ss.frame_stack_v1(env, 3)
然后加载策略
model = PPO.load(“policy”)
我们可以让他们使用该策略将其呈现在您的桌面上,如下所示:
env.reset()
for agent in env.agent_iter():
obs, reward, done, info = env.last()
act = model.predict(obs, deterministic=True)[0] if not done else None
env.step(act)
env.render()
效果如下