观察包装器

class gymnasium.ObservationWrapper(env: Env[ObsType, ActType])[source]

使用 observation() 函数修改来自 Env.reset()Env.step() 的观察结果。

如果你想在将观察结果传递给学习代码之前只对其应用一个函数,你只需继承自 ObservationWrapper 并覆盖方法 observation() 来实现该转换。在该方法中定义的转换必须由 env 观察空间反映。否则,你需要通过在包装器的 __init__() 方法中设置 self.observation_space 来指定包装器的新观察空间。

参数:

env – 要包装的环境。

observation(observation: ObsType) WrapperObsType[source]

返回修改后的观察结果。

参数:

observationenv 观察结果

返回值:

修改后的观察结果

已实现包装器

class gymnasium.wrappers.TransformObservation(env: gym.Env[ObsType, ActType], func: Callable[[ObsType], Any], observation_space: gym.Space[WrapperObsType] | None)[source]

对从环境的 Env.reset()Env.step() 接收到的 observation 应用函数,该函数会传回给用户。

函数 func 将应用于所有观察结果。如果来自 func 的观察结果超出了 env 的观察空间的范围,请提供更新的 observation_space

包装器的向量版本存在于 gymnasium.wrappers.vector.TransformObservation 中。

示例

>>> import gymnasium as gym
>>> from gymnasium.wrappers import TransformObservation
>>> import numpy as np
>>> np.random.seed(0)
>>> env = gym.make("CartPole-v1")
>>> env.reset(seed=42)
(array([ 0.0273956 , -0.00611216,  0.03585979,  0.0197368 ], dtype=float32), {})
>>> env = gym.make("CartPole-v1")
>>> env = TransformObservation(env, lambda obs: obs + 0.1 * np.random.random(obs.shape), env.observation_space)
>>> env.reset(seed=42)
(array([0.08227695, 0.06540678, 0.09613613, 0.07422512]), {})
更改日志
  • v0.15.4 - 最初添加

  • v1.0.0 - 添加 observation_space 的要求

参数:
  • env – 要包装的环境

  • func – 将转换观察结果的函数。如果此转换后的观察结果超出了 env.observation_space 的观察空间,则提供一个 observation_space

  • observation_space – 包装器的观察空间,如果为 None,则假定与 env.observation_space 相同。

class gymnasium.wrappers.DelayObservation(env: Env[ObsType, ActType], delay: int)[source]

在从环境返回的观察结果中添加延迟。

在达到 delay 次步数之前,返回的观察结果是一个与观察空间形状相同的全零数组。

不存在包装器的向量版本。

注意

这不支持随机延迟值,如果用户有兴趣,请提出问题或拉取请求以添加此功能。

示例

>>> import gymnasium as gym
>>> env = gym.make("CartPole-v1")
>>> env.reset(seed=123)
(array([ 0.01823519, -0.0446179 , -0.02796401, -0.03156282], dtype=float32), {})
>>> env = DelayObservation(env, delay=2)
>>> env.reset(seed=123)
(array([0., 0., 0., 0.], dtype=float32), {})
>>> env.step(env.action_space.sample())
(array([0., 0., 0., 0.], dtype=float32), 1.0, False, False, {})
>>> env.step(env.action_space.sample())
(array([ 0.01823519, -0.0446179 , -0.02796401, -0.03156282], dtype=float32), 1.0, False, False, {})
更改日志
  • v1.0.0 - 最初添加

参数:
  • env – 要包装的环境

  • delay – 延迟观察结果的步数

class gymnasium.wrappers.DtypeObservation(env: Env[ObsType, ActType], dtype: Any)[source]

将观察结果数组的 dtype 修改为指定的 dtype。

注意

这仅与 BoxDiscreteMultiDiscreteMultiBinary 观察空间兼容

包装器的向量版本存在于 gymnasium.wrappers.vector.DtypeObservation 中。

更改日志
  • v1.0.0 - 最初添加

参数:
  • env – 要包装的环境

  • dtype – 观测值的新的数据类型

class gymnasium.wrappers.FilterObservation(env: gym.Env[ObsType, ActType], filter_keys: Sequence[str | int])[source]

通过一组键或索引过滤字典或元组观测空间。

此包装器的向量版本存在于 gymnasium.wrappers.vector.FilterObservation 中。

示例

