强化学习系列文章(二十六):向量化环境Vectorized Environments
OpenAI Gym最近公布了官方API手册,可以趁机学习一下环境运行的并行化技术。
https://www.gymlibrary.ml/pages/vector_api/index
Vectorized Environments
所谓“矢量化环境”,是运行多个(独立)子环境的环境,可以按顺序运行,也可以使用多处理并行运行。矢量化环境将一批action作为输入,并返回一批observation。例如,当策略被定义为对一批obs进行操作的神经网络时,矢量化环境就特别有用了。
Gym 提供两种类型的矢量化环境:
gym.vector.SyncVectorEnv,其中的子环境按顺序执行。gym.vector.AsyncVectorEnv,其中的子环境使用多进程并行执行。这将为每个子环境创建一个进程。
与gym.make类似,您可以使用gym.vector.make函数运行已注册环境的矢量化版本。这将运行同一环境的多个副本(默认情况下并行运行)。
下面的示例并行运行CartPole-v1环境的3个副本,将3个二值操作(每个子环境一个)的向量作为输入,并返回一个沿第一维度堆叠的3个observation的数组,其中包含每个子环境返回的奖励数组,以及一个指示每个子环境中的episode是否已结束的布尔数组。
>>> envs = gym.vector.make("CartPole-v1", num_envs=3)
>>> envs.reset()
>>> actions = np.array([1, 0, 1])
>>> observations, rewards, dones, infos = envs.step(actions)
>>> observations
array([[ 0.00122802, 0.16228443, 0.02521779, -0.23700266],
[ 0.00788269, -0.17490888, 0.03393489, 0.31735462],
[ 0.04918966, 0.19421194, 0.02938497, -0.29495203]],
dtype=float32)
>>> rewards
array([1., 1., 1.])
>>> dones
array([False, False, False])
>>> infos
({
}, {
}, {
})
函数gym.vector.make仅用于基本情况(例如,运行同一注册环境的多个副本)。对于任何其他用例,请使用SyncVectorEnv进行顺序执行,或使用AsyncVectorEnv进行并行执行。这些用例可能包括:
- 使用不同的参数运行同一环境的多个实例(例如,具有不同重力值的
"Pendulum-v0") - 运行未注册环境(例如自定义环境)的多个实例
- 在某些(但不是全部)子环境中使用包装器。
Creating a vectorized environment
若要创建运行多个子环境的矢量化环境,可以将子环境包装在gym.vector.SyncVectorEnv(用于顺序执行)或gym.vector.AsyncVectorEnv(用于并行执行,具有多进程)中。这些创建矢量化环境的API的输入是“一个指定如何创建子环境的可调用对象的列表”。
>>> envs = gym.vector.AsyncVectorEnv([
lambda: gym.make("CartPole-v1"),
lambda: gym.make("CartPole-v1"),
lambda: gym.make("CartPole-v1")
])
或者,要创建同一环境的多个副本的矢量化环境,可以使用函数gym.vector.make()。
>>> envs = gym.vector.make("CartPole-v1", num_envs=3) # Equivalent
要启用action和observation的自动批处理,所有子环境必须共享相同的action_space和observation_space。但是,所有子环境都不需要是彼此的精确副本。例如,可以使用以下命令在矢量化环境中运行2个具有不同重力值的Pendulum-v0实例:
>>> env = gym.vector.AsyncVectorEnv([
lambda: gym.make("Pendulum-v0", g=9.81),
lambda: gym.make("Pendulum-v0", g=1.62)
])
关于自动批处理的详细信息,请参考Observation & Action spaces章节。
将AsyncVectorEnv与spawn或forkserver start方法一起使用时,必须使用'if __name__ == '__main__":' 包装包含矢量化环境的代码。有关详细信息,请参阅此文档。
if __name__ == "__main__":
envs = gym.vector.make("CartPole-v1", num_envs=3, context="spawn")
Working with vectorized environments
虽然标准Gym环境执行单个action并返回单个observation(包括reward和done),但矢量化环境是将一批action作为输入,并返回一批observation,以及一系列奖励和布尔值Done,指示episode是否在每个子环境中结束。
>>> envs = gym.vector.make("CartPole-v1", num_envs=3)
>>> envs.reset()
array([[ 0.00198895, -0.00569421, -0.03170966, 0.00126465],
[-0.02658334, 0.00755256, 0.04376719, -0.00266695],
[-0.02898625, 0.04779156, 0.02686412, -0.01298284]],
dtype=float32)
>>> actions = np.array([1, 0, 1])
>>> observations, rewards, dones, infos = envs.step(actions)
>>> observations
array([[ 0.00187507, 0.18986781, -0.03168437, -0.301252 ],
[-0.02643229, -0.18816885, 0.04371385, 0.3034975 ],
[-0.02803041, 0.24251814, 0.02660446, -0.29707024]],
dtype=float32)
>>> rewards
array([1., 1., 1.])
>>> dones
array([False, False, False])
>>> infos
({
}

最低0.47元/天 解锁文章
7821





