一、装饰器
装饰器是一种修改现有环境的便捷方式,无需直接修改底层代码。使用装饰器将允许您避免大量样板代码,并使您的环境更加模块化。装饰器也可以被链接起来根据效果组合使用。情况下,通过gym.make
生成的大多数环境都默认已被包装。
为了打包环境,必须首先初始化一个基本环境。然后,可以将此环境及(可选的)参数传递给装饰器的构造函数。您可以使用.env
属性访问第一个装饰器下的环境。
如果您想进入所有装饰层下面的那个环境,可以使用.unwrapped
属性。如果环境已经是一个裸环境,那么.unwrapped
属性将只返回自身。
装饰器三个常见的用法:
- 在将动作应用于基础环境之前对其进行转换
- 转换基本环境返回的观察值
- 转换基础环境返回的奖励
通过继承ActionWrapper、ObservationWrapper和RewardWrapper或分别转换,可以实现这些装饰器。如果需要装饰器来执行更复杂的任务,可以直接从Wrapper
类继承。
1.ActionWrapper
如果希望在动作传递到基本环境之前对该动作应用函数,只需从ActionWrapper
继承并重写action
方法即可实现该转换。由该方法定义的转换必须取值于基本环境的动作空间。但是,它的域可能不同于原始的动作空间。在这种情况下,需要通过在装饰器的__init__
方法中设置self._action_space
来指定装饰器的新动作空间。除此之外,Gym还提供动作装饰器ClipAction
和RescaleAction
。
2.ObservationWrapper
如果希望在将基本环境返回的结果传递给学习代码之前对该观察结果应用函数,只需从ObservationWrapper继承并重写observation
方法即可实现该转换。该转换必须由基础环境的观察空间定义。但是,它可能会在不同的空间中获取值。在这种情况下,需要通过在装饰器的__init__
方法中设置self._observation_space
来为装饰器指定新的观察空间。其中,Gym提供了观察装饰器TimeAwareObservation,它将有关时间步索引的信息添加到观察中。
3.RewardWrapper
如果希望在将基本环境返回的奖励传递给学习代码之前对该奖励结果应用函数,只需从RewardWrapper继承并重写奖励方法即可实现该转换。这种转变可能会改变奖励范围;要指定装饰器的奖励范围,只需在_init__中定义self._reward_range
即可。
4.自动复位装饰器
有时希望当被装饰环境达到done状态时,装饰器能自动重置环境。这种环境的一个优点是,当越过done状态时,永远不会像标准Gym环境那样产生未定义的行为。
当调用step使self.env.step()
返回done=True时,调用self.env.reset()
,返回的self.step()
格式如下:
new_obs, terminal_reward, terminal_done, info
new_obs
是调用self.env.reset()
的首次观察,
terminal_reward
是调用self.env.step()后的奖励
, 优先于调用 self.env.reset(),
terminal_done
总是 True
,
info
是一个dict,其中包含调用self.env.reset()
返回的info dict的所有键(keys)。额外的,terminal_observation包含最后一次调用self.env.step()
返回的观察值,terminal_info包含最后一次调用self.env.step()
返回的info dict。
如果在调用self.env.step()
时done
不是true,则self.step()
会像正常情况一样返回:
obs, reward, done, info
在调用gym.make()
时,默认情况下不会应用AutoResetRapper,但是可以通过将可选的autoreset
参数设置为True
来应用AutoResetRapper。AutoResetRapper也可以使用其构造函数应用。
当使用AutoResetWrapper收集卷展时,请注意,当
self.env.step()
返回“done”时,调用self.env.reset()
后self.step()
会返回一个新的观察结果,该观察结果延续自的前一集(episode)的“终端奖励和done”状态。如果你需要上一集的终端状态,你需要通过info dict中的terminal_observation
键来检索它。
5.General Wrappers
有时,可能希望使用装饰器实现更加复杂的修改(例如,根据信息中的数据修改奖励或更改渲染行为)。这样的装饰器可以通过从Wrapper类
继承。
-
通过在
__init__
中分别定义self._action_space
或self._observation_space
来设置新的操作或观察空间 -
通过在
__init__
中分别定义self._metadata
和self._reward_range
,可以设置新的元数据和奖励范围 -
也可以覆盖step、render、close等。为此,可以通过访问属性
self.env
来访问传递给装饰器的环境(该装饰器仍然有可能被打包在其他装饰器中)。
6.Available Wrappers
Name | Type | Arguments | Description |
---|---|---|---|
|
|
| Implements the best practices from Machado et al. (2018), |
|
|
| 当达到“done”状态时,打包环境将自动重置。在使用此装饰器之前,请务必阅读文档! |
|
|
| 将连续操作剪裁到环境的 |
|
|
| 如果有一个将字典数据作为观察结果返回的环境,但只希望保留条目的子集,那么可以使用此装饰器。filter_keys应该是可迭代的,其中包含保存在新观察中的键。如果没有,则保留所有keys,且装饰器无效 |
|
|
| 观察装饰器,flattens the observation |
|
|
| 以滚动方式堆叠观察结果的观察装饰器。观察对象将是 |
|
|
| 将图像观察值从RGB转换为灰度。默认情况下,生成的观察结果是二维的。如果 |
|
|
| 这个装饰使即时奖励标准化(例如,指数移动平均值有固定的方差)。 |
|
|
| 这个包装饰将观察结果标准化(例如,每个坐标都以单位方差为中心)。标准化取决于过去的轨迹,如果装饰器是新实例化的,或者策略是最近更改的,则观察结果将无法正确标准化。 |
|
|
| 如果在初始 |
|
|
| 通过 |
|
|
| 记录累积奖励和脚本(episode)长度。在一集结束时,该集的统计信息将添加到 |
|
|
| This wrapper will record videos of rollouts. The results will be saved in the folder specified via |
|
|
| 将环境的连续动作空间重新缩放到一个范围[ |
|
|
| 此装饰器适用于具有图像观察(或更一般地说是形状AxBxC的观察)的环境,并将观察调整为元组shape 给定的形状。参数shape 也可以是整数。在这种情况下,观测值被缩放为边长shape 的平方 |
|
|
| 使用trajectory中的当前的时间步长(通过将其附加到观测值中)增加观测值。这有助于一切stay Markov。目前它只适用于一维观测空间。 |
|
|
| 也许是Gym里最有用的装饰器。如果在一集中超过指定的步数,该装饰器将发出一个done信号。为了能够区分终止和截断,您需要检查 |
|
|
| 这个包装将f函数作用于观察 |
|
|
| 这个包装将f函数作用于奖励 |
Wrappers - Gym Documentationhttps://www.gymlibrary.ml/content/wrappers/