>>> import gymnasium as gym
>>> from gymnasium.wrappers import FilterObservation
>>> env = gym.make("CartPole-v1")
>>> env = gym.wrappers.TimeAwareObservation(env, flatten=False)
>>> env.observation_space
Dict('obs': Box([-4.8               -inf -0.41887903        -inf], [4.8               inf 0.41887903        inf], (4,), float32), 'time': Box(0, 500, (1,), int32))
>>> env.reset(seed=42)
({'obs': array([ 0.0273956 , -0.00611216,  0.03585979,  0.0197368 ], dtype=float32), 'time': array([0], dtype=int32)}, {})
>>> env = FilterObservation(env, filter_keys=['time'])
>>> env.reset(seed=42)
({'time': array([0], dtype=int32)}, {})
>>> env.step(0)
({'time': array([1], dtype=int32)}, 1.0, False, False, {})
更改日志
  • v0.12.3 - 最初添加,最初称为 FilterObservationWrapper

  • v1.0.0 - 重命名为 FilterObservation 并添加对使用整数 filter_keys 的元组观测空间的支持

参数:
  • env – 要包装的环境

  • filter_keys – 要包含的子空间集,对于 Dict 空间使用字符串列表,对于 Tuple 空间使用整数列表

class gymnasium.wrappers.FlattenObservation(env: Env[ObsType, ActType])[source]

将环境的观测空间以及来自 resetstep 函数的每个观测值展平。

此包装器的向量版本存在于 gymnasium.wrappers.vector.FlattenObservation 中。

示例

>>> import gymnasium as gym
>>> from gymnasium.wrappers import FlattenObservation
>>> env = gym.make("CarRacing-v3")
>>> env.observation_space.shape
(96, 96, 3)
>>> env = FlattenObservation(env)
>>> env.observation_space.shape
(27648,)
>>> obs, _ = env.reset()
>>> obs.shape
(27648,)
更改日志
  • v0.15.0 - 最初添加

参数:

env – 要包装的环境

class gymnasium.wrappers.FrameStackObservation(env: gym.Env[ObsType, ActType], stack_size: int, *, padding_type: str | ObsType = 'reset')[source]

以滚动方式将来自过去 N 个时间步的观测值堆叠起来。

例如,如果堆叠数为 4,则返回的观测值包含最近的 4 个观测值。对于环境 “Pendulum-v1”,原始观测值是一个形状为 [3] 的数组,因此如果我们堆叠 4 个观测值,则处理后的观测值形状为 [4, 3]。

用户可以选择使用的填充观测值

  • “reset”(默认) - 重置值将重复

  • “zero” - 观测空间的 “零” 类实例

  • custom - 观测空间的实例

不存在包装器的向量版本。

示例

>>> import gymnasium as gym
>>> from gymnasium.wrappers import FrameStackObservation
>>> env = gym.make("CarRacing-v3")
>>> env = FrameStackObservation(env, stack_size=4)
>>> env.observation_space
Box(0, 255, (4, 96, 96, 3), uint8)
>>> obs, _ = env.reset()
>>> obs.shape
(4, 96, 96, 3)
具有不同填充观测值的示例
>>> env = gym.make("CartPole-v1")
>>> env.reset(seed=123)
(array([ 0.01823519, -0.0446179 , -0.02796401, -0.03156282], dtype=float32), {})
>>> stacked_env = FrameStackObservation(env, 3)   # the default is padding_type="reset"
>>> stacked_env.reset(seed=123)
(array([[ 0.01823519, -0.0446179 , -0.02796401, -0.03156282],
       [ 0.01823519, -0.0446179 , -0.02796401, -0.03156282],
       [ 0.01823519, -0.0446179 , -0.02796401, -0.03156282]],
      dtype=float32), {})
>>> stacked_env = FrameStackObservation(env, 3, padding_type="zero")
>>> stacked_env.reset(seed=123)
(array([[ 0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.01823519, -0.0446179 , -0.02796401, -0.03156282]],
      dtype=float32), {})
>>> stacked_env = FrameStackObservation(env, 3, padding_type=np.array([1, -1, 0, 2], dtype=np.float32))
>>> stacked_env.reset(seed=123)
(array([[ 1.        , -1.        ,  0.        ,  2.        ],
       [ 1.        , -1.        ,  0.        ,  2.        ],
       [ 0.01823519, -0.0446179 , -0.02796401, -0.03156282]],
      dtype=float32), {})
更改日志
  • v0.15.0 - 最初添加为 FrameStack,并支持 lz4

  • v1.0.0 - 重命名为 FrameStackObservation,并删除 lz4 和 LazyFrame 支持

    并添加了 padding_type 参数

