Gymnasium 版本说明¶
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)、Minigrid 或 HighwayEnv 的用户,以前可以使用以下代码
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 包含一个示例矢量 cartpole 环境,它完全使用 NumPy 编写,运行速度比使用 Gymnasium 的同步矢量环境快数千倍。
为了让用户能够轻松创建矢量化环境,我们提供 gymnasium.make_vec
作为 gymnasium.make
的矢量化等效项。由于有多种不同的矢量化选项(“同步”、“异步”以及称为“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
和 gymnasium.wrappers.vector
中分别包含了仅限 Env
的包装器和仅限 VectorEnv
的包装器。此外,我们更新了基本矢量包装器名称,从 VectorEnvWrapper
变为 VectorWrapper
,并添加了 VectorObservationWrapper
、VectorRewardWrapper
和 VectorActionWrapper
类。有关新信息,请参阅 矢量包装器 页面。
为了提高矢量环境的效率,自动重置是一个常见功能,它允许子环境在不需要所有子环境都完成之前就重置,而无需要求所有子环境都完成再重置它们。以前在 Gym 和 Gymnasium 中,自动重置是在环境剧集结束的同一步骤上完成的,因此最终的观测和信息将存储在步骤的信息中,即 info["final_observation"]
和 info[“final_info”]
以及包含子环境重置观测和信息的标准观测和信息。因此,从矢量环境中准确地采样观测需要以下代码(注意,如果子环境已终止或截断,则需要提取 infos["next_obs"][j]
)。此外,对于使用展开的策略性算法,需要额外的前向传递来计算正确的下一个观测(这通常不作为优化来完成,假设环境只终止,不会截断)。
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 字典)以及不得不提取最终观测以正确训练智能体的烦恼,例如 example。因此,在 v1.0.0 中,我们正在修改自动重置,使其与专门的矢量项目(如 EnvPool 和 SampleFactory)保持一致,在这些项目中,子环境不会在下一步骤之前重置。因此,在采样时需要进行以下更改
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)
对于策略性展开,为了解决自动重置问题,需要屏蔽新剧集中的第一个观测的错误(done[t+1]
),以防止计算剧集的最后一个观测和第一个观测之间的错误。
最后,我们已经改进了 AsyncVectorEnv.set_attr
和 SyncVectorEnv.set_attr
函数,以便使用 Wrapper.set_wrapper_attr
允许用户在环境堆栈中的任何位置设置变量,如果该变量已经存在。以前,这是不可能的,用户只能修改环境堆栈上的“顶部”包装器中的变量,重要的是,不能修改实际环境本身。
包装器
以前,一些包装器可以支持环境和矢量环境,但是,这并不标准化,也不清楚哪些包装器支持哪些不支持矢量环境。对于 v1.0.0,随着 Env
和 VectorEnv
分开不再相互继承(在矢量部分中详细了解),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 环境都使用已终止/截断步骤 API,因此,用户不应该需要StepAPICompatibility
包装器。 Shimmy 包含一个兼容环境,用于将 gym-api 环境转换为 gymnasium。
- 已重命名的包装器(我们希望包装器的命名保持一致。因此,我们已从所有包装器中删除了“Wrapper”,并在适当的位置包含了“Observation”、“Action”和“Reward”)
AutoResetWrapper
->Autoreset
FrameStack
->FrameStackObservation
PixelObservationWrapper
->AddRenderObservation
- 已移动的包装器(所有矢量包装器都在
gymnasium.wrappers.vector
中)VectorListInfo
->vector.DictInfoToList
- 已添加的包装器
DelayObservation
- 将延迟添加到下一个观测和奖励DtypeObservation
- 修改环境的观测空间的 dtypeMaxAndSkipObservation
- 会跳过n
个观察结果,并在最后 2 个观察结果上取最大值,灵感来自 Atari 环境中针对其他环境的启发式方法StickyAction
- 以一定的概率随机重复动作,并返回最后一步的观察结果和多步奖励总和。灵感来自 Atari 环境的启发式方法JaxToNumpy
- 将基于 Jax 的环境转换为使用基于 Numpy 的输入和输出数据,用于reset
、step
等JaxToTorch
- 将基于 Jax 的环境转换为使用基于 PyTorch 的输入和输出数据,用于reset
、step
等NumpyToTorch
- 将基于 Numpy 的环境转换为使用基于 PyTorch 的输入和输出数据,用于reset
、step
等
对于所有包装器,我们添加了示例代码文档和变更日志,以帮助未来的研究人员理解所做的任何更改。请参阅以下 页面 了解示例。
功能性环境
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
要求 initial
和 transition
函数在给定其输入时返回一个新状态,作为 Env.step
和 Env.reset
的部分实现。因此,用户可以针对一系列输入对下一个状态进行采样(并保存),以用于规划、搜索等。给定一个状态,observation
、reward
和 terminal
为用户提供明确的定义,以了解每个因素如何影响环境的输出。
收集种子值
以前,环境和空间可以使用 None
来进行种子,以使用随机初始种子值,但是无法知道这些初始种子值是什么。我们在 #1033 和 #889 中解决了 Space.seed
和 reset.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
环境,并在 MuJoCov5
中更新了该模型,以生成更符合预期的行为,类似于v4
和mujoco< 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
现在与 ROM 一起打包,这意味着用户不需要使用autoroms
单独安装 Atari ROM。
其他错误修复
spaces.Box
允许低值和高值超出数据类型的范围,这会导致一些非常奇怪的边缘情况,很难被 @pseudo-rnd-thoughts 发现 (#774)- 由于 @pseudo-rnd-thoughts 提出的
cython==3
问题,限制gymnasium[mujoco-py]
的 cython 版本 (#616) - 通过 @logan-dunbar 修复了使用自定义宽度值的 mujoco 渲染问题 (#634)
- 通过 @chrisyeh96 修复了环境检查器,以正确报告无限边界 (#708)
- 通过 @younik 修复了
register(kwargs)
的类型提示,从**kwargs
更改为kwargs: dict | None = None
(#788) - 通过 @RedTachyon 修复了
AsyncVectorEnv
中针对自定义环境的注册问题 (#810) - 通过 @MischaPanch 删除了 v4+ MuJoCo 环境的
mujoco-py
导入错误
(#934) - 修复了
Tuple
和Dict
空间的共享内存读取问题 (#941) - 修复了 Windows 上的
Multidiscrete.from_jsonable
问题 (#932) - 删除了
play
渲染规范化问题 (#956) - 通过 @mantasu 修复了
to_torch
转换中未使用的设备参数问题 (#1107) - 通过 @mantasu 修复了在 GPU 上执行 torch 到 numpy 转换时的问题 (#1109)
其他新功能
- 通过 @RedTachyon 在 #1094 中添加了 Python 3.12 和 NumPy 2.0 支持
- 通过 @logan-dunbar 在 MuJoCo 人工渲染中添加了更改查看窗口大小的功能 (#635)
- 通过 @guyazran (#731) 在 MuJoCo 渲染中添加更多对屏幕外尺寸和场景几何体的控制。
- 通过 @pseudo-rnd-thoughts 在 #1119 中将堆栈跟踪报告添加到
AsyncVectorEnv
。 - 通过 @RogerJL (#789) 和 @pseudo-rnd-thoughts (#811) 为
JaxToNumpy
、JaxToTorch
和NumpyToTorch
添加对处理NamedTuples
的支持。 - 通过 @jamartinh (#830) 为
FrameSkipObservation
添加padding_type
参数以选择填充观察结果。 - 通过 @Kallinteris-Andreas (#748) 为
check_environments_match
添加渲染检查。 - 通过 @RedTachyon 和 @pseudo-rnd-thoughts (#812) 添加一个新的
OneOf
空间,它提供了空间的排他性并集。 - 由于放弃了对 Python 3.7 的支持,通过 @pseudo-rnd-thoughts (#977) 更新
Dict.sample
以使用标准的 Python 字典而不是OrderedDict
。 - 通过 @RedTachyon 和 @pseudo-rnd-thoughts (#817) Jax 环境返回 Jax 数据而不是 numpy 数据。
- 通过 @pseudo-rnd-thoughts 和 @TimSchneider42 (#1013) 添加
wrappers.vector.HumanRendering
并从CartPoleVectorEnv
中删除人类渲染。 - 通过 @pseudo-rnd-thoughts (#957) 如果用户混合使用 Gym 和 Gymnasium,则添加更多有用的错误消息。
- 通过 @Kallinteris-Andreas (#958) 为
CartPole
添加sutton_barto_reward
参数,该参数将奖励函数更改为不在终止状态返回 1。 - 通过 @Kallinteris-Andreas (#965) 为 MuJoCo 环境添加
visual_options
渲染参数。 - 通过 @Kallinteris-Andreas (#924) 为
utlis.env_checker.data_equivilance
添加exact
参数。 - 通过 @pseudo-rnd-thoughts (#978) 更新
wrapper.NormalizeObservation
观察空间并将观察结果更改为float32
。 - 通过 @pseudo-rnd-thoughts (#982) 在
env.spec
期间捕获异常,如果 kwarg 不可序列化。 - 通过 @turbotimon (#1009) 改进 Box2D 的 ImportError。
- 通过 @pseudo-rnd-thoughts (#1105) 为 AtariPreprocessing 包装器添加了 (int, int) 屏幕尺寸元组选项。
- 通过 @CloseChoice (#1087) 为 cliffwalking 环境添加
is_slippery
选项。 - 通过 @TimSchneider42 (#1095) 更新
RescaleAction
和RescaleObservation
以支持np.inf
边界。 - 通过 @qgallouedec (#1086) 更新
env.reset(seed=42); env.reset()
的确定性检查。 - 通过 @Kallinteris-Andreas (#1075) 重构 mujoco 以删除
BaseMujocoEnv
类。
弃用
- 通过 @pseudo-rnd-thoughts (#801) 从 error.py 中删除不必要的错误类。
- 通过 @Kallinteris-Andreas (#827) 停止从
gymnasium.envs.mujoco
中导出 MuJoCo v2 环境类。 - 由 @pseudo-rnd-thoughts 从 PlayPlot 中移除弃用警告 (#800)
文档变更
- 由 @kir0ul 更新了 v1.0.0 的自定义环境教程 (#709)
- 由 @btjanaka 将 swig 添加到 Box2D 的安装说明中 (#683)
- 由 @Kallinteris-Andreas 添加了使用
Gymnasium/MuJoCo/Ant-v5
框架加载自定义四足机器人环境的教程 (#838) - 由 @pseudo-rnd-thoughts 添加了一个第三方教程页面,用于列出在其他网站上撰写和托管的教程 (#867)
- 由 @pseudo-rnd-thoughts 添加了更多入门页面 (#791)
- 由 @Kallinteris-Andreas 为每个 MuJoCo 环境添加了代表其动作空间的图形 (#762)
- 由 @pseudo-rnd-thoughts 修正了关于 blackjack 初始状态的文档 (#893)
- 由 @britojr 在 #1120 中更新了出租车环境文档,以澄清初始状态定义。
- 由 @PierreCounathe 修正了关于 Frozenlake 和 Cliffwalking 位置的文档 (#695)
- 由 @pseudo-rnd-thoughts 更新了经典控制环境的
__init__
和reset
参数 (#898)
完整变更日志: 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 环境
提供 Atari 环境的 ale-py 已在 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.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 的推杆与 MuJoCo
>= 3
不兼容,因为错误修复发现了代理必须推动的块的模型密度是空气的密度。这显然开始对使用 MuJoCo v3+ 和推杆的用户造成问题。因此,我们禁用了 MuJoCo>= 3
中的v4
环境,并更新了 MuJoCov5
中的模型,该模型产生了与v4
和 MuJoCo< 3
类似的更预期行为 (#1019)。 - Alpha 2 包括新的 v5 MuJoCo 环境,作为两年前添加的 v4 环境的后续版本,修复了一致性,添加了新功能并更新了文档。我们已决定将 MuJoCo-py(v2 和 v3)环境标记为弃用,并计划在将来从 Gymnasium 中移除它们 (#926)。
- Lunar Lander 的版本从 v2 升级到 v3,这是由于两个错误修复。第一个修复了环境的确定性,以便在重置时世界对象不会完全被破坏,从而在某些情况下导致不确定性 (#979)。第二个是,风力生成(默认情况下关闭)在每次重置时不会随机生成,因此,我们更新了它以在各集之间获得统计独立性 (#959).
Box 采样
发现 spaces.Box
允许低值和高值超出数据类型的范围 (#774),这会导致一些非常奇怪的边缘情况,这些情况非常难以检测。我们希望这些更改能够改善调试和检测对空间的无效输入,但是,如果您的环境引发了与这相关的错误,请告知我们。
错误修复
- 更新
CartPoleVectorEnv
以适应新的自动重置 API (#915) - 修复了来自新的自动重置 API 的
wrappers.vector.RecordEpisodeStatistics
集数长度计算 (#1018) - 移除 v4+ MuJoCo 环境的
mujoco-py
导入错误 (#934) - 修复
make_vec(**kwargs)
未传递到向量入口点环境 (#952) - 修复了
Tuple
和Dict
空间的共享内存读取问题 (#941) - 修复 Windows 上的
Multidiscrete.from_jsonable
(#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 不可序列化 (#982) - 改进 Box2D 的 ImportError (#1009)
- 为 VectorEnv 和 VectorWrapper 添加元数据字段 (#1006)
- 修复修改 make 参数时用于同步或异步的
make_vec
(#1027)
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.0a1
或 pip 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)、Minigrid 或 HighwayEnv 的用户,可以使用以下代码
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
。这可能会导致类型检查方面的特殊问题(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.0a1 包含一个示例向量弹簧杆环境,其运行速度比使用 Gymnasium 的同步向量环境快数千倍。
为了让用户能够轻松地创建向量化环境,我们提供 gymnasium.make_vec
作为 gymnasium.make
的向量化等效项。由于存在多种不同的向量化选项(“同步”、“异步”以及称为“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
和 gymnasium.wrappers.vector
中分别包含了仅限 Env
的包装器和仅限 VectorEnv
的包装器。此外,我们更新了基本矢量包装器名称,从 VectorEnvWrapper
变为 VectorWrapper
,并添加了 VectorObservationWrapper
、VectorRewardWrapper
和 VectorActionWrapper
类。有关新信息,请参阅 矢量包装器 页面。
为了提高向量环境的效率,自动重置是一项常见功能,允许子环境在不需要所有子环境都完成之前就重置,而无需重置所有子环境。以前在 Gym 和 Gymnasium 中,自动重置是在环境情节结束的同一步骤完成的,因此最终的观测值和信息将存储在该步骤的信息中,即 info["final_observation"]
和 info[“final_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 中,我们正在修改自动重置以与像 EnvPool 和 SampleFactory 这样的专门的仅向量项目保持一致,这样子环境就不会在下一步骤之前重置。因此,这需要在采样时进行以下更改。对于具有更复杂观测空间(以及操作动作)的环境,则
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_attr
和 SyncVectorEnv.set_attr
函数,以便使用 Wrapper.set_wrapper_attr
允许用户在环境堆栈中的任何位置设置变量,如果它已经存在。以前,这是不可能的,用户只能修改环境堆栈上“顶部”包装器中的变量,重要的是,不能修改实际环境本身。
包装器
以前,一些包装器可以支持环境和矢量环境,但是,这并不标准化,也不清楚哪些包装器支持哪些不支持矢量环境。对于 v1.0.0,随着 Env
和 VectorEnv
分开不再相互继承(在矢量部分中详细了解),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 环境都使用已终止/已截断的步骤 API,因此用户不应该需要StepAPICompatibility
包装器。 Shimmy 包含一个兼容环境,用于将 gym-api 环境转换为 gymnasium。
- 已重命名的包装器(我们希望包装器的命名保持一致。因此,我们已从所有包装器中删除了“Wrapper”,并在适当的位置包含了“Observation”、“Action”和“Reward”)
AutoResetWrapper
->Autoreset
FrameStack
->FrameStackObservation
PixelObservationWrapper
->AddRenderObservation
- 已移动的包装器(所有矢量包装器都在
gymnasium.wrappers.vector
中)VectorListInfo
->vector.DictInfoToList
- 已添加的包装器
DelayObservation
- 将延迟添加到下一个观测和奖励DtypeObservation
- 修改环境的观测空间的 dtypeMaxAndSkipObservation
- 会跳过n
个观察结果,并在最后 2 个观察结果上取最大值,灵感来自 Atari 环境中针对其他环境的启发式方法StickyAction
- 以一定的概率随机重复动作,并返回最后一步的观察结果和多步奖励总和。灵感来自 Atari 环境的启发式方法JaxToNumpy
- 将基于 Jax 的环境转换为使用基于 Numpy 的输入和输出数据,用于reset
、step
等JaxToTorch
- 将基于 Jax 的环境转换为使用基于 PyTorch 的输入和输出数据,用于reset
、step
等NumpyToTorch
- 将基于 Numpy 的环境转换为使用基于 PyTorch 的输入和输出数据,用于reset
、step
等
对于所有包装器,我们添加了示例代码文档和变更日志,以帮助未来的研究人员理解所做的任何更改。请参阅以下 页面 了解示例。
函数式环境
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) → StateType
…
def transition(state: StateType, action: ActType, rng: Any, params: Params | None = None) → StateType
…
def observation(state: StateType, params: Params | None = None) → ObsType
…
def reward(
state: StateType, action: ActType, next_state: StateType, params: Params | None = None
) → RewardType
…
def terminal(state: StateType, params: Params | None = None) → TerminalType
…
FuncEnv
要求 initial
和 transition
函数返回一个给定其输入的新状态,作为 Env.step
和 Env.reset
的部分实现。因此,用户可以对一系列输入(以及保存)下一个状态进行采样,以便与规划、搜索等一起使用。给定一个状态,observation
、reward
和 terminal
为用户提供了明确的定义,以便理解每个定义如何影响环境的输出。
其他错误修复
- 由于 cython==3 的问题,由 @pseudo-rnd-thoughts (#616) 限制了
gymnasium[mujoco-py]
的 cython 版本。 - 由 @Kallinteris-Andreas (#612) 修复了
MuJoCo
环境类型问题。 - 通过 @logan-dunbar 修复了使用自定义宽度值的 mujoco 渲染问题 (#634)
- 通过 @chrisyeh96 修复了环境检查器,以正确报告无限边界 (#708)
- 通过 @younik 修复了
register(kwargs)
的类型提示,从**kwargs
更改为kwargs: dict | None = None
(#788) - 由 @TimSchneider42 (#886) 修复了
CartPoleVectorEnv
步数计数器在reset
时重置为零的问题。 - 由 @RedTachyon (#810) 修复了自定义环境的异步向量环境注册问题。
其他新功能
- 新增 MuJoCo v5 环境(更改和性能图将在单独的博客文章中发布)由 @Kallinteris-Andreas (#572) 完成。
- 由 @logan-dunbar (#635) 为 MuJoCo 人类渲染添加了支持,以便更改查看窗口的大小。
- 通过 @guyazran (#731) 在 MuJoCo 渲染中添加更多对屏幕外尺寸和场景几何体的控制。
- 通过 @RogerJL (#789) 和 @pseudo-rnd-thoughts (#811) 为
JaxToNumpy
、JaxToTorch
和NumpyToTorch
添加对处理NamedTuples
的支持。 - 通过 @jamartinh (#830) 为
FrameSkipObservation
添加padding_type
参数以选择填充观察结果。 - 通过 @Kallinteris-Andreas (#748) 为
check_environments_match
添加渲染检查。
弃用
- 通过 @pseudo-rnd-thoughts (#801) 从 error.py 中删除不必要的错误类。
- 通过 @Kallinteris-Andreas (#827) 停止从
gymnasium.envs.mujoco
中导出 MuJoCo v2 环境类。 - 由 @pseudo-rnd-thoughts 从 PlayPlot 中移除弃用警告 (#800)
文档变更
- 由 @kir0ul 更新了 v1.0.0 的自定义环境教程 (#709)
- 由 @btjanaka 将 swig 添加到 Box2D 的安装说明中 (#683)
- 由 @Kallinteris-Andreas 添加了使用
Gymnasium/MuJoCo/Ant-v5
框架加载自定义四足机器人环境的教程 (#838) - 由 @pseudo-rnd-thoughts (#867) 在网站上添加了第三方教程页面,以列出在其他网站上编写和托管的教程。
- 由 @pseudo-rnd-thoughts 添加了更多入门页面 (#791)
- 由 @Kallinteris-Andreas (#762) 为每个 MuJoCo 环境添加了表示其动作空间的图形。
- 由 @pseudo-rnd-thoughts 修正了关于 blackjack 初始状态的文档 (#893)
- 由 @PierreCounathe 修正了关于 Frozenlake 和 Cliffwalking 位置的文档 (#695)
- 由 @pseudo-rnd-thoughts 更新了经典控制环境的
__init__
和reset
参数 (#898)
完整变更日志: 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
时,__getattr__
警告仍然会由于get_wrapper_attr
使用hasattr
,而hasattr
在底层使用__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 之后发布一篇相关论文,感谢过去三年所有帮助 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 完成了这项工作。
重大变更
- 由 @Kallinteris-Andreas 在 #573 中删除了对 Python 3.7 的支持,因为 Python 3.7 已经到了生命周期结束。
- 由 @Kallinteris-Andreas 在 #589 中更新了 MuJoCo Hopper 和 Walker2D 模型,使其能够与 MuJoCo >= 2.3.3 协同工作。
- 在 #535 中为将在 v1.0 中删除的几个功能添加了弃用警告:
Wrapper.__get_attr__
、gymnasium.make(..., autoreset=True)
、gymnasium.make(..., apply_api_compatibility=True)
、Env.reward_range
和gymnasium.vector.make
。有关其建议的替换,请参见。 - 由 @jjshoots 在 #495 中针对
Box
边界为low > high
、low == inf
和high == -inf
的情况引发错误。 - 由 @pseudo-rnd-thoughts 在 #515 中为
data_equivalence()
中的 NumPy 数组添加了数据类型测试。 - 由 @pseudo-rnd-thoughts 在 #548 中从 gymnasium 包装器中删除了 Jumpy,因为它只是部分实现了,测试和使用有限。
- 由 @charraut 在 #373 中更新了项目要求为
jax>=0.4
。
新功能
- 由 @pseudo-rnd-thoughts 在 #558 中删除了对 pygame 版本的限制,
pygame>=2.1.3
。 - 由 @Rayerdyne 在 #557 中为
MultiDiscrete
空间添加了start
参数,类似于Discrete(..., start)
参数。 - 由 @pseudo-rnd-thoughts 在 #564 中为
check_env
添加了测试,以确保关闭已关闭的环境不会引发错误。 - 由 @robertoschiavone 在 #580 中,如果环境的渲染模式无效
(None, "human", "ansi")
,则在初始化时wrapper.RecordVideo
会引发错误。 - 由 @LucasAlegre 在 #561 中添加了
MaxAndSkipObservation
包装器。 - 由 @Kallinteris-Andreas 在 #576 中添加了
check_environments_match
函数,用于检查两个环境是否相同。 - 由 @Kallinteris-Andreas 在 #583 中添加了性能调试实用程序,
utils/performance.py
。 - 由 @balisujohn 在 #407 中添加了基于 Jax 的悬崖行走环境。
- MuJoCo
- 由 @Kallinteris-Andreas 在 #536 中添加了对使用
xml_file
参数的相对路径的支持。 - 由 @Kallinteris-Andreas 在 #540 中添加了对环境在
reset
中指定info
的支持。 - 由 @Kallinteris-Andreas 在 #525 中移除了环境定义
metadata["render_fps"]
的要求,该值在__init__
中使用dt
确定。
- 由 @Kallinteris-Andreas 在 #536 中添加了对使用
- 实验性
- 由 @charraut 在 #341 中添加了
gymnasium.experimental.wrappers
中的弃用包装器错误。 - 由 @younik 在 #503 中为
RecordVideoV0
添加了fps
参数,用于自定义 fps 值,该值会覆盖环境的内部render_fps
值。 - 由 @pseudo-rnd-thoughts 在 #444 中添加了用于 lambda 观察、动作和奖励包装器的实验性向量包装器。
- 由 @charraut 在 #341 中添加了
错误修复
- 由 @pseudo-rnd-thoughts 在 #608 中修复了
spaces.Dict.keys()
,因为key in keys
为 False。 - 由 @mmcaulif 在 #569 中基于边界更新了
wrappers.RescaleAction
的动作空间。 - 由 @pseudo-rnd-thoughts 在 #435 中移除了被动环境检查器中关于无限 Box 边界的警告。
- 由 @alexdlukens 在 #512 中撤销了 Lunar Lander 观察空间的更改。
- 由 @robertoschiavone 在 #554 中修复了
check_env
中的 URL 链接。 - 由 @elliottower 在 #433 中将
shimmy[gym]
更新为shimmy[gym-v21]
或shimmy[gym-v26]
。 - 由 @pseudo-rnd-thoughts 在 #516 中修复了实验性向量环境和包装器中的几个问题。
- 视频录制包装器
- 由 @voidflight 在 #518 中修复了
VideoRecorder
在reset
上清空recorded_frames
而不是frames
的问题。 - 由 @qgallouedec 在 #533 中移除了
VideoRecorder.close
中的Env.close
。 - 由 @pseudo-rnd-thoughts 在 #553 中修复了
VideoRecorder
和RecordVideoV0
,将import moviepy
移动到__del__
不再引发AttributeErrors
的位置。
- 由 @voidflight 在 #518 中修复了
- Mujoco
- 由 @Kallinteris-Andreas 在 #588 中移除了 Hopper-v4 的旧渲染 API 函数。
- 由 @sonelu 在 (#440) 中修复了关闭渲染时出现的 TypeError。
- 由 @xuanhien070594 在 #424 中修复了
MujocoEnv
的_step_mujoco_simulation
函数中nstep
错误的问题。 - 由 @reginald-mclean 在 #604 中允许动作空间中的执行器控制数量与动作空间不同。
文档更新
- 由 @pseudo-rnd-thoughts 在 #497 中允许用户在网站上查看引用对象的源代码。
- 更新网站主页,由 @elliottower 在 #482 中完成。
- 由 @pseudo-rnd-thoughts 在 #418 中使 Atari 文档保持一致,并在 @dylwil3 的 #510 中添加了缺失的描述。
- 添加第三方环境:safety gymnasium, pyflyt, Gym-Trading-Env, stable-retro, DACBench, gym-cellular-automata,由 @elliottower、@stefanbschneider、@ClementPerroud、@jjshoots、@MatPoliquin 和 @robertoschiavone 在 #450、#451、#474、#487、#529、#538、#581 中完成。
- 由 @Kallinteris-Andreas 在 #524、#522 中更新了所有环境和基本 MuJoCo 环境的 MuJoCo 文档。
- 由 @robertoschiavone 在 #429 中更新了 CartPole 奖励文档,以澄清 v0 和 v1 的不同最大奖励。
- 由 @yaniv-peretz 在 #459 中澄清了
FrozenLake4x4
和FrozenLake8x8
环境的 Frozen lake 时间限制。 - 由 @kvrban 在 #491 中修复了 single_observation_space 文档中的错别字。
- 由 @helpingstar 在 #520 中修复了网站上警告的渲染。
完整变更日志: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.spec
和 env.unwrapped.spec
返回不同的规范)之外,这是一个重大变更。有关更多信息,请参阅可重复性详细信息部分。
在 v0.27 中,我们添加了 experimental
文件夹,以便我们可以开发一些新功能(包装器和硬件加速环境)。我们引入了一个新的实验性 VectorEnv
类。此类不继承自标准的 Env
类,并将允许更有效地实现并行化功能。我们计划在接下来的几个月内通过多个次要版本来改进实现并添加基于向量的包装器。
此外,我们优化了模块加载,以便只有在用户导入需要 PyTorch 或 Jax 的包装器时才会加载它们,而不会在 import gymnasium
时加载。
可重复性详细信息
在之前的版本中,Gymnasium 支持 gym.make(spec)
,其中 spec
来自 gym.spec(str)
或 env.spec
的 EnvSpec
,并且与基于字符串的 gym.make(“”)
相同。在这两种情况下,都没有办法指定应应用于环境的额外包装器。在此版本中,我们向 EnvSpec
添加了 additional_wrappers
,用于指定应用于基本环境的包装器(TimeLimit
、PassiveEnvChecker
、Autoreset
和 ApiCompatibility
不包括在内,因为它们是在其他字段中指定的)。
此额外字段将允许用户准确地保存或重现用于训练策略或生成离线 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
更有效的元素表示,而tuple
是之前支持的。 #284- 以前,
Box.sample
会对上界空间进行错误的裁剪,使得当 dtype 为离散或布尔值时,0 永远无法被采样。现在已修复,使得在这些情况下可以采样 0。 #249 - 如果安装了
jax
或pytorch
,那么在import gymnasium
时,这两个模块也会被加载,导致加载时间显著变慢。现在已修复,使得jax
和torch
仅在用户加载特定包装器时才会加载。 #323 - 在 v0.26 中,我们为
Wrapper
添加了参数,以允许为包装器及其子环境指定不同的观察和动作类型。然而,这会导致 pyright 和 mypy 的类型问题,现在通过 Wrapper 具有四个泛型参数[ObsType, ActType, WrappedEnvObsType, WrappedEnvActType]
来解决此问题。 #337 - 在 v0.25 和 0.v26 中,引入了几个新的空间类型,
Text
、Graph
和Sequence
,但矢量实用程序函数没有更新以支持这些空间。已在实验性矢量空间实用程序函数中添加了对这些空间的支持:batch_space
、concatenate
、iterate
和create_empty_array
。 #223 - 由于缺乏测试,实验性有状态观察包装器(
FrameStackObservation
、DelayObservation
和TimeAwareObservation
)无法按预期工作。这些包装器现在已修复,并添加了测试。 #224
次要更改
- 通过 @raphajaner 在 #268 中,允许在评估期间禁用和启用 NormalizeX 包装器的统计信息,以便在评估期间使用。
- 通过 @DrRyanHuang 在 #278 中修复 lunar_lander.py 中的 AttributeError。
- 通过 @valentin-cnt 在 #281 中添加对文档字符串(doctest)的测试,以确保文档字符串与实现相匹配。
- 类型提示修复并添加了
__all__
dunder,由 @howardh 在 #321 中完成。 - 通过 @valentin-cnt 在 #327 中修复 gymnasium/spaces 中的类型提示错误。
- 通过 @pseudo-rnd-thoughts 在 #339 中更新实验性矢量共享内存实用程序函数。
- 通过 @jjshoots 在 #332 中将 Gymnasium 通知更改为 Farama 通知。
- 通过 @balisujohn 在 #338 中添加了基于 Jax 的 Blackjack 环境。
文档变更
- 通过 @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
发布说明
修复的错误
- 通过 @pseudo-rnd-thoughts 在 #221 中将
np.bool8
替换为np.bool_
,以避免 numpy 1.24 的弃用警告。 - 通过 @pseudo-rnd-thoughts 在 #272 中移除 shimmy 作为核心依赖项。
- 通过 @ianyfan 在 #230 和 @RedTachyon 在 #254 中修复了 ResizeObservation 中针对二维观测的静默错误。
- 通过 @jjshoots 在 #215 中将环境检查器中的断言更改为警告。
- 通过 @pseudo-rnd-thoughts 在 #216 中恢复了在使用渲染模式时没有元数据渲染模式的情况下
make
错误。 - 通过 @XuehaiPan 在 #250 中更新了额外依赖项的提示信息。
- 通过 @younik 在 #252 中修复了
AsyncVectorEnv.reset
的返回值类型。 - 通过 @pseudo-rnd-thoughts 在 #255 中更新了跳跃错误,以明确说明 pip 安装的是 jax-jumpy。
- 通过 @ianyfan 在 #259 中修复了
callable
到Callable
的类型注解。 - 通过 @rafaelcp 在 #277 中修复了实验性的 normalize reward 包装器。
新功能/改进
- 通过 @PaulMest 在 #235 中将 LunarLander-v2 的
step
性能提高了 1.5 倍以上。 - 通过 @nidhishs 在 #238 中为 StepAPICompatibility 包装器添加了向量环境支持。
- 通过 @jjshoots 在 #241 中允许 sequence 在特征空间为 Box 时接受堆叠的 np 数组。
- 通过 @pseudo-rnd-thoughts 在 #225 中改进了从插件抛出错误时的警告信息。
- 通过 @mgoulao 在 #257 中将变更日志(发行说明)添加到网站。
- 通过 @younik 在 #246 中实现了 RecordVideoV0。
- 通过 @PierreMardon 在 #267 中添加了在 unflatten discrete 和 multidiscrete 失败时的显式错误消息。
文档更新
- 通过 @valentin-cnt 在 #274 中将 doctest 添加到 CI 并修复了文档字符串中所有现有的错误。
- 通过 @till2 在 #234 中添加了使用 A2C 的向量化环境的教程。
- 通过 @Kallinteris-Andreas 在 #206 中修复了
MuJoCo.Humanoid
的动作描述。 Ant
use_contact_forces
的观测和奖励 DOC 由 @Kallinteris-Andreas 在 #218 中提供。MuJoCo.Reacher-v4
的文档修复由 @Kallinteris-Andreas 在 #219 中提供。- 通过 @RedTachyon 在 #105 中在迁移指南中提到了截断。
- docs(tutorials): 通过 @lpizzinidev 在 #244 中修复了环境创建链接。
Mujoco/Hooper
文档中轻微的拼写错误修复由 @Kallinteris-Andreas 在 #247 中提供。- 添加关于 @metric-space 在 #264 中 A2C 教程中卷积操作的说明。
- 修复 @younik 在 #270 中 README.md 的环境版本问题。
- 添加 @mgoulao 在 #258 中的教程画廊。
感谢新的 Gymnasium 贡献者,如果您想参与其中,请加入我们的 Discord 服务器。链接在自述文件中。
- @PaulMest 在 #235 中做出了他们的第一次贡献。
- @nidhishs 在 #238 中做出了他们的第一次贡献。
- @lpizzinidev 在 #244 中做出了他们的第一次贡献。
- @ianyfan 在 #230 中做出了他们的第一次贡献。
- @metric-space 在 #264 中做出了他们的第一次贡献。
- @PierreMardon 在 #267 中做出了他们的第一次贡献。
- @valentin-cnt 在 #274 中做出了他们的第一次贡献。
- @rafaelcp 在 #277 中做出了他们的第一次贡献。
完整变更日志: 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,并且几乎不需要任何努力。
与往常一样,我们的开发路线图公开提供 here,以便您可以跟踪我们的未来计划。目前计划的唯一重大变化是将选定的环境切换到使用硬件加速物理引擎,以及我们长期计划彻底改造矢量 API 和内置包装器。
这个版本特别包括一个全新的库部分:gymnasium.experimental
。我们添加了一些新的功能、包装器和功能环境 API,供用户测试和试用,以发现错误并提供反馈。
新的包装器
这些新的包装器,在 gymnasium.experimental.wrappers
中可以访问,请在 https://gymnasium.org.cn/main/api/experimental/ 中查看完整列表,旨在取代 gymnasium v0.30.0 中的包装器,并包含一些改进
- (正在进行中) 支持任意复杂的观测/动作空间。随着强化学习的进步,动作和观测空间变得越来越复杂,而当前的包装器并没有考虑到这一点。
- 支持基于 Jax 的环境。对于在 Jax 中编写的硬件加速环境,例如 Brax,以及类似的基于 PyTorch 的程序,NumPy 不再是编写环境的唯一选择。因此,这些升级将使用 Jumpy,这是一个由 Farama Foundation 开发的项目,旨在为 NumPy、Jax 和未来 PyTorch 数据提供自动兼容性,适用于大多数 NumPy 函数。
- 更多包装器。像 Supersuit 这样的项目旨在为强化学习带来更多包装器,但是,许多用户没有意识到这些包装器,因此我们计划将这些包装器移入 Gymnasium。如果我们在上面提供的列表中遗漏了常见的包装器,请创建问题,我们很乐意添加它。
- 版本控制。与环境一样,包装器的实现细节可能会导致代理性能的变化。因此,我们建议为所有包装器添加版本号,例如
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
其他重大更改
- 重构 Mujoco 渲染机制,使用单独的线程用于 OpenGL。删除
Viewer
,转而使用MujocoRenderer
,该渲染器可以被 @rodrigodelazcano 在 #112 中使用的离屏、人工和其他渲染模式使用。 - 添加弃用警告,用于
gym.make(..., apply_env_compatibility=True)
,转而使用gym.make("GymV22Environment", env_id="...")
,由 @pseudo-rnd-thoughts 在 #125 中完成。 - 添加
gymnasium.pprint_registry()
,用于漂亮地打印 gymnasium 注册表,由 @kad99kev 在 #124 中完成。 - 将
Discrete.dtype
更改为np.int64
,以便样本为np.int64
,而不是 python 整数。由 @pseudo-rnd-thoughts 在 #141 中完成。 - 由 @pseudo-rnd-thoughts 在 #72 中添加了 OpenAI Gym v21 到 v26 的迁移指南。
- 由 @pseudo-rnd-thoughts 在 #39 中添加了
core.py
中Env
、Wrapper
等等的完整类型提示。 - 由 @pseudo-rnd-thoughts 在 #37 中添加了
gymnasium.spaces
中所有空间的完整类型提示。 - 由 @Markus28 在 #190 中使
play()
中的窗口可调整大小。 - 由 @siddarth-c 在 #155 中添加了 REINFORCE 实现教程。
错误修复和文档变更
- 由 @younik 在 #42 中移除了
VideoRecorder
包装器中的自动关闭。 - 由 @theo-brown 在 #74 中将
seeding.np_random
错误消息更改为报告种子类型。 - 由 @ikamensh 在 #83 中在 MujocoEnv 错误消息中包含了形状。
- 由 @tobirohrer 在 #89 中添加了漂亮的 Feature/GitHub 问题表单。
- 由 @Markus28 在 #117 中添加了
check_env
和PassiveEnvChecker
中渲染返回数据的测试。 - 由 @Thytu 在 #123 中修正了经典控制环境的动作空间描述的文档字符串并进行了更新。
- 由 @pseudo-rnd-thoughts 在 #130 中修正了根
__init__.py
中的__all__
,以指定正确的文件夹。 - 由 @Markus28 在 #132 中修正了
play()
的断言错误。 - 由 @MarionJS 在 #136 中更新了 Frozen Lake
is_slippy
的文档。 - 由 @younik 在 #143 中修正了
render_mode
为 None 时的警告。 - 由 @Markus28 在 #172 中在文档中添加了
is_np_flattenable
属性。 - 由 @Markus28 在 #173 中更新了 Wrapper 的文档。
- 由 @Markus28 在 #174 中更新了空间文档的格式。
- 由 @kir0ul 在 #139 中为 FrozenLake 添加了随机地图生成中的播种。
- 由 @rusu24edward 在 #164 中添加了关于从扁平化空间中解扁平化样本时的问题的说明。
- 由 @axb2035 在 #171 中将 pusher 环境页面添加到了网站上。
- 由 @aaronwalsman 在 #178 中在
AsyncVectorEnv
中添加了在step_wait
中分割结果之前检查成功的操作。 - 由 @Kallinteris-Andreas 在 #183 中添加了
MuJoCo.Ant-v4.use_contact_forces
的文档。 - 由 @cool-RR 在 #184 中修正了 README.md 中的错别字。
- 由 @Kallinteris-Andreas 在 #186 中添加了
MuJoCo.Ant
v4 变更日志的文档。 - 由 @Kallinteris-Andreas 在 #208 中修正了
MuJoCo.Ant
的文档中的动作顺序。 - 由 @cool-RR 在 #205 中为整个代码库添加了
raise-from
异常。
幕后变更
- 文档版本由 @mgoulao 在 #73 中更新。
- 添加 Atari 环境到测试,删除无用代码,由 @Markus28 在 #78 中更新。
- 修复版本控制工作流中缺少的构建步骤,由 @mgoulao 在 #81 中更新。
- 对环境页面进行少量改进,由 @mgoulao 在 #110 中更新。
- 更新第三方环境文档,由 @pseudo-rnd-thoughts 在 #138 中更新。
- 更新 docstrings 以改进文档,由 @axb2035 在 #160 中更新。
- 在 CI 中测试核心依赖项,由 @pseudo-rnd-thoughts 在 #146 中更新。
- 更新并重新运行
pre-commit
钩子以提高代码质量,由 @XuehaiPan 在 #179 中更新。
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 中更新。
- 修改
HumanRendering
和RenderCollection
包装器中的元数据以拥有正确的元数据,由 @RedTachyon 在 #35 中更新。 - 简化
EpisodeStatisticsRecorder
包装器,由 @DavidSlayback 在 #31 中更新。 - 修复 MultiDiscrete.flatten() 中的整数溢出问题,由 @olipinski 在 #55 中更新。
- 重新添加为 Mujoco 环境指定 XML 文件的功能,由 @Kallinteris-Andreas 在 #70 中更新。
文档更改
- 添加在 Blackjack 中训练代理的教程,由 @till2 在 #64 中更新。
- 由 @mgoulao、@vairodp、@WillDudley、@pseudo-rnd-thoughts 和 @jjshoots 进行的非常多的文档更新。
完整变更日志: v0.26.2...v0.26.3
感谢新贡献者
- @vairodp 在 #41 中做出了他们的首次贡献。
- @DavidSlayback 在 #31 中做出了他们的首次贡献。
- @WillDudley 在 #51 中做出了他们的首次贡献。
- @olipinski 在 #55 中做出了他们的首次贡献。
- @jjshoots 在 #58 中做出了他们的首次贡献。
- @vmoens 在 #60 中做出了他们的首次贡献。
- @till2 在 #64 中做出了他们的首次贡献。
- @Kallinteris-Andreas 在 #70 中做出了他们的首次贡献。
v0.26.2 ¶
发布日期:2022-10-05 - GitHub - PyPI
此版本是 Gym v26.2 的上游版本。
错误修复
- 由于 reset 现在返回 (obs, info),因此在矢量环境中,这会导致最后一步的 info 被覆盖。现在,最后的观测值和 info 包含在 info 中,作为 "final_observation" 和 "final_info",由 @pseudo-rnd-thoughts 更新。
- 在尝试渲染而不指定 render_mode 时添加警告,由 @younik 更新。
- 更新 Atari 预处理,以便包装器可以被腌制,由 @vermouth1992 更新。
- Github CI 进行了强化,使其仅具有读取权限 @sashashura
- 澄清并修复 GraphInstance 中的错别字 @ekalosak
v0.26.1¶
发布于 2022-09-16 - GitHub - PyPI
此版本是 Gym v26.1 的上游版本
此外,gym 文档 代码库已合并到新的网站 https://gymnasium.org.cn/
v0.26.0: 初始版本¶
发布于 2022-09-13 - GitHub - PyPI
这是 Gymnasium 的第一个版本,它是 OpenAI Gym 的维护分支
此版本与 Gym v0.26.0 相同,除了项目名称 (Gymnasium) 和行为准则
阅读 #12 以了解变更路线图