观察包装器¶
- class gymnasium.ObservationWrapper(env: Env[ObsType, ActType])[source]¶
使用
observation()
函数修改来自Env.reset()
和Env.step()
的观察。如果你想在将观察传递给学习代码之前只对观察应用一个函数,你可以简单地继承
ObservationWrapper
并重写observation()
方法来实现该转换。该方法中定义的转换必须与env
观察空间相符。否则,你需要在包装器的__init__()
方法中通过设置self.observation_space
来指定包装器的新观察空间。- 参数:
env – 要被包装的环境。
已实现的包装器¶
- class gymnasium.wrappers.TransformObservation(env: Env[ObsType, ActType], func: Callable[[ObsType], Any], observation_space: 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]¶
将观察数组的数据类型修改为指定的数据类型。
注意
这仅与
Box
、Discrete
、MultiDiscrete
和MultiBinary
观察空间兼容。此包装器的向量版本存在于
gymnasium.wrappers.vector.DtypeObservation
。- 更改日志
v1.0.0 - 初次添加
- 参数:
env – 要包装的环境
dtype – 观察的新数据类型
- class gymnasium.wrappers.FilterObservation(env: Env[ObsType, ActType], filter_keys: Sequence[str | int])[source]¶
根据一组键或索引过滤 Dict 或 Tuple 观察空间。
此包装器的向量版本存在于
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]¶
展平环境的观察空间以及来自
reset
和step
函数的每个观察。此包装器的向量版本存在于
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: Env[ObsType, ActType], stack_size: int, *, padding_type: str | ObsType = 'reset')[source]¶
以滚动方式堆叠过去
N
个时间步的观察。例如,如果堆叠数为 4,则返回的观察包含最近的 4 个观察。对于环境“Pendulum-v1”,原始观察是一个形状为 [3] 的数组,如果我们堆叠 4 个观察,则处理后的观察形状为 [4, 3]。
用户可以选择用于填充的观察值。
“reset”(默认) - 重置值重复。
“zero” - 观察空间的“零”实例。
自定义 - 观察空间的一个实例。
此包装器没有向量版本。
示例
>>> 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
参数。
- v1.0.0 - 重命名为
- 参数:
env – 要应用包装器的环境
stack_size – 要堆叠的帧数。
padding_type – 堆叠观察时使用的填充类型,选项:“reset”、“zero”、自定义观察。
- class gymnasium.wrappers.GrayscaleObservation(env: Env[ObsType, ActType], keep_dim: bool = False)[source]¶
将由
reset
和step
计算的图像观察从 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 帧(观察)并返回最后两个观察之间的最大值。
此包装器没有向量版本。
注意
此包装器基于 [stable-baselines3](https://stable-baselines3.readthedocs.io/en/master/_modules/stable_baselines3/common/atari_wrappers.html#MaxAndSkipEnv) 中的包装器。
示例
>>> 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]¶
将观察归一化,使其以均值为中心,并具有单位方差。
属性
update_running_mean
允许冻结/继续观察统计量的运行均值计算。如果为True
(默认),则每次调用step
或reset
时,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.inf 和 np.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 – 可选的自定义字符串,指定观察键。默认为“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: 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: Env[ObsType, ActType], min_obs: floating | integer | ndarray, max_obs: floating | integer | 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_time
参数如果为True
,则将时间表示为 [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 - 移除向量环境支持,添加
flatten
和normalize_time
参数。
- 参数:
env – 要应用包装器的环境
flatten – 将观察展平为单个维度的 Box。
normalize_time – 如果为 True,则返回范围在 [0,1] 之间的时间;否则,返回时间为截断前剩余的时间步数。
dict_time_key – 对于具有
Dict
观察空间的环境,时间空间的键。默认为“time”。