一、矢量化环境(Vectorized Environments)
矢量化环境是使用多处理并行运行同一环境的多个独立副本的环境。矢量化环境将一批操作作为输入,并返回一批观察结果。Gym提供两种矢量化环境:
-
gym.vector.SyncVectorEnv
, 按顺序执行环境的不同副本 -
gym.vector.AsyncVectorEnv
,使用多处理并行执行环境的不同副本,并为每个副本创建一个进程。
可以使用gym.vector.make
函数运行已注册环境的矢量化版本。这将运行同一环境的多个副本(默认情况下是并行的)。
函数gym.vector.make
仅用于基础情况(例如,运行同一注册环境的多个副本)。对于任何其他用例,请使用SyncVectorEnv进行顺序执行,或使用AsyncVectorEnv进行并行执行。这些用例可能包括:
- 使用同一环境不同参数运行的多个实例。
- 运行一个未注册环境(例如自定义环境)中的多个实例。
- 在一些(但不是全部)环境副本上使用装饰器。
1. 创建矢量化环境
要创建运行多个环境副本的矢量化环境,可以将并行环境打包在gym.vector.SyncVectorEnv
(顺序执行)中或gym.vector.AsyncVectorEnv
(并行执行,或具有多处理)中。这些矢量化环境的输入是指定如何创建副本的可调用项列表。要创建同一注册环境的多个副本的矢量化环境,也可以使用函数gym.vector.make()
。
要实现动作和观察的自动批处理,所有环境副本必须共享相同的动作空间和观察空间。但不要求所有并行环境都是彼此的精确副本。
2.使用矢量化环境
标准Gym环境只执行一个动作并返回一个观察结果(有奖励,布尔值表示终止),而矢量化环境则将一批动作作为输入,并返回一批观察结果以及一系列奖励和布尔值,表明事件是否在每个环境副本中结束。
矢量化环境与任何环境都兼容,无论是动作空间还是观察空间(例如,gym.spaces.Dict
这样的容器空间,或任何任意嵌套的空间)。矢量化环境可以自动批量处理任何标准Gym空间由VectorEnv.reset
和VectorEnv.step
返回的观察结果(例如,Gym.spaces.Box、Gym.spaces.Discrete、Gym.spaces.Dict或其任何嵌套结构)。同样,矢量化环境可以从任何标准健Gym空间进行批量操作。在矢量化环境中复制的环境会在一个脚本结束时自动调用gym.Env.reset
。
3.Observation & Action spaces
与任何Gym环境一样,矢量化环境包含两个属性VectorEnv.observation_space
和VectorEnv.action_space
,以指定环境的观察和行动空间。由于矢量化环境在多个环境副本上运行,其间,所有副本执行的操作和返回的观察都被批处理在一起。因此观察和操作空间也被批处理。为了在矢量化环境中批量处理观察和操作,所有副本的观察和操作空间都必须相同。有时,使用矢量化环境的VectorEnv.single_observation_space
和VectorEnv.single_action_space
属性访问特定副本的观察和操作空间。
二、Intermediate Usage
1.共享内存(memory)
AsyncVectorEnv在每一个独立进程内运行环境副本。在每次调用AsyncVectorEnv.reset
或AsyncVectorEnv.step
时,所有并行环境的观察结果都会发送回主进程。为了避免在进程之间进行昂贵的数据传输,尤其是对于大型观测(例如图像),AsyncVectorEnv默认使用共享内存(shared_memory=True),进程可以以最低成本写入和读取共享内存,这样可以增加矢量化环境的吞吐量。
2.异常处理
在任何给定环境副本中引发的异常也会在矢量化环境中重新引发,也包括副本在AsyncVectorEnv并行运行的情况下。
三、高级用法
1.自定义空间
如果矢量化环境是标准Gym空间中的元素,例如gym.spaces.Box
、gym.spaces.Discrete
或gym.spaces.Dict
,则它们将批处理动作和观察。但是,如果您使用自定义动作和/或观察空间(继承自gym.space)创建自己的环境,矢量化环境将不会尝试自动批处理动作/观察,相反,它将返回所有并行环境中元素的原始元组。
自定义观察和操作空间可以从gym.Space
类继承。但是,大多数用例都应该包含在现有的空间类(例如gym.spaces.Box、gym.spaces.Discrete等)和容器类(gym.spaces.Tuple和gym.spaces.Dict)中。此外,强化学习算法的一些实现可能无法正确处理自定义空间。小心使用自定义空间。
如果将AsyncVectorEnv与自定义观察空间一起使用,则必须将shared_memory=False,因为共享内存、自动批处理与自定义空间不兼容。通常,如果将自定义空间与AsyncVectorEnv一起使用,则这些空间的元素必须是pickleable
。
四、API参考
1.VectorEnv
gym.vector.VectorEnv.action_space
#The (batched) action space. The input actions of step must be valid elements of action_space.
gym.vector.VectorEnv.observation_space
#The (batched) observation space. The observations returned by reset and step are valid elements of observation_space.
gym.vector.VectorEnv.single_action_space
#The action space of an environment copy.
gym.vector.VectorEnv.single_observation_space
#The observation space of an environment copy.
2.Reset
VectorEnv.reset(*,
seed: Optional[Union[int, List[int]]] = None,
return_info: bool = False,
options: Optional[dict] = None)
重置所有并行环境并返回一批初始观察结果。
Returns
observations (element of observation_space)
3.Step
VectorEnv.step(actions)
Parameters
actions (element of action_space)
Returns
-
observations (element of observation_space)
-
rewards (
np.ndarray
, dtypenp.float_
) -
dones (
np.ndarray
, dtypenp.bool_
) -
infos (list of dict)
4.Seed
VectorEnv.seed(seed=None)
在所有并行环境中设置随机种子。
Parameters
seed (list of int, or int, optional) – 每个并行环境的随机种子。如果seed是长度num_env的列表,那么列表中的项目将被选择为随机种子。如果seed是int,那么每个并行环境使用随机种子seed+n,其中n是并行环境的索引名(介于0和num_envs-1之间)。
Vector API - Gym Documentationhttps://www.gymlibrary.ml/content/vector_api/