参数:
  • env – 要应用包装器的环境

  • stack_size – 要堆叠的帧数。

  • padding_type – 堆叠观测值时使用的填充类型,选项: “reset”、 “zero”、自定义观测值

class gymnasium.wrappers.GrayscaleObservation(env: Env[ObsType, ActType], keep_dim: bool = False)[source]

resetstep 计算出的图像观测值从 RGB 转换为灰度。

keep_dim 将保留通道维度。

此包装器的向量版本存在于 gymnasium.wrappers.vector.GrayscaleObservation 中。

示例

>>> import gymnasium as gym
>>> from gymnasium.wrappers import GrayscaleObservation
>>> env = gym.make("CarRacing-v3")
>>> env.observation_space.shape
(96, 96, 3)
>>> grayscale_env = GrayscaleObservation(env)
>>> grayscale_env.observation_space.shape
(96, 96)
>>> grayscale_env = GrayscaleObservation(env, keep_dim=True)
>>> grayscale_env.observation_space.shape
(96, 96, 1)
更改日志
  • v0.15.0 - 最初添加,最初称为 GrayScaleObservation

  • v1.0.0 - 重命名为 GrayscaleObservation

参数:
  • env – 要包装的环境

  • keep_dim – 是否保留观测值中的通道,如果为 True,则 obs.shape == 3,否则 obs.shape == 2

class gymnasium.wrappers.MaxAndSkipObservation(env: Env[ObsType, ActType], skip: int = 4)[source]

跳过第 N 帧(观测值)并返回最后两个观测值之间的最大值。

不存在包装器的向量版本。

示例

>>> import gymnasium as gym
>>> env = gym.make("CartPole-v1")
>>> obs0, *_ = env.reset(seed=123)
>>> obs1, *_ = env.step(1)
>>> obs2, *_ = env.step(1)
>>> obs3, *_ = env.step(1)
>>> obs4, *_ = env.step(1)
>>> skip_and_max_obs = np.max(np.stack([obs3, obs4], axis=0), axis=0)
>>> env = gym.make("CartPole-v1")
>>> wrapped_env = MaxAndSkipObservation(env)
>>> wrapped_obs0, *_ = wrapped_env.reset(seed=123)
>>> wrapped_obs1, *_ = wrapped_env.step(1)
>>> np.all(obs0 == wrapped_obs0)
np.True_
>>> np.all(wrapped_obs1 == skip_and_max_obs)
np.True_
更改日志
  • v1.0.0 - 最初添加

参数:
  • env (Env) – 要应用包装器的环境

  • skip – 要跳过的帧数

class gymnasium.wrappers.NormalizeObservation(env: Env[ObsType, ActType], epsilon: float = 1e-8)[source]

将观测值标准化为以均值为中心,方差为 1。

属性 update_running_mean 允许冻结/继续观测统计信息的运行均值计算。如果为 True(默认),则每次调用 stepreset 时都会更新 RunningMeanStd。如果为 False,则使用计算出的统计信息,但不再更新;这可以在评估期间使用。

此包装器的向量版本存在于 gymnasium.wrappers.vector.NormalizeObservation 中。

注意

归一化取决于过去的轨迹,如果包装器刚刚实例化或策略最近发生了更改,则观测值将无法正确归一化。

示例

>>> import numpy as np
>>> import gymnasium as gym
>>> env = gym.make("CartPole-v1")
>>> obs, info = env.reset(seed=123)
>>> term, trunc = False, False
>>> while not (term or trunc):
...     obs, _, term, trunc, _ = env.step(1)
...
>>> obs
array([ 0.1511158 ,  1.7183299 , -0.25533703, -2.8914354 ], dtype=float32)
>>> env = gym.make("CartPole-v1")
>>> env = NormalizeObservation(env)
>>> obs, info = env.reset(seed=123)
>>> term, trunc = False, False
>>> while not (term or trunc):
...     obs, _, term, trunc, _ = env.step(1)
>>> obs
array([ 2.0059888,  1.5676788, -1.9944268, -1.6120394], dtype=float32)
更改日志
  • v0.21.0 - 最初添加

  • v1.0.0 - 添加 update_running_mean 属性以允许禁用运行均值/标准的更新,这在评估时特别有用。

    将所有观测值转换为 np.float32,并将观测空间的低/高设置为 -np.infnp.inf,并将数据类型设置为 np.float32

