觀測 Wrappers (包裝器)¶
- class gymnasium.ObservationWrapper(env: Env[ObsType, ActType])[原始碼]¶
使用
observation()
函數修改來自Env.reset()
和Env.step()
的觀測。如果您只想在將觀測傳遞到學習程式碼之前對其應用函數,您可以簡單地繼承自
ObservationWrapper
並覆寫方法observation()
以實作該轉換。在該方法中定義的轉換必須反映在env
觀測空間中。否則,您需要在 wrapper 的__init__()
方法中設定self.observation_space
來指定 wrapper 的新觀測空間。- 參數:
env – 要包裝的環境。
已實作的 Wrappers (包裝器)¶
- class gymnasium.wrappers.TransformObservation(env: gym.Env[ObsType, ActType], func: Callable[[ObsType], Any], observation_space: gym.Space[WrapperObsType] | None)[原始碼]¶
將函數應用於從環境的
Env.reset()
和Env.step()
收到的observation
,並將其傳遞回使用者。函數
func
將應用於所有觀測。如果來自func
的觀測超出env
的觀測空間的範圍,請提供更新的observation_space
。此 wrapper 存在向量版本
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 – wrapper 的觀測空間,如果為 None,則假設與
env.observation_space
相同。
- class gymnasium.wrappers.DelayObservation(env: Env[ObsType, ActType], delay: int)[原始碼]¶
為環境返回的觀測新增延遲。
在達到
delay
時間步數之前,返回的觀測是與觀測空間形狀相同的零陣列。此 wrapper 沒有向量版本。
注意
這不支援隨機延遲值,如果使用者有興趣,請提出問題或提取請求以新增此功能。
範例
>>> 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)[原始碼]¶
將觀測陣列的 dtype 修改為指定的 dtype。
注意
這僅與
Box
、Discrete
、MultiDiscrete
和MultiBinary
觀測空間相容此 wrapper 存在向量版本
gymnasium.wrappers.vector.DtypeObservation
。- 變更日誌
v1.0.0 - 初始新增
- 參數:
env – 要包裝的環境
dtype – 觀測的新 dtype
- class gymnasium.wrappers.FilterObservation(env: gym.Env[ObsType, ActType], filter_keys: Sequence[str | int])[原始碼]¶
依一組鍵或索引篩選 Dict 或 Tuple 觀測空間。
此 wrapper 存在向量版本
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
的 tuple 觀測空間的支援
- 參數:
env – 要包裝的環境
filter_keys – 要包含的子空間組,針對
Dict
使用字串列表,針對Tuple
空間使用整數
- class gymnasium.wrappers.FlattenObservation(env: Env[ObsType, ActType])[原始碼]¶
展平環境的觀測空間以及來自
reset
和step
函數的每個觀測。此 wrapper 存在向量版本
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')[原始碼]¶
以滾動方式堆疊來自最後
N
個時間步的觀測。例如,如果堆疊數為 4,則返回的觀測包含最近的 4 個觀測。對於環境 'Pendulum-v1',原始觀測是形狀為 [3] 的陣列,因此如果我們堆疊 4 個觀測,則處理後的觀測形狀為 [4, 3]。
使用者可以選擇使用的填充觀測
“reset”(預設)- 重複重設值
“zero” - 觀測空間的“零”類別實例
custom (自訂) - 觀測空間的實例
此 wrapper 沒有向量版本。
範例
>>> 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 – 套用 wrapper 的環境
stack_size – 要堆疊的幀數。
padding_type – 堆疊觀測時要使用的填充類型,選項:“reset”、“zero”、自訂觀測
- class gymnasium.wrappers.GrayscaleObservation(env: Env[ObsType, ActType], keep_dim: bool = False)[原始碼]¶
將
reset
和step
計算的影像觀測從 RGB 轉換為灰階。keep_dim
將保留通道維度。此 wrapper 存在向量版本
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)[原始碼]¶
跳過第 N 幀(觀測),並返回最後兩個觀測之間的最大值。
此 wrapper 沒有向量版本。
注意
此 wrapper 基於 [stable-baselines3](https://stable-baselines3.readthedocs.io/en/master/_modules/stable_baselines3/common/atari_wrappers.html#MaxAndSkipEnv) 中的 wrapper
範例
>>> 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) – 要套用 wrapper 的環境
skip – 要跳過的幀數
- class gymnasium.wrappers.NormalizeObservation(env: Env[ObsType, ActType], epsilon: float = 1e-8)[原始碼]¶
將觀測正規化為以平均值為中心且單位變異數。
屬性
update_running_mean
允許凍結/繼續觀測統計的運行平均值計算。如果True
(預設),則每次呼叫step
或reset
時,RunningMeanStd
都會更新。如果False
,則使用計算的統計資料,但不再更新;這可用於評估期間。此 wrapper 存在向量版本
gymnasium.wrappers.vector.NormalizeObservation
。注意
正規化取決於過去的軌跡,如果 wrapper 是新實例化的或最近更改了策略,則觀測將不會被正確正規化。
範例
>>> 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 的低/高值,以及 dtype 為 np.float32
- 參數:
env (Env) – 要套用 wrapper 的環境
epsilon – 一個穩定性參數,用於縮放觀測。
- class gymnasium.wrappers.AddRenderObservation(env: Env[ObsType, ActType], render_only: bool = True, render_key: str = 'pixels', obs_key: str = 'state')[原始碼]¶
在環境的觀測中包含渲染的觀測。
註解
這之前稱為
PixelObservationWrapper
。此 wrapper 沒有向量版本。
- 範例 - 將觀測替換為渲染的影像
>>> 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])[原始碼]¶
使用 OpenCV 將影像觀測調整為指定的形狀。
此 wrapper 存在向量版本
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 - 需要具有兩個整數 tuple 的
shape
- 參數:
env – 要包裝的環境
shape – 調整大小後的觀測形狀
- class gymnasium.wrappers.ReshapeObservation(env: gym.Env[ObsType, ActType], shape: int | tuple[int, ...])[原始碼]¶
將基於陣列的觀測重塑為指定的形狀。
此 wrapper 存在向量版本
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]
的範圍內。對於原始觀察空間中無界的組件,對應的目標邊界也必須是無限的,反之亦然。
此 wrapper 存在向量版本
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]¶
使用 episode 內採取的時間步數來擴增觀察。
如果
normalize_time
為True
,則時間表示為 [0,1] 之間的正規化值,否則如果False
,則目前的時間步長為整數。對於具有
Dict
觀察空間的環境,時間資訊會自動新增到鍵 “time” 中 (可以透過dict_time_key
變更),而對於具有Tuple
觀察空間的環境,時間資訊會新增為 tuple 中的最後一個元素。否則,觀察空間會轉換為具有兩個鍵的Dict
觀察空間,“obs” 代表基礎環境的觀察,“time” 代表時間資訊。若要展平觀察,請使用
flatten
參數,此參數將使用gymnasium.spaces.utils.flatten()
函數。此 wrapper 沒有向量版本。
範例
>>> 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 – 套用 wrapper 的環境
flatten – 將觀察展平為單一維度的 Box
normalize_time – 如果為 True,則傳回範圍在 [0,1] 的時間,否則傳回截斷前的剩餘時間步數
dict_time_key – 對於具有
Dict
觀察空間的環境,時間空間的鍵。預設為 “time”。