Gymnasium 发布说明

v1.2.0

发布于 2025-06-27 - GitHub - PyPI

Gymnasium v1.2.0

在 Gym v0.24 中,添加了使用不同模拟器(mujoco,而非 mujoco-py)的 v4 MuJoCo 环境。
由于 v0.24 发布至今已有三年,且 mujoco-py 已停止维护,这限制了我们对 Python 3.13 的支持能力。
因此,在此版本中,我们已将 MuJoCo v2 和 v3 迁移到 Gymnasium-Robotics 项目,这意味着无法升级到 v4 或 v5 MuJoCo 环境的用户应将其代码更新为

import gymnasium as gym
import gymnasium_robotics  # `pip install "gymnasium-robotics[mujoco-py]"`

gym.register_envs(gymnasium_robotics)  # optional

env = gym.make("Humanoid-v3")

此外,我们还添加了对 Python 3.13 的支持(并跟随 NumPy 及其他项目放弃了对 Python 3.8 和 3.9 的支持)。

新特性

  • 添加 `AddWhiteNoise` 和 `ObstructView` 封装器,由 @sparisi 实现,用于在 RGB 渲染中添加噪声,覆盖整个图像或部分区域 (#1243)
  • 为出租车环境添加了多雨和反复无常的选项,这些选项由 @foreverska 在原始论文中实现 (#1315)
  • 添加 `wrappers.ArrayConversion`,这是一个由 @amacati 实现的通用转换封装器,用于在兼容 Array API 的框架(如 NumPy、Torch、Jax 等)之间进行转换 (#1333)
  • 在 RecordVideo 封装器上添加垃圾回收器,以防止内存溢出问题,由 @vicbentu 实现 (#1378)

错误修复

此外,此版本还包括对文档的众多更新,最重要的是对介绍性页面的更新,旨在使 Gymnasium 或 RL 的新用户更容易理解。

完整更新日志: v1.1.1...v1.2.0

Gymnasium v1.1.1

发布于 2025-03-06 - GitHub - PyPI

更改

  • 移除 `mujoco_env.py` 中基于 MuJoCo 的环境对元数据渲染模式的断言 (#1328)
  • @pkuderov 更新 `wrappers.vector.NumpyToTorch`,使其引用 `numpy` 而非 `jax` (#1319)

完整更新日志: v1.1.0...v1.1.1

v1.1.0

发布于 2025-02-26 - GitHub - PyPI

Gymnasium v1.1

在此版本中,我们修复了 Gymnasium v1.0 的多个错误,并添加了新功能以改进已进行的更改。

随着 Gymnasium v1.0 的发布,我们做出的主要改变之一是向量环境的实现,改进了用户与之交互和扩展的方式。一些用户指出,他们需要向后兼容向量环境在终止或截断时自动重置子环境的方式,这被称为自动重置模式或 API。因此,在 v1.1 中,我们已为实现的向量环境(`SyncVectorEnv` 和 `AsyncVectorEnv`)和封装器添加了对所有三种可能模式的支持:next-step(下一步)、same-step(同一步)和 disabled(禁用)。要了解所使用的自动重置模式类型,应在向量环境元数据 `metadata["autoreset_mode"]` 中指定为 `gymnasium.vectors.AutoresetMode` 枚举。有关自动重置模式之间差异以及如何使用它们的更多信息,请阅读 https://farama.org/Vector-Autoreset-Mode

此外,我们还添加了几个有用的功能

  • 在 Gymnasium v0.25 中,我们为空间添加了掩码功能,即 `space.sample(mask=...)`,用于逻辑上掩盖空间中可能的样本。#1310 通过 `space.sample(probability=...)` 为每个空间添加了概率掩码,以指定每个样本的概率,这对于输出动作概率分布的 RL 策略非常有用。
  • 对于 MuJoCo 环境,用户可以选择使用 RGB 图像或基于深度的图像渲染机器人。以前,只能访问 RGB 或深度渲染。Gymnasium v1.1 添加了 RGBD 渲染,可将 RGB 和基于深度的图像作为单个输出。
  • 在 Gymnasium v1.0 中,我们通过 `JaxToTorch`、`JaxToNumpy`、`NumpyToTorch` 等改进了 `jax`、`torch` 和 `numpy` 之间的转换封装器。在 v1.1 中,我们改进了封装器以支持渲染并与完整的 dlpack API 兼容。

新特性

  • @mariojerez 实现的带概率掩码的空间采样 (#1310)
  • @DavidPL1 为 MuJoCo 添加 RGB + 深度渲染 (#1229)
  • @amacati 添加对 `JaxToNumpy`、`JaxToTorch` 和 `NumpyToTorch` 的渲染支持 (#1306)
  • @amacati 添加对 dlpack API 的完全支持 (#1299)
  • @sparisi 启用 StickyAction 封装器,使其能够重复旧动作超过 1 步 (#1240)
  • @howardh 添加 `wrappers.vector.TransformObs/Action` 对单个观测/动作空间参数的支持 (#1288)
  • @duburcqa 改进封装器的 'set_wrapper_attr' 以修改变量更新方式 (#1294)
  • @li-plus 允许 `AtariPreprocessing` 支持非方形观测 (#1312)
  • @pseudo-rnd-thoughts 改进 `Wrapper` 和 `VectorWrapper` 的错误检查 (#1260)

错误修复

文档更改

  • @artemmiyy 修复 21点游戏中采样值(2-10 而非 2-9)的拼写错误 (#1250)
  • @godsboy404 添加了一些流行的第三方初学者教程 (#1271)
  • @keraJLi 更新奖励缩放封装器的文档 (#1285)

感谢 31 位新贡献者为此次发布做出的贡献,完整更新日志: v1.0.0...v1.1.0

v1.0.0

发布于 2024-10-08 - GitHub - PyPI

v1.0.0 发布说明

在过去的几年里,Gym 和 Gymnasium 背后的志愿者团队一直致力于修复错误、改进文档、添加新功能,并在适当的情况下更改 API,以使收益大于成本。这是 `v1.0.0` 的完整发布,这将是更改项目核心 API(`Env`、`Space`、`VectorEnv`)的道路的终点。此外,自 `0.29.1` 以来,此版本已包含 200 多个 PR,其中包括许多错误修复、新功能和改进的文档。因此,感谢所有志愿者的辛勤工作,使这一切成为可能。在这些发布说明的其余部分,我们将介绍核心 API 更改,最后是其中包含的额外新功能、错误修复、弃用和文档更改。

最后,我们发表了一篇关于 Gymnasium 的论文,讨论了其整体设计决策等,详见 https://arxiv.org/abs/2407.17032,可使用以下方式引用

@misc{towers2024gymnasium,
      title={Gymnasium: A Standard Interface for Reinforcement Learning Environments}, 
      author={Mark Towers and Ariel Kwiatkowski and Jordan Terry and John U. Balis and Gianluca De Cola and Tristan Deleu and Manuel Goulão and Andreas Kallinteris and Markus Krimmel and Arjun KG and Rodrigo Perez-Vicente and Andrea Pierré and Sander Schulhoff and Jun Jet Tai and Hannah Tan and Omar G. Younis},
      year={2024},
      eprint={2407.17032},
      archivePrefix={arXiv},
      primaryClass={cs.LG},
      url={https://arxiv.org/abs/2407.17032}, 
}

移除插件系统

在 Gym v0.23+ 和 Gymnasium v0.26 至 v0.29 中,一个用于在后台注册外部环境的未文档化功能已被移除。对于 Atari (ALE)MinigridHighwayEnv 的用户,以前可以使用以下代码

import gymnasium as gym

env = gym.make("ALE/Pong-v5")

即使从未导入 Atari(即 `import ale_py`),用户仍然可以创建 Atari 环境。此功能已在 `v1.0.0` 中移除,这将要求用户更新到

import gymnasium as gym
import ale_py

gym.register_envs(ale_py)  # optional, helpful for IDEs or pre-commit

env = gym.make("ALE/Pong-v5")

或者,用户可以使用以下结构,`module_name:env_id`,以便在创建环境之前首先导入模块。例如,`ale_py:ALE/Pong-v5`。

import gymnasium as gym

env = gym.make("ale_py:ALE/Pong-v5")

为了帮助使用 IDE(例如 VSCode、PyCharm)的用户,在导入模块以注册环境(例如 `import ale_py`)时,IDE(以及 pre-commit isort / black / flake8)可能会认为此导入是无意义的,并应将其删除。因此,我们引入了 `gymnasium.register_envs` 作为空操作函数(该函数实际上不执行任何操作),以使 IDE 认为正在发生一些事情并且需要此导入语句。

向量环境

为了提高环境的采样速度,向量化是同时采样同一环境多个实例的最简单方法之一。Gym 和 Gymnasium 提供 `VectorEnv` 作为其基类,但其问题之一是它继承了 `Env`。这可能导致类型检查(`Env` 和 `VectorEnv` 的 `step` 返回类型不同)、环境类型测试(尽管两者行为不同,但 `isinstance(env, Env)` 对于向量环境可能为真)以及最终的封装器(一些 Gym 和 Gymnasium 封装器支持向量环境,但没有明确或一致的 API 来确定哪些支持哪些不支持)等特定问题。因此,我们已将 `Env` 和 `VectorEnv` 分离,使其不再相互继承。

在实现新的独立 `VectorEnv` 类时,我们努力最小化使用 `Env` 和 `VectorEnv` 的代码之间的差异,并在某些地方使其更具通用性。该类包含与 `Env` 相同的属性和方法,此外还包括 `num_envs: int`、`single_action_space: gymnasium.Space` 和 `single_observation_space: gymnasium.Space` 属性。此外,我们已从 `VectorEnv` 中删除了所有向量实现都不需要的几个函数:`step_async`、`step_wait`、`reset_async`、`reset_wait`、`call_async` 和 `call_wait`。此更改现在允许用户编写自己的自定义向量环境,v1.0.0 包含一个示例向量倒立摆环境,该环境仅用 NumPy 编写,运行速度比使用 Gymnasium 的同步向量环境快数千倍。

为了方便用户创建向量化环境,我们提供了 `gymnasium.make_vec` 作为 `gymnasium.make` 的向量化等效项。由于存在多种不同的向量化选项(“sync”、“async”以及称为“vector_entry_point”的自定义类),参数 `vectorization_mode` 选择环境如何被向量化。此参数默认为 `None`,这样如果环境具有自定义向量环境实现的向量入口点,则将首先使用该入口点(目前,Cartpole 是 Gymnasium 中唯一内置向量入口点的环境)。否则,将使用同步向量化器(以前,Gym 和 Gymnasium 的 `vector.make` 默认使用异步向量化器)。有关更多信息,请参阅函数 文档字符串。我们很高兴看到其他项目利用此选项来更轻松地创建其环境。

env = gym.make("CartPole-v1")
env = gym.wrappers.ClipReward(env, min_reward=-1, max_reward=3)

envs = gym.make_vec("CartPole-v1", num_envs=3)
envs = gym.wrappers.vector.ClipReward(envs, min_reward=-1, max_reward=3)

由于 `Env` 和 `VectorEnv` 的这种拆分,现在 `gymnasium.wrappers` 中有仅适用于 `Env` 的封装器,而 `gymnasium.wrappers.vector` 中有仅适用于 `VectorEnv` 的封装器。此外,我们将基础向量封装器的名称从 `VectorEnvWrapper` 更新为 `VectorWrapper`,并添加了 `VectorObservationWrapper`、`VectorRewardWrapper` 和 `VectorActionWrapper` 类。有关新信息,请参阅向量封装器页面。

为提高向量环境的效率,自动重置(autoreset)是一项常见功能,它允许子环境在所有子环境完成之前进行重置。以前在 Gym 和 Gymnasium 中,自动重置发生在环境回合结束的同一时间步。最终的观察和信息会存储在时间步的信息中,即 info["final_observation"]info[“final_info”],而标准的观察和信息则包含子环境重置后的观察和信息。因此,要从向量环境中准确采样观察值,需要以下代码(注意如果子环境已终止或截断,需要提取 infos["next_obs"][j])。此外,对于使用 rollout 的在策略(on-policy)算法,需要额外的正向传播来计算正确的下一个观察值(这通常作为优化省略,假设环境只终止,不截断)。

replay_buffer = []
obs, _ = envs.reset()
for _ in range(total_timesteps):
    next_obs, rewards, terminations, truncations, infos = envs.step(envs.action_space.sample())

    for j in range(envs.num_envs):
        if not (terminations[j] or truncations[j]):
            replay_buffer.append((
                obs[j], rewards[j], terminations[j], truncations[j], next_obs[j]
            ))
        else:
            replay_buffer.append((
                obs[j], rewards[j], terminations[j], truncations[j], infos["next_obs"][j]
            ))

    obs = next_obs

然而,随着时间的推移,开发团队已经认识到这种方法的低效性(主要是由于大量使用了 Python 字典)以及必须提取最终观察值才能正确训练智能体的麻烦,例如 这个示例。因此,在 v1.0.0 版本中,我们正在修改自动重置功能,使其与 EnvPoolSampleFactory 等专门的向量专用项目保持一致,在这些项目中,子环境直到下一步才重置。因此,在采样时需要进行以下更改:

replay_buffer = []
obs, _ = envs.reset()
autoreset = np.zeros(envs.num_envs)
for _ in range(total_timesteps):
    next_obs, rewards, terminations, truncations, _ = envs.step(envs.action_space.sample())

    for j in range(envs.num_envs):
        if not autoreset[j]:
            replay_buffer.append((
                obs[j], rewards[j], terminations[j], truncations[j], next_obs[j]
            ))

    obs = next_obs
    autoreset = np.logical_or(terminations, truncations)

对于在策略 rollout,为了适应自动重置,需要对新回合中的第一个观察值(done[t+1])进行误差掩码,以防止计算回合中最后一个观察值和第一个观察值之间的误差。

最后,我们改进了 AsyncVectorEnv.set_attrSyncVectorEnv.set_attr 函数,使其使用 Wrapper.set_wrapper_attr,允许用户在环境堆栈中已存在的任何位置设置变量。以前,这是不可能的,用户只能修改环境堆栈中“顶部”包装器中的变量,而不是实际环境本身。

封装器 (Wrappers)

以前,一些包装器(wrapper)可以同时支持标准环境和向量环境,但这种支持并未标准化,并且不清楚哪些包装器支持向量环境,哪些不支持。对于 v1.0.0 版本,通过将 EnvVectorEnv 分开,使其不再相互继承(详情请参阅向量部分),gymnasium.wrappers 中的包装器将仅支持标准环境,而 gymnasium.wrappers.vector 中的包装器包含提供的专用向量包装器(大多数但并非所有包装器都受支持,如果您需要,请提出功能请求)。

在 v0.29 版本中,我们已弃用 Wrapper.__getattr__ 函数,并由 Wrapper.get_wrapper_attr 取代,后者提供了对环境堆栈中任何位置变量的访问权限。在 v1.0.0 版本中,我们添加了 Wrapper.set_wrapper_attr 作为等效函数,用于在变量已存在的情况下,在环境堆栈中的任何位置设置变量;否则,变量将分配给顶层包装器。

最重要的是,我们移除、重命名并添加了以下列出的几个包装器。

  • 已移除的包装器
    • monitoring.VideoRecorder - 替换包装器是 RecordVideo
    • StepAPICompatibility - 我们期望所有 Gymnasium 环境都使用终止/截断(terminated/truncated)步长 API,因此用户不应再需要 StepAPICompatibility 包装器。Shimmy 包含一个兼容环境,用于将 gym-api 环境转换为 Gymnasium。
  • 已重命名的包装器(为了使包装器命名保持一致。因此,我们从所有包装器名称中移除了“Wrapper”,并在适当的地方包含了“Observation”、“Action”和“Reward”)
    • AutoResetWrapper -> Autoreset
    • FrameStack -> FrameStackObservation
    • PixelObservationWrapper -> AddRenderObservation
  • 已移动的包装器(所有向量包装器都位于 gymnasium.wrappers.vector 中)
    • VectorListInfo -> vector.DictInfoToList
  • 已添加的包装器
    • DelayObservation - 添加对下一个观察值和奖励的延迟
    • DtypeObservation - 修改环境观察空间的 dtype
    • MaxAndSkipObservation - 将跳过 n 个观察值,并取最近 2 个观察值的最大值,灵感来自 Atari 环境启发式算法,适用于其他环境
    • StickyAction - 以一定概率随机重复动作,并返回最终观察值和多个时间步的奖励总和。灵感来自 Atari 环境启发式算法
    • JaxToNumpy - 将基于 Jax 的环境转换为使用基于 Numpy 的输入和输出数据进行 resetstep 等操作
    • JaxToTorch - 将基于 Jax 的环境转换为使用基于 PyTorch 的输入和输出数据进行 resetstep 等操作
    • NumpyToTorch - 将基于 Numpy 的环境转换为使用基于 PyTorch 的输入和输出数据进行 resetstep 等操作

对于所有包装器,我们都添加了示例代码文档和更新日志,以帮助未来的研究人员了解所做的任何更改。例如,请参阅以下页面

函数式环境

Gymnasium 的 Env 的一个显著优势是它通常只需要关于底层环境规范的最小信息;然而,这可能会使此类环境应用于规划、搜索算法和理论研究变得更加困难。我们提议使用 FuncEnv 作为 Env 的替代定义,它更接近马尔可夫决策过程的定义,向用户公开更多函数,包括观察、奖励和终止函数,以及作为单一对象的环境原始状态。

from typing import Any
import gymnasium as gym
from gymnasium.functional import StateType, ObsType, ActType, RewardType, TerminalType, Params

class ExampleFuncEnv(gym.functional.FuncEnv):
  def initial(self, rng: Any, params: Params | None = None) -> StateType:
    ...
  def transition(self, state: StateType, action: ActType, rng: Any, params: Params | None = None) -> StateType:
    ...
  def observation(self, state: StateType, rng: Any, params: Params | None = None) -> ObsType:
    ...
  def reward(
      self, state: StateType, action: ActType, next_state: StateType, rng: Any, params: Params | None = None
  ) -> RewardType:
    ...
  def terminal(self, state: StateType, rng: Any, params: Params | None = None) -> TerminalType:
    ...

FuncEnv 要求 initialtransition 函数在给定输入的情况下返回一个新状态,作为 Env.stepEnv.reset 的部分实现。因此,用户可以采样(并保存)各种输入的下一个状态,用于规划、搜索等。在给定状态下,observationrewardterminal 为用户提供了明确的定义,以了解它们如何影响环境的输出。

收集种子值

以前可以使用 None 对环境和空间进行种子设置以使用随机初始种子值,但无法知道这些初始种子值是什么。我们已通过 #1033#889 解决了 Space.seedreset.seed 的此问题。此外,对于 Space.seed,我们已将返回类型更改为针对每个空间专门化,以便以下代码适用于所有空间。

seeded_values = space.seed(None)
initial_samples = [space.sample() for _ in range(10)]

reseed_values = space.seed(seeded_values)
reseed_samples = [space.sample() for _ in range(10)]

assert seeded_values == reseed_values
assert initial_samples == reseed_samples

此外,对于环境,我们添加了一个新的 np_random_seed 属性,它将存储来自 reset(seed=seed) 的最新 np_random 种子值。

环境版本变更

  • 最近发现,基于 MuJoCo 的 Pusher 与 mujoco>= 3 不兼容,因为代理需要推动的方块模型密度比空气轻。这显然开始对使用 mujoco>= 3 和 Pusher 的用户造成问题。因此,我们禁用了 mujoco>= 3 下的 v4 环境,并更新到 MuJoCo v5 中的模型,该模型能产生与 v4mujoco< 3 类似更预期的行为 (#1019)。

  • 作为两年前添加的 v4 环境的后续,新的 v5 MuJoCo 环境修复了一致性问题,添加了新功能并更新了文档 (#572)。此外,我们已决定将基于 mujoco-py 的(v2 和 v3)环境标记为已弃用,并计划在未来从 Gymnasium 中移除它们 (#926)。

  • 由于修复了两个错误,Lunar Lander 版本从 v2 升级到 v3。第一个修复了环境的确定性,使得世界对象在重置时不会完全被销毁,从而避免了在特定情况下的非确定性 (#979)。第二,风生成(默认关闭)在每次重置时并未随机生成,因此我们已更新此功能,以确保回合之间的统计独立性 (#959)。

  • CarRacing 版本从 v2 升级到 v3,以改变环境的结束方式,即当代理完成赛道时,环境将终止而非截断。

  • 我们已移除 pip install "gymnasium[accept-rom-license]",因为 ale-py>=0.9 现在已随 roms 一起打包,这意味着用户不再需要单独安装带有 autoroms 的 Atari roms。

其他错误修复

  • spaces.Box 允许低于或高于 dtype 范围的值,这可能导致一些非常奇怪的边缘情况,而 @pseudo-rnd-thoughts 很难检测到这些情况 (#774)
  • 由于 cython==3 问题,@pseudo-rnd-thoughts 限制了 gymnasium[mujoco-py] 的 cython 版本 (#616)
  • @logan-dunbar 修复了 MuJoCo 渲染时自定义宽度值的问题 (#634)
  • @chrisyeh96 修复了环境检查器以正确报告无限边界 (#708)
  • @younikregister(kwargs) 的类型提示从 **kwargs 修复为 kwargs: dict | None = None (#788)
  • @RedTachyon 修复了 AsyncVectorEnv 中自定义环境的注册问题 (#810)
  • @MischaPanch 移除了 v4+ MuJoCo 环境的 mujoco-py 导入错误
    (#934)
  • 修复了 TupleDict 空间共享内存读取问题 (#941)
  • 修复了 Multidiscrete.from_jsonable 在 Windows 上的问题 (#932)
  • 移除了 play 渲染归一化 (#956)
  • @mantasu 修复了 to_torch 转换中未使用的设备参数 (#1107)
  • @mantasu 修复了 GPU 上 PyTorch 到 NumPy 的转换问题 (#1109)

其他新功能

弃用

文档变更

完整更新日志: v0.29.1...v1.0.0

v1.0.0a2: v1.0.0 alpha 2

发布于 2024-05-21 - GitHub - PyPI

这是我们的第二个 alpha 版本,我们希望它能成为 Gymnasium v1.0.0 正式发布前的最后一个版本。我们在此 alpha 版本中总结了主要的更改、错误修复和新增功能。

主要变更

Atari 环境

ale-py 提供 Atari 环境,其已在 v0.9.0 中更新,使用 Gymnasium 作为 API 后端。此外,pip 安装包中包含 ROM,因此安装 Atari 只需执行 pip install “gymnasium[atari]”(因此,gymnasium[accept-rom-license] 已被移除)。请注意,对于 Gymnasium v1.0,要注册外部环境(例如 ale-py),您需要在创建任何 Atari 环境之前 import ale_py

收集种子值

以前可以通过将环境和空间设置为 None 来使用随机初始种子值,但无法得知这些初始种子值是什么。我们已在 #1033#889 中解决了 Space.seedreset.seed 的这个问题。对于 Space.seed,我们已将返回类型更改为针对每个空间进行特化,以便以下代码适用于所有空间。

seeded_values = space.seed(None)
initial_samples = [space.sample() for _ in range(10)]

reseed_values = space.seed(seeded_values)
reseed_samples = [space.sample() for _ in range(10)]

assert seeded_values == reseed_values
assert initial_samples == reseed_samples

此外,对于环境,我们添加了一个新的 np_random_seed 属性,它将存储来自 reset(seed=seed) 的最新 np_random 种子值。

环境版本变更

  • 最近发现,基于 MuJoCo 的推杆(pusher)环境与 MuJoCo >= 3 不兼容,原因是修复了一些 bug,发现智能体需要推动的块的模型密度是空气密度。这显然开始给使用 MuJoCo v3+ 和 Pusher 的用户带来问题。因此,我们禁用了 MuJoCo >= 3 上的 v4 环境,并更新到 MuJoCo v5 中的模型,该模型能够产生更符合预期的行为,与 v4 和 MuJoCo < 3 类似 (#1019)。
  • Alpha 2 版本包含了新的 v5 MuJoCo 环境,作为两年前添加的 v4 环境的后续更新,修复了一致性问题,增加了新功能并更新了文档。我们已决定将 MuJoCo-py (v2 和 v3) 环境标记为已弃用,并计划在将来从 Gymnasium 中移除它们 (#926)。
  • 由于修复了两个错误,Lunar Lander 版本从 v2 升级到 v3。第一个修复了环境的确定性,使得世界对象在重置时不会完全被销毁,从而避免了在特定情况下的非确定性 (#979)。第二,风生成(默认关闭)在每次重置时并未随机生成,因此我们已更新此功能,以确保回合之间的统计独立性 (#959)。

Box 空间采样

发现 spaces.Box 允许低值和高值超出数据类型 (dtype) 的范围 (#774),这可能导致一些非常难以检测的奇怪边缘情况。我们希望这些更改能改善调试和检测空间无效输入的能力,但是,如果您的环境出现与此相关的问题,请告知我们。

错误修复

  • 更新 CartPoleVectorEnv 以支持新的自动重置 API (#915)
  • 修复了 wrappers.vector.RecordEpisodeStatistics 中使用新自动重置 API 计算剧集长度的问题 (#1018)
  • 移除 v4+ MuJoCo 环境的 mujoco-py 导入错误 (#934)
  • 修复 make_vec(**kwargs) 未传递给向量入口点环境的问题 (#952)
  • 修复了 TupleDict 空间共享内存读取问题 (#941)
  • 修复 Multidiscrete.from_jsonable 在 Windows 上的问题 (#932)
  • 移除 play 渲染标准化 (#956)

新特性

  • 新增 Python 3.12 支持
  • 添加一个新的 OneOf 空间,提供空间的独占联合 (#812)
  • 更新 Dict.sample,使其使用标准 Python 字典而非 OrderedDict,因为已放弃对 Python 3.7 的支持 (#977)
  • Jax 环境返回 Jax 数据而非 NumPy 数据 (#817)
  • 添加 wrappers.vector.HumanRendering 并从 CartPoleVectorEnv 中移除人工渲染 (#1013)
  • 如果用户混合使用 Gym 和 Gymnasium,则添加更有帮助的错误消息 (#957)
  • CartPole 添加 sutton_barto_reward 参数,将奖励函数修改为在终止状态不返回 1 (#958)
  • 为 MuJoCo 环境添加 visual_options 渲染参数 (#965)
  • utlis.env_checker.data_equivilance 添加 exact 参数 (#924)
  • 更新 wrapper.NormalizeObservation 的观察空间并将观察数据类型更改为 float32 (#978)
  • 如果在 env.spec 期间 kwarg 无法被 pickle 化,则捕获异常 (#982)
  • 改进 Box2D 的 ImportError (#1009)
  • 为 VectorEnv 和 VectorWrapper 添加了 metadata 字段 (#1006)
  • 修复在修改 make 参数时 make_vec 同步或异步的问题 (#1027)

完整更新日志: v1.0.0a1...v1.0.0a2 v0.29.1...v1.0.0a2

v1.0.0a1: v1.0.0 alpha1

发布于 2024-02-13 - GitHub - PyPI

在过去的几年里,Gym 和 Gymnasium 背后的志愿者团队一直致力于修复错误、改进文档、添加新功能以及在适当情况下更改 API,以确保收益大于成本。这是 v1.0.0 的第一个 alpha 版本,旨在结束项目 API 的变更之路,同时包含许多新功能和改进的文档。

要安装 v1.0.0a1,您必须使用 pip install gymnasium==1.0.0a1pip install --pre gymnasium,否则将安装 v0.29.1。同样,网站将默认显示 v0.29.1 的文档,您可以通过右下角的弹出窗口进行更改。

我们非常希望项目能够使用这些 v1.0.0 alpha 版本进行测试,以便在 v1.0 正式发布之前发现任何错误、缺失的文档或 API 更改方面的问题。

移除插件系统

在 Gym v0.23+ 和 Gymnasium v0.26 到 v0.29 中,一个用于在后台注册外部环境的未文档化功能已被移除。对于 Atari (ALE)MinigridHighwayEnv 的用户,以前可以使用以下代码

import gymnasium as gym

env = gym.make("ALE/Pong-v5")

这样即使从未导入 Atari (即,import ale_py),用户仍然可以加载 Atari 环境。此功能已在 v1.0.0 中移除,这将要求用户更新为

import gymnasium as gym
import ale_py

gym.register_envs(ale_py)  # optional

env = gym.make("ALE/Pong-v5")

或者,用户可以执行以下操作,其中环境 ID 中的 ale_py 将导入该模块

import gymnasium as gym

env = gym.make("ale_py:ALE/Pong-v5")  # `module_name:env_id`

对于使用 IDE(即 VSCode、PyCharm)的用户,import ale_py 可能导致 IDE(以及 pre-commit isort / black / flake8)认为该导入语句没有作用。因此,我们引入了 gymnasium.register_envs 作为空操作函数(该函数实际上什么都不做),以使 IDE 相信有事情正在发生,并且导入语句是必需的。

注意:ALE-py、Minigrid 和 HighwayEnv 必须更新才能与 Gymnasium v1.0.0 兼容,我们希望在 alpha 2 版本中完成所有受影响项目的更新。

向量环境

为了提高环境的采样速度,向量化是同时采样同一环境多个实例的最简单方法之一。Gym 和 Gymnasium 提供了 VectorEnv 作为其基类,但其中一个问题是它继承了 Env。这可能导致类型检查(step 的返回类型在 EnvVectorEnv 中不同)、环境类型测试(isinstance(env, Env) 对于向量环境可能为真,尽管两者行为不同)以及最终的包装器(一些 Gym 和 Gymnasium 包装器支持向量环境,但没有明确或一致的 API 来确定哪些支持哪些不支持)等特定问题。因此,我们已将 EnvVectorEnv 分开,使其不再相互继承。

在实现新的独立 VectorEnv 类时,我们努力最小化使用 EnvVectorEnv 的代码之间的差异,并使其在某些地方更具通用性。该类包含与 Env 相同的属性和方法,以及 num_envs: intsingle_action_space: gymnasium.Spacesingle_observation_space: gymnasium.Space。此外,我们从 VectorEnv 中移除了几个并非所有向量实现都需要的函数:step_asyncstep_waitreset_asyncreset_waitcall_asynccall_wait。这一更改现在允许用户编写自己的自定义向量环境,v1.0.0a1 包含一个示例向量 Cartpole 环境,其运行速度比使用 Gymnasium 的同步向量环境快数千倍。

为了方便用户创建向量化环境,我们提供了 gymnasium.make_vec,作为 gymnasium.make 的向量化等效函数。由于存在多种不同的向量化选项(“sync”、“async”以及称为“vector_entry_point”的自定义类),参数 vectorization_mode 用于选择环境的向量化方式。该参数默认为 None,这样如果环境具有自定义向量环境实现的向量入口点,将首先使用该入口点(目前,Cartpole 是 Gymnasium 中唯一内置向量入口点的环境)。否则,将使用同步向量化器(以前,Gym 和 Gymnasium 的 vector.make 默认使用异步向量化器)。欲了解更多信息,请参阅函数的 docstring

​​env = gym.make("CartPole-v1")
env = gym.wrappers.ClipReward(env, min_reward=-1, max_reward=3)

envs = gym.make_vec("CartPole-v1", num_envs=3)
envs = gym.wrappers.vector.ClipReward(envs, min_reward=-1, max_reward=3)

由于 `Env` 和 `VectorEnv` 的这种拆分,现在 `gymnasium.wrappers` 中有仅适用于 `Env` 的封装器,而 `gymnasium.wrappers.vector` 中有仅适用于 `VectorEnv` 的封装器。此外,我们将基础向量封装器的名称从 `VectorEnvWrapper` 更新为 `VectorWrapper`,并添加了 `VectorObservationWrapper`、`VectorRewardWrapper` 和 `VectorActionWrapper` 类。有关新信息,请参阅向量封装器页面。

为了提高向量环境的效率,自动重置 (autoreset) 是一种常见功能,它允许子环境在所有子环境完成之前进行重置,而无需等待所有子环境都完成。以前在 Gym 和 Gymnasium 中,自动重置是在环境剧集结束的同一步骤中完成的,因此最终的观察值和信息会存储在步骤的信息中,即 info["final_observation"]info[“final_info”],而标准的 obs 和 info 则包含子环境的重置观察值和信息。这需要向量化环境进行类似的通用采样。

replay_buffer = []
obs, _ = envs.reset()
for _ in range(total_timesteps):
    next_obs, rewards, terminations, truncations, infos = envs.step(envs.action_space.sample())

    for j in range(envs.num_envs):
        if not (terminations[j] or truncations[j]):
            replay_buffer.append((
                obs[j], rewards[j], terminations[j], truncations[j], next_obs[j]
            ))
        else:
            replay_buffer.append((
                obs[j], rewards[j], terminations[j], truncations[j], infos["next_obs"][j]
            ))

    obs = next_obs

然而,随着时间的推移,开发团队已经认识到这种方法的低效率(主要是由于大量使用了 Python 字典)以及必须提取最终观察结果才能正确训练智能体的麻烦,例如 此处。因此,在 v1.0.0 中,我们正在修改自动重置功能,使其与 EnvPoolSampleFactory 等专门的仅向量项目对齐,从而子环境直到下一步才会重置。因此,这要求在采样时进行以下更改。对于具有更复杂观察空间(和动作空间)的环境,则

replay_buffer = []
obs, _ = envs.reset()
autoreset = np.zeros(envs.num_envs)
for _ in range(total_timesteps):
    next_obs, rewards, terminations, truncations, _ = envs.step(envs.action_space.sample())

    for j in range(envs.num_envs):
        if not autoreset[j]:
            replay_buffer.append((
                obs[j], rewards[j], terminations[j], truncations[j], next_obs[j]
            ))

    obs = next_obs
    autoreset = np.logical_or(terminations, truncations)

最后,我们改进了 AsyncVectorEnv.set_attrSyncVectorEnv.set_attr 函数,使其使用 Wrapper.set_wrapper_attr,从而允许用户在环境堆栈中任何位置设置已存在的变量。以前,这是不可能的,用户只能修改环境堆栈中“顶部”包装器中的变量,重要的是无法修改实际环境本身。

封装器 (Wrappers)

以前,一些包装器(wrapper)可以同时支持标准环境和向量环境,但这种支持并未标准化,并且不清楚哪些包装器支持向量环境,哪些不支持。对于 v1.0.0 版本,通过将 EnvVectorEnv 分开,使其不再相互继承(详情请参阅向量部分),gymnasium.wrappers 中的包装器将仅支持标准环境,而 gymnasium.wrappers.vector 中的包装器包含提供的专用向量包装器(大多数但并非所有包装器都受支持,如果您需要,请提出功能请求)。

在 v0.29 中,我们弃用了 Wrapper.__getattr__ 函数,并由 Wrapper.get_wrapper_attr 取代,以提供对环境堆栈中任何位置变量的访问权限。在 v1.0.0 中,我们添加了 Wrapper.set_wrapper_attr 作为等效函数,用于在环境堆栈中任何位置设置变量(如果该变量已存在);只有在最顶层的包装器(或环境)中设置变量。

最重要的是,我们移除、重命名并添加了以下列出的几个包装器。

  • 已移除的包装器
    • monitoring.VideoRecorder - 替换包装器是 RecordVideo
    • StepAPICompatibility - 我们期望所有 Gymnasium 环境都使用 terminated / truncated 步进 API,因此,用户不应再需要 StepAPICompatibility 包装器。Shimmy 包含兼容性环境,用于将 gym-api 环境转换为 gymnasium 可用格式。
  • 已重命名的包装器(为了使包装器命名保持一致。因此,我们从所有包装器名称中移除了“Wrapper”,并在适当的地方包含了“Observation”、“Action”和“Reward”)
    • AutoResetWrapper -> Autoreset
    • FrameStack -> FrameStackObservation
    • PixelObservationWrapper -> AddRenderObservation
  • 已移动的包装器(所有向量包装器都位于 gymnasium.wrappers.vector 中)
    • VectorListInfo -> vector.DictInfoToList
  • 已添加的包装器
    • DelayObservation - 添加对下一个观察值和奖励的延迟
    • DtypeObservation - 修改环境观察空间的数据类型 (dtype)
    • MaxAndSkipObservation - 将跳过 n 个观察值,并取最近 2 个观察值的最大值,灵感来自 Atari 环境启发式算法,适用于其他环境
    • StickyAction - 以一定概率随机重复动作,并返回最终观察值和多个时间步的奖励总和。灵感来自 Atari 环境启发式算法
    • JaxToNumpy - 将基于 Jax 的环境转换为使用基于 Numpy 的输入和输出数据进行 resetstep 等操作
    • JaxToTorch - 将基于 Jax 的环境转换为使用基于 PyTorch 的输入和输出数据进行 resetstep 等操作
    • NumpyToTorch - 将基于 Numpy 的环境转换为使用基于 PyTorch 的输入和输出数据进行 resetstep 等操作

对于所有包装器,我们都添加了示例代码文档和更新日志,以帮助未来的研究人员了解所做的任何更改。例如,请参阅以下页面

函数式环境

Gymnasium 的 Env 的一个显著优点是它通常只需要关于底层环境规范的极少信息,然而,这使得将此类环境应用于规划、搜索算法和理论研究变得更加困难。我们提出 FuncEnv 作为 Env 的替代定义,它更接近马尔可夫决策过程的定义,向用户公开更多函数,包括观察、奖励和终止函数以及环境的原始状态作为单个对象。

from typing import Any
import gymnasium as gym
from gymnasium.functional import StateType, ObsType, ActType, RewardType, TerminalType, Params

class ExampleFuncEnv(gym.functional.FuncEnv):
  def initial(rng: Any, params: Params | None = None) → StateTypedef transition(state: StateType, action: ActType, rng: Any, params: Params | None = None) → StateTypedef observation(state: StateType, params: Params | None = None) → ObsTypedef reward(
      state: StateType, action: ActType, next_state: StateType, params: Params | None = None
  ) →   RewardTypedef terminal(state: StateType, params: Params | None = None) → TerminalType

FuncEnv 要求 initialtransition 函数在给定输入的情况下返回新状态,作为 Env.stepEnv.reset 的部分实现。因此,用户可以采样(并保存)给定一系列输入下的下一个状态,以用于规划、搜索等。给定一个状态,observationrewardterminal 为用户提供了明确的定义,以了解每个如何影响环境的输出。

其他错误修复

  • 由于 cython==3 的问题,限制 gymnasium[mujoco-py] 的 cython 版本,由 @pseudo-rnd-thoughts 完成 (#616)
  • 修复 MuJoCo 环境类型问题,由 @Kallinteris-Andreas 完成 (#612)
  • @logan-dunbar 修复了 MuJoCo 渲染时自定义宽度值的问题 (#634)
  • @chrisyeh96 修复了环境检查器以正确报告无限边界 (#708)
  • @younikregister(kwargs) 的类型提示从 **kwargs 修复为 kwargs: dict | None = None (#788)
  • 修复 CartPoleVectorEnv 步数计数器在 reset 时重置为零的问题,由 @TimSchneider42 完成 (#886)
  • 修复自定义环境的异步向量环境注册问题,由 @RedTachyon 完成 (#810)

其他新功能

弃用

文档变更

完整更新日志: v0.29.0...v1.0.0a1

v0.29.1

发布于 2023-08-21 - GitHub - PyPI

一个最小版本,修复了 Wrapper.__getattr__ 产生的警告。
特别是,此函数将在 v1.0.0 中移除,但报告的解决方案不正确,并且更新后的解决方案仍然导致警告显示(由于 Python 的技术原因)。

更改

  • Wrapper.__getattr__ 警告报告了不正确的新函数,是 get_attr 而非 get_wrapper_attr
  • 当使用 get_wrapper_attr 时,由于 get_wrapper_attr 内部使用了 hasattr,而 hasattr 又使用了 __getattr__,因此 __getattr__ 警告仍然会触发。所以已更新以移除意外警告。
  • VectorEnvWrapper.__getattr__ 添加警告,指明它在 v1.0.0 中也被弃用

完整更新日志: v0.29.0...v0.29.1

v0.29.0

发布于 2023-07-14 - GitHub - PyPI

v0.29.0 发布说明

我们终于为 Gymnasium 获得了软件引用,并计划在 v1.0 之后发布相关论文,感谢过去 3 年来所有为 Gym 和 Gymnasium 做出贡献的人 (#590)

@misc{towers_gymnasium_2023,
        title = {Gymnasium},
        url = {https://zenodo.org/record/8127025},
        abstract = {An API standard for single-agent reinforcement learning environments, with popular reference environments and related utilities (formerly Gym)},
        urldate = {2023-07-08},
        publisher = {Zenodo},
        author = {Towers, Mark and Terry, Jordan K. and Kwiatkowski, Ariel and Balis, John U. and Cola, Gianluca de and Deleu, Tristan and Goulão, Manuel and Kallinteris, Andreas and KG, Arjun and Krimmel, Markus and Perez-Vicente, Rodrigo and Pierré, Andrea and Schulhoff, Sander and Tai, Jun Jet and Shen, Andrew Tan Jin and Younis, Omar G.},
        month = mar,
        year = {2023},
        doi = {10.5281/zenodo.8127026},
}

Gymnasium 现已提供 conda 包,可以通过 conda install gymnasium 安装。感谢 @ChristofKaufmann 完成此项工作

重大变更

  • 终止对 Python 3.7 的支持,该版本已达到生命周期结束,由 @Kallinteris-Andreas#573 中完成
  • 更新 MuJoCo Hopper & Walker2D 模型以与 MuJoCo >= 2.3.3 兼容,由 @Kallinteris-Andreas#589 中完成
  • 为 v1.0 中将移除的几个功能添加弃用警告:Wrapper.__get_attr__gymnasium.make(..., autoreset=True)gymnasium.make(..., apply_api_compatibility=True)Env.reward_rangegymnasium.vector.make。关于其建议的替代方案,请参见 #535
  • Box 边界 low > highlow == infhigh == -inf 抛出错误,由 @jjshoots#495 中完成
  • data_equivalence() 中为 NumPy 数组添加 dtype 测试,由 @pseudo-rnd-thoughts#515 中完成
  • 从 gymnasium 包装器中移除 Jumpy,因为它仅部分实现,测试和使用有限,由 @pseudo-rnd-thoughts#548 中完成
  • 更新项目对 jax>=0.4 的要求,由 @charraut 在 #373 中完成

新特性

  • 移除 pygame 版本限制 pygame>=2.1.3,由 @pseudo-rnd-thoughts#558 中完成
  • MultiDiscrete 空间添加 start 参数,类似于 Discrete(..., start) 参数,由 @Rayerdyne#557 中完成
  • check_env 添加测试,确保关闭已关闭的环境不会引发错误,由 @pseudo-rnd-thoughts#564 中完成
  • 在初始化时,如果环境具有无效的渲染模式 (None, "human", "ansi")wrapper.RecordVideo 会抛出错误,由 @robertoschiavone#580 中完成
  • 添加 MaxAndSkipObservation 包装器,由 @LucasAlegre#561 中完成
  • 添加 check_environments_match 函数,用于检查两个环境是否相同,由 @Kallinteris-Andreas#576 中完成
  • 添加性能调试工具 utils/performance.py,由 @Kallinteris-Andreas#583 中完成
  • 新增基于 Jax 的 Cliff Walking 环境,由 @balisujohn#407 中完成
  • MuJoCo
  • 实验性功能
    • gymnasium.experimental.wrappers 中添加已弃用的包装器错误,由 @charraut 在 #341 中提出
    • RecordVideoV0 添加 fps 参数,用于自定义帧率值,该值将覆盖环境内部的 render_fps 值,由 @younik#503 中提出
    • 为 lambda 观察、动作和奖励包装器添加实验性向量包装器,由 @pseudo-rnd-thoughts#444 中提出

错误修复

  • 修复 spaces.Dict.keys(),因为 key in keys 曾为 False,由 @pseudo-rnd-thoughts#608 中提出
  • 根据边界更新 wrappers.RescaleAction 的动作空间,由 @mmcaulif#569 中提出
  • 移除被动环境检查器中关于无限 Box 边界的警告,由 @pseudo-rnd-thoughts#435 中提出
  • 回滚 Lunar Lander 观察空间更改,由 @alexdlukens#512 中提出
  • 修复 check_env 中的 URL 链接,由 @robertoschiavone#554 中提出
  • shimmy[gym] 更新为 shimmy[gym-v21]shimmy[gym-v26],由 @elliottower#433 中提出
  • 修复实验性向量环境和包装器中的若干问题,由 @pseudo-rnd-thoughts#516 中提出
  • 视频录制器包装器
    • 修复 VideoRecorderreset 时清空 recorded_frames 而非 frames 的问题,由 @voidflight#518 中提出
    • VideoRecorder.close 中移除 Env.close,由 @qgallouedec#533 中提出
    • 修复 VideoRecorderRecordVideoV0,将 import moviepy 移动,以避免 __del__ 抛出 AttributeErrors,由 @pseudo-rnd-thoughts#553 中提出
  • Mujoco

文档更新

完整更新日志: v0.28.1...v0.29.0

v0.28.1

发布于 2023-03-25 - GitHub - PyPI

v0.28.1 发布说明

小型紧急发布,修复若干问题

  • 修复 gymnasium.vector,因为它没有在 gymnasium/__init__.py 中导入 #403
  • 更新第三方环境,以区分支持 gymnasium 和 gym 的环境并保持一致的风格 #404
  • 更新 v0.28 的文档,因首页 GIF 链接错误,缺少实验性文档并添加 gym 发布说明 #405

完整更新日志: v0.28.0...v0.28.1

v0.28.0

发布于 2023-03-24 - GitHub - PyPI

v0.28.0 发布说明

此版本引入了对 Gymnasium 环境可重现性的改进支持,特别是针对离线强化学习。gym.make 现在可以创建完整的环境堆栈,包括包装器,以便训练库或离线数据集可以指定用于环境的所有参数和包装器。对于大多数标准用法(gym.make(”EnvironmentName-v0”)),这将向后兼容,但某些相当不常见的情况(即 env.specenv.unwrapped.spec 返回不同的规范)除外,这是一个破坏性更改。有关更多信息,请参阅可重现性详情部分。
在 v0.27 中,我们添加了 experimental 文件夹,以便开发多项新功能(包装器和硬件加速环境)。我们引入了一个新的实验性 VectorEnv 类。此类别不继承自标准 Env 类,并将允许显着提高并行化效率。我们计划在未来几个月的几个次要版本中改进实现并添加基于向量的包装器。
此外,我们优化了模块加载,使 PyTorch 或 Jax 仅在用户导入需要它们的包装器时加载,而不是在 import gymnasium 时加载。

可重现性详情

在以前的版本中,Gymnasium 支持 gym.make(spec),其中 spec 是来自 gym.spec(str)env.specEnvSpec,并且与基于字符串的 gym.make(“”) 工作方式相同。在这两种情况下,都无法指定应用于环境的额外包装器。在此版本中,我们为 EnvSpec 添加了 additional_wrappers,用于指定应用于基础环境的包装器(TimeLimitPassiveEnvCheckerAutoresetApiCompatibility 未包含在内,因为它们在其他字段中指定)。
这个额外字段将允许用户准确地保存或重现用于策略训练或生成离线 RL 数据集的环境。我们提供了一个 json 转换函数(EnvSpec.to_json),用于将 EnvSpec 保存为“安全”的文件类型,但有几种情况(NumPy 数据、函数)无法保存为 json。在这些情况下,我们建议使用 pickle,但请注意,这可能会允许远程用户在规范中包含恶意数据。

import gymnasium as gym

env = gym.make("CartPole-v0")
env = gym.wrappers.TimeAwareObservation(env)
print(env)  
# <TimeAwareObservation<TimeLimit<OrderEnforcing<PassiveEnvChecker<CartPoleEnv<CartPole-v0>>>>>>
env_spec = env.spec
env_spec.pprint()
# id=CartPole-v0
# reward_threshold=195.0
# max_episode_steps=200
# additional_wrappers=[
# 	name=TimeAwareObservation, kwargs={}
# ]

import json
import pickle

json_env_spec = json.loads(env_spec.to_json())
pickled_env_spec = pickle.loads(pickle.dumps(env_spec))
recreated_env = gym.make(json_env_spec)
print(recreated_env)  
# <TimeAwareObservation<TimeLimit<OrderEnforcing<PassiveEnvChecker<CartPoleEnv<CartPole-v0>>>>>>
# Be aware that the `TimeAwareObservation` was included by `make`

为了支持这种重现,包装器必须继承自 gym.utils.RecordConstructorUtils,以便 gym.make 知道用哪些参数创建包装器。Gymnasium 已为所有内置包装器实现了这一点,但对于外部项目,应将其添加到每个包装器中。为此,在包装器构造函数的第一行调用 gym.utils.RecordConstructorUtils.__init__(self, …),并传入与包装器构造函数相同的关键字参数,除了 env。例如,请参见 Atari 预处理包装器
有关更详细的讨论,请参阅原始 PR - #292#355

其他重大变更

  • 在 Gymnasium v0.26 中,添加了 GymV22Compatibility 环境以支持 Gymnasium 中的基于 Gym 的环境。然而,该名称不正确,因为该环境支持 Gym 的 v0.21 API,而不是 v0.22,因此,我们已将其更新为 GymV21Compatibility 以准确反映所支持的 API。 #282
  • Sequence 空间允许观察或动作空间样本中包含动态数量的元素。为了提高效率,我们添加了一个 stack 参数,它可以支持比之前支持的 tuple 更高效的元素表示。 #284
  • 之前,Box.sample 在处理有上限空间时会错误地截断,导致如果 dtype 是离散或布尔类型,则永远无法采样到 0。现在已修复此问题,以便在这些情况下可以采样到 0。 #249
  • 如果安装了 jaxpytorch,那么在 import gymnasium 时,这两个模块也会被加载,导致加载时间显着变慢。现在已修复此问题,jaxtorch 仅在用户加载特定包装器时加载。 #323
  • 在 v0.26 中,我们为 Wrapper 添加了参数,以允许为包装器及其子环境指定不同的观察和动作类型。然而,这导致了 pyright 和 mypy 的类型问题,现在通过 Wrapper 拥有四个通用参数 [ObsType, ActType, WrappedEnvObsType, WrappedEnvActType] 解决了这个问题。 #337
  • 在 v0.25 和 v0.26 中引入了几个新的空间类型:TextGraphSequence,但向量实用函数没有更新以支持这些空间。现在已将对这些空间的支持添加到实验性向量空间实用函数中:batch_spaceconcatenateiteratecreate_empty_array#223
  • 由于缺乏测试,实验性有状态观察包装器(FrameStackObservationDelayObservationTimeAwareObservation)未能按预期工作。这些包装器现已修复并添加了测试。 #224

次要变更

  • 允许在评估期间禁用和启用 NormalizeX 包装器的统计信息,由 @raphajaner#268 中提出
  • 修复 lunar_lander.py 中的 AttributeError,由 @DrRyanHuang#278 中提出
  • 添加文档字符串测试 (doctest),以使文档字符串与实现匹配,由 @valentin-cnt 在 #281 中提出
  • 类型提示修复并添加了 __all__ 特殊方法,由 @howardh#321 中提出
  • 修复 gymnasium/spaces 中的类型提示错误,由 @valentin-cnt 在 #327 中提出
  • 更新实验性向量共享内存实用函数,由 @pseudo-rnd-thoughts#339 中提出
  • 将 Gymnasium 通知更改为 Farama 通知,由 @jjshoots#332 中提出
  • 添加了基于 Jax 的 Blackjack 环境,由 @balisujohn#338 中提出

文档变更

  • @Matyasch#279 中修复了文档中 MultiBinary 和 MultiDiscrete 类的引用。
  • @nerdyespresso#304 中添加了 Comet 集成。
  • @pseudo-rnd-thoughts#330 中更新了 Atari 文档。
  • @mihaic#331 中记录了 Box 整数边界。
  • 由 @valentin-cnt 在 #329 中添加了文档字符串解析器,以移除 Gymnasium 网站中的重复内容。
  • 由 @keyb0ardninja 在 #333 中修复了基本用法页面中的一个语法错误。
  • @mgoulao#340 中更新了 docs/README.md,以链接到新的文档贡献指南 CONTRIBUTING.md。
  • @Kallinteris-Andreas#342 中澄清了 MuJoCo/Ant 在 v3(及更早版本)中缺少 use_contact_forces 的问题。

更新内容

感谢本次发布的新贡献者:@Matyasch, @DrRyanHuang, @nerdyespresso, @khoda81, @howardh, @mihaic, 和 @keyb0ardninja。

完整更新日志: v0.27.1...v0.28.0

v0.27.1

发布于 2023-01-20 - GitHub - PyPI

发行说明

修复的 Bug

新功能/改进

  • @PaulMest#235 中将 LunarLander-v2 step 性能提升了 1.5 倍以上。
  • @nidhishs#238 中为 StepAPICompatibility 包装器添加了向量环境支持。
  • @jjshoots#241 中允许序列在特征空间为 Box 时接受堆叠的 numpy 数组。
  • @pseudo-rnd-thoughts#225 中改进了从插件引发错误时的警告。
  • @mgoulao#257 中将更新日志(发行说明)添加到了网站。
  • @younik#246 中实现了 RecordVideoV0。
  • @PierreMardon#267 中添加了当离散和多离散解压失败时的明确错误消息。

文档更新

感谢 Gymnasium 的新贡献者,如果你想参与进来,请加入我们的 Discord 服务器。链接在 README 中。

完整更新日志: v0.27.0...v0.27.1

v0.27.0

发布于 2022-12-12 - GitHub - PyPI

发行说明

Gymnasium 0.27.0 是 Gymnasium 的第一个主要版本。它包含了几个重要的新功能,以及随着我们处理积压工作而进行的众多小错误修复和代码质量改进。除了放弃 Python 3.6 支持并将 mujoco Viewer 类替换为 MujocoRendering 类之外,应该没有其他破坏性更改。您应该能够以很少的精力将使用 Gymnasium 0.26.x 的代码升级到 0.27.0。

一如既往,我们的开发路线图 此处 公开可用,因此您可以关注我们未来的计划。唯一仍在计划中的重大破坏性更改是将选定的环境切换为使用硬件加速物理引擎,以及我们长期以来对向量 API 和内置包装器进行大修的计划。

本次发布值得注意的是包含了一个全新的库部分:gymnasium.experimental。我们正在添加新功能、包装器和下面讨论的功能性环境 API,供用户测试和试用,以发现 Bug 并提供反馈。

新包装器

这些新包装器可在 gymnasium.experimental.wrappers 中访问,完整列表请参见 https://gymnasium.org.cn/main/api/experimental/。它们旨在替换 Gymnasium v0.30.0 中的包装器,并包含多项改进。

  • (正在进行中)支持任意复杂的观测/动作空间。随着强化学习的发展,动作和观测空间变得越来越复杂,而当前的包装器在实现时并未考虑到这一点。
  • 支持基于 Jax 的环境。随着硬件加速环境(例如,用 Jax 编写的 Brax 和类似的基于 PyTorch 的程序)的出现,NumPy 不再是编写环境的唯一选择。因此,这些升级将使用 Farama Foundation 开发的项目 Jumpy,它为 NumPy、Jax 以及未来 PyTorch 数据的大部分 NumPy 函数提供自动兼容性。
  • 更多包装器。像 Supersuit 这样的项目旨在为强化学习带来更多包装器,然而,许多用户并不知道这些包装器,所以我们计划将这些包装器移入 Gymnasium。如果上面提供的列表中缺少常用包装器,请创建一个 issue,我们有兴趣将其添加。
  • 版本控制。与环境一样,包装器的实现细节可能会导致智能体性能的变化。因此,我们建议为所有包装器添加版本号,例如 LambaActionV0。我们不期望这些版本号会定期更改,它们将与环境版本号类似。这应该能确保所有用户都知道何时会发生可能影响您的智能体在环境和包装器中性能的重大更改。此外,我们希望这将提高未来强化学习的重现性,这对于学术界至关重要。
  • 在 v28 中,我们旨在重写 VectorEnv,使其不继承自 Env,因此将提供包装器的新向量化版本。

核心开发者:@gianlucadecola, @RedTachyon, @pseudo-rnd-thoughts

函数式 API

Env 类为环境提供了非常通用的结构,允许程序结构具有高度灵活性。然而,这限制了高效向量化环境、将环境代码模块化等能力。因此,gymnasium.experimental.FuncEnv 为环境实现提供了更严格的结构,其中每个环境实现阶段都使用无状态函数。这个类不继承自 Env,并且需要一个转换/兼容类来完成此操作。我们已经提供了 FuncJaxEnv 用于将基于 Jax 的 FuncEnv 转换为 Env。我们希望这将有助于提高环境实现的可读性,并为向量化代码的用户带来潜在的加速。

此 API 处于高度实验阶段,未来可能会有改动。我们对尝试使用此 API 的用户提供的反馈很感兴趣,我们认为这对于探索强化学习规划、基于模型的强化学习以及修改环境函数(如奖励)的用户尤其有用。

核心开发者:@RedTachyon, @pseudo-rnd-thoughts, @balisujohn

其他重大更改

  • @rodrigodelazcano#112 中重构了 Mujoco 渲染机制,为 OpenGL 使用单独的线程。移除 Viewer,转而使用 MujocoRenderer,后者可用于离屏、人机及其他渲染模式。
  • @pseudo-rnd-thoughts#125 中为 gym.make(..., apply_env_compatibility=True) 添加了弃用警告,建议改用 gym.make("GymV22Environment", env_id="...")
  • @kad99kev#124 中添加了 gymnasium.pprint_registry() 用于美观地打印 Gymnasium 注册表。
  • @pseudo-rnd-thoughts#141 中将 Discrete.dtype 更改为 np.int64,以便样本为 np.int64 而非 Python 整数。
  • @pseudo-rnd-thoughts#72 中添加了 OpenAI Gym v21 到 v26 的迁移指南。
  • @pseudo-rnd-thoughts#39 中为 core.py 中的 EnvWrapper 等添加了完整的类型提示。
  • @pseudo-rnd-thoughts#37 中为 gymnasium.spaces 中的所有空间添加了完整的类型提示。
  • @Markus28#190 中使 play() 中的窗口可调整大小。
  • @siddarth-c#155 中添加了 REINFORCE 实现教程。

Bug 修复和文档更改

  • @younik#42 中移除了 VideoRecorder 包装器中的自动关闭。
  • @theo-brown#74 中将 seeding.np_random 错误消息更改为报告种子类型。
  • @ikamensh#83 中在 MujocoEnv 错误消息中包含了形状信息。
  • @tobirohrer#89 中添加了美观的特性/GitHub issue 表单。
  • check_envPassiveEnvChecker 中增加了渲染返回数据的测试,由 @Markus28 提交于 #117
  • 修复了经典控制环境的文档字符串并更新了动作空间描述,由 @Thytu 提交于 #123
  • 修复了根目录 __init__.py 中的 __all__ 以指定正确的文件夹,由 @pseudo-rnd-thoughts 提交于 #130
  • 修复了 play() 断言错误,由 @Markus28 提交于 #132
  • 更新了 Frozen Lake 的 is_slippy 文档,由 @marionjs 提交于 #136
  • 修复了 render_mode 为 None 时的警告,由 @younik 提交于 #143
  • 为文档添加了 is_np_flattenable 属性,由 @Markus28 提交于 #172
  • 更新了 Wrapper 文档,由 @Markus28 提交于 #173
  • 更新了 spaces 文档的格式,由 @Markus28 提交于 #174
  • 针对 FrozenLake,在随机地图生成中添加了种子设定,由 @kir0ul 提交于 #139
  • 添加了从扁平化空间中反扁平化样本时的问题说明,由 @rusu24edward 提交于 #164
  • 在网站中添加了 pusher 环境页面,由 @axb2035 提交于 #171
  • AsyncVectorEnv 中的 step_wait 分割结果之前添加了成功检查,由 @aaronwalsman 提交于 #178
  • MuJoCo.Ant-v4.use_contact_forces 添加了文档,由 @Kallinteris-Andreas 提交于 #183
  • 修复了 README.md 中的拼写错误,由 @cool-RR 提交于 #184
  • MuJoCo.Ant v4 变更日志添加了文档,由 @Kallinteris-Andreas 提交于 #186
  • 修复了 MuJoCo.Ant 文档中的动作顺序,由 @Kallinteris-Andreas 提交于 #208
  • 为整个代码库添加了 raise-from 异常,由 @cool-RR 提交于 #205

幕后更改

v0.26.3

发布于 2022-10-24 - GitHub - PyPI

发行说明

注意:ale-py (atari) 尚未更新到 Gymnasium。因此 pip install gymnasium[atari] 将会失败,这将在 v0.27 中修复。在此期间,请使用 pip install shimmy[atari] 进行修复。

错误修复

  • 增加了 Gym-Gymnasium 兼容性转换器,允许用户在 Gymnasium 中使用 Gym 环境,由 @RedTachyon 提交于 #61
  • 修改了 HumanRenderingRenderCollection 包装器中的元数据,使其具有正确的元数据,由 @RedTachyon 提交于 #35
  • 简化了 EpisodeStatisticsRecorder 包装器,由 @DavidSlayback 提交于 #31
  • 修复了 MultiDiscrete.flatten() 中的整数溢出问题,由 @olipinski 提交于 #55
  • 重新添加了为 Mujoco 环境指定 XML 文件的功能,由 @Kallinteris-Andreas 提交于 #70

文档更改

完整变更日志v0.26.2...v0.26.3

感谢新贡献者

v0.26.2

发布于 2022-10-05 - GitHub - PyPI

此版本是 Gym v26.2 的上游版本

Bug 修复

  • 由于 reset 现在返回 (obs, info),这导致在向量环境中,最终步骤的信息被覆盖。现在,最终的观察和信息作为 “final_observation” 和 “final_info” 包含在 info 中。@pseudo-rnd-thoughts
  • 尝试在未指定 render_mode 时添加警告 @younik
  • 更新了 Atari 预处理,使得包装器可以被序列化 (pickled) @vermouth1992
  • GitHub CI 得到了加强,使其仅具有读取权限 @sashashura
  • 澄清并修复了 GraphInstance 中的拼写错误 @ekalosak

v0.26.1

发布于 2022-09-16 - GitHub - PyPI

此版本是 Gym v26.1 的上游版本

此外,gym docs 仓库已与新网站 https://gymnasium.org.cn/ 合并。

v0.26.0: 首次发布

发布于 2022-09-13 - GitHub - PyPI

这是 Gymnasium 的首次发布,它是 OpenAI Gym 的一个维护分支。

此版本与 Gym v0.26.0 完全相同,但项目名称(Gymnasium)和行为准则除外。

阅读 #12 查看变更路线图。