参数:
  • env (Env) – 要应用包装器的环境

  • epsilon – 用于缩放观测值的稳定性参数。

class gymnasium.wrappers.AddRenderObservation(env: Env[ObsType, ActType], render_only: bool = True, render_key: str = 'pixels', obs_key: str = 'state')[source]

将渲染后的观察结果包含在环境的观察结果中。

注意事项

以前称为 PixelObservationWrapper

不存在包装器的向量版本。

示例 - 用渲染后的图像替换观察结果
>>> env = gym.make("CartPole-v1", render_mode="rgb_array")
>>> env = AddRenderObservation(env, render_only=True)
>>> env.observation_space
Box(0, 255, (400, 600, 3), uint8)
>>> obs, _ = env.reset(seed=123)
>>> image = env.render()
>>> np.all(obs == image)
np.True_
>>> obs, *_ = env.step(env.action_space.sample())
>>> image = env.render()
>>> np.all(obs == image)
np.True_
示例 - 将渲染后的图像作为字典项添加到原始观察结果中
>>> env = gym.make("CartPole-v1", render_mode="rgb_array")
>>> env = AddRenderObservation(env, render_only=False)
>>> env.observation_space
Dict('pixels': Box(0, 255, (400, 600, 3), uint8), 'state': Box([-4.8               -inf -0.41887903        -inf], [4.8               inf 0.41887903        inf], (4,), float32))
>>> obs, info = env.reset(seed=123)
>>> obs.keys()
dict_keys(['state', 'pixels'])
>>> obs["state"]
array([ 0.01823519, -0.0446179 , -0.02796401, -0.03156282], dtype=float32)
>>> np.all(obs["pixels"] == env.render())
np.True_
>>> obs, reward, terminates, truncates, info = env.step(env.action_space.sample())
>>> image = env.render()
>>> np.all(obs["pixels"] == image)
np.True_
更改日志
  • v0.15.0 - 最初添加为 PixelObservationWrapper

  • v1.0.0 - 重命名为 AddRenderObservation

参数:
  • env – 要包装的环境。

  • render_only (bool) – 如果为 True(默认值),则将丢弃包装环境返回的原始观察结果,并且字典观察结果将仅包含像素。如果为 False,则观察结果字典将包含原始观察结果和像素观察结果。

  • render_key – 指定像素键的可选自定义字符串。默认为“pixels”。

  • obs_key – 指定 obs 键的可选自定义字符串。默认为“state”。

class gymnasium.wrappers.ResizeObservation(env: Env[ObsType, ActType], shape: tuple[int, int])[source]

使用 OpenCV 将图像观察结果调整为指定的形状。

包装器的向量版本存在于 gymnasium.wrappers.vector.ResizeObservation 中。

示例

>>> import gymnasium as gym
>>> from gymnasium.wrappers import ResizeObservation
>>> env = gym.make("CarRacing-v3")
>>> env.observation_space.shape
(96, 96, 3)
>>> resized_env = ResizeObservation(env, (32, 32))
>>> resized_env.observation_space.shape
(32, 32, 3)
更改日志
  • v0.12.6 - 最初添加

  • v1.0.0 - 需要具有两个整数元组的 shape

参数:
  • env – 要包装的环境

  • shape – 调整大小后的观察结果形状

class gymnasium.wrappers.ReshapeObservation(env: gym.Env[ObsType, ActType], shape: int | tuple[int, ...])[source]

将基于数组的观察结果重塑为指定的形状。

包装器的向量版本存在于 gymnasium.wrappers.vector.RescaleObservation 中。

示例

>>> import gymnasium as gym
>>> from gymnasium.wrappers import ReshapeObservation
>>> env = gym.make("CarRacing-v3")
>>> env.observation_space.shape
(96, 96, 3)
>>> reshape_env = ReshapeObservation(env, (24, 4, 96, 1, 3))
>>> reshape_env.observation_space.shape
(24, 4, 96, 1, 3)
更改日志
  • v1.0.0 - 最初添加

参数:
  • env – 要包装的环境

  • shape – 重塑后的观察空间

class gymnasium.wrappers.RescaleObservation(env: gym.Env[ObsType, ActType], min_obs: np.floating | np.integer | np.ndarray, max_obs: np.floating | np.integer | np.ndarray)[source]

仿射(线性)地将环境的 Box 观察空间重新缩放至 [min_obs, max_obs] 范围内。

对于原始观察空间中的无界分量,相应的目标边界也必须是无穷大,反之亦然。

包装器的向量版本存在于 gymnasium.wrappers.vector.RescaleObservation 中。

示例

>>> import gymnasium as gym
>>> from gymnasium.wrappers import RescaleObservation
>>> env = gym.make("Pendulum-v1")
>>> env.observation_space
Box([-1. -1. -8.], [1. 1. 8.], (3,), float32)
>>> env = RescaleObservation(env, np.array([-2, -1, -10], dtype=np.float32), np.array([1, 0, 1], dtype=np.float32))
>>> env.observation_space
Box([ -2.  -1. -10.], [1. 0. 1.], (3,), float32)
更改日志
  • v1.0.0 - 最初添加

参数:
  • env – 要包装的环境

  • min_obs – 新的最小观察边界

  • max_obs – 新的最大观察边界

class gymnasium.wrappers.TimeAwareObservation(env: Env[ObsType, ActType], flatten: bool = True, normalize_time: bool = False, *, dict_time_key: str = 'time')[source]

用在某一集内执行的时间步数来增强观察结果。

如果 normalize_timeTrue,则时间表示为 [0,1] 之间的归一化值,否则如果为 False,则当前时间步是整数。

对于具有 Dict 观察空间的环境,时间信息会自动添加到键 “time”(可以通过 dict_time_key 更改)中,对于具有 Tuple 观察空间的环境,时间信息会作为元组中的最后一个元素添加。否则,观察空间将转换为具有两个键的 Dict 观察空间,“obs” 用于基本环境的观察结果,“time” 用于时间信息。

要使观察结果扁平化,请使用 flatten 参数,它将使用 gymnasium.spaces.utils.flatten() 函数。

不存在包装器的向量版本。

示例

>>> import gymnasium as gym
>>> from gymnasium.wrappers import TimeAwareObservation
>>> env = gym.make("CartPole-v1")
>>> env = TimeAwareObservation(env)
>>> env.observation_space
Box([-4.80000019        -inf -0.41887903        -inf  0.        ], [4.80000019e+00            inf 4.18879032e-01            inf
 5.00000000e+02], (5,), float64)
>>> env.reset(seed=42)[0]
array([ 0.0273956 , -0.00611216,  0.03585979,  0.0197368 ,  0.        ])
>>> _ = env.action_space.seed(42)
>>> env.step(env.action_space.sample())[0]
array([ 0.02727336, -0.20172954,  0.03625453,  0.32351476,  1.        ])
归一化时间观察空间示例
>>> env = gym.make('CartPole-v1')
>>> env = TimeAwareObservation(env, normalize_time=True)
>>> env.observation_space
Box([-4.8               -inf -0.41887903        -inf  0.        ], [4.8               inf 0.41887903        inf 1.        ], (5,), float32)
>>> env.reset(seed=42)[0]
array([ 0.0273956 , -0.00611216,  0.03585979,  0.0197368 ,  0.        ],
      dtype=float32)
>>> _ = env.action_space.seed(42)
>>> env.step(env.action_space.sample())[0]
array([ 0.02727336, -0.20172954,  0.03625453,  0.32351476,  0.002     ],
      dtype=float32)
扁平化观察空间示例
>>> env = gym.make("CartPole-v1")
>>> env = TimeAwareObservation(env, flatten=False)
>>> env.observation_space
Dict('obs': Box([-4.8               -inf -0.41887903        -inf], [4.8               inf 0.41887903        inf], (4,), float32), 'time': Box(0, 500, (1,), int32))
>>> env.reset(seed=42)[0]
{'obs': array([ 0.0273956 , -0.00611216,  0.03585979,  0.0197368 ], dtype=float32), 'time': array([0], dtype=int32)}
>>> _ = env.action_space.seed(42)
>>> env.step(env.action_space.sample())[0]
{'obs': array([ 0.02727336, -0.20172954,  0.03625453,  0.32351476], dtype=float32), 'time': array([1], dtype=int32)}
更改日志
  • v0.18.0 - 最初添加

  • v1.0.0 - 移除向量环境支持,添加 flattennormalize_time 参数

参数:
  • env – 要应用包装器的环境

  • flatten – 将观察结果扁平化为一个单维 Box

  • normalize_time – 如果为 True,则以 [0,1] 范围内的值返回时间,否则以截止前剩余的时间步数返回时间

  • dict_time_key – 对于具有 Dict 观察空间的环境,时间空间的键。默认值为 “time”