强化学习 | Gym官方文档——Basic Usage(1)

初始化环境 Initializing Environments

        在gym中初始化环境非常简单,可以用以下代码

import gym
env = gym.make('CartPole-v0')

环境交互 Interacting with the Environment

        Gym实现了经典的“模型-环境交互循环”结构

        智能体agent在环境中做出一些动作,通过观察获得环境的变化状态。这样的一次交互被称之为一个时间步长timestep

        强化学习模型的目的是为了用一种特殊的方式和环境交互。例如,我们希望模型引导机器人到达空间中的某个特殊点,如果他成功抵达,或者向着这个点前进,就会收到一些奖励reward作为反馈。如果模型尚未到达目标点或者没有任何进展,奖励将会是0或者负值。通过多次训练,模型最终将会使奖励值最大化

        经过多个步长后,环境可能会进入终止状态terminal state,例如机器人可能会坠毁,在这种情况下,必须重置环境达到初始状态initial state。环境在终止状态下需要向模型返回终止信号done signal。然而不是所有终止信号都由这种灾难性的失败触发的,有时我们也可以在一定时长之后终止模型,或者模型已经与环境交互完成了某些特定的任务后终止

        让我们通过下面这个例子,看看agent-environment loop是如何在gym中被实现的

import gym
env = gym.make("LunarLander-v2", render_mode="human")
env.action_space.seed(42)
observation, info = env.reset(seed=42)
for _ in range(1000):
    observation, reward, terminated, truncated, info = env.step(env.action_space.sample())
    if terminated or truncated:
        observation, info = env.reset()
env.close()

        通过属性env.action_space实现了在不同环境中与之对应的特殊形式的动作空间,同理通过属性env.observation_space实现了不同环境中与之对应的特殊形式的观测值。在上面的例子中通过env.action_space.sample()方法,在动作空间中随机选取了动作。

        注意,我们需要将动作空间与环境独立开来,以确保样本的可重复性(Note that we need to seed the action space separately from the environment to ensure reproducible samples.)

接口完整性检查 Checking API-Conformity

        如果你已经实现了一个自定义环境,并且希望执行完整性检查以确保它与接口保持相对应,可以运行

from gym.utils.env_checker import check_env
check_env(env)

        如果环境没有遵循Gym API,该函数将抛出异常。如果你犯了其他错误或者没有传入正确类型的参数,它也会发出警告。可以通过传参warn=False来关闭警告。默认情况下,check_env不会检查参数render的值,要改变这种行为,你可以传参skip_render_check= false。

        注意,在环境上运行check_env之后不应该再次使用被检查的实例,因为它可能已经关闭了。

空间 Spaces

        空间通常被用于指定不同动作和观测值的形式,每个环境都应该有action_space和observation_space属性,这两个属性都应该是继承自Space空间类的实例。

        Gym中有多种可用的空间类型:

  1. Box:表示一个n维连续空间,这是一个有界的空间,我们可以定义上限和下限来描述实际观测值。
  2. Discrete:表示一个离散空间,其中{0,1,…,(n-1)}是观测值或动作的可能值,通过传参可以使取值范围变到{a, a+1,…,(a+n-1) }
  3. Dict:表示包含简单空间的字典。
  4. Tuple:表示由简单空间组成的元组。
  5. MultiBinary:表示规模为n的二进制空间。参数n可以是一个数字或一个数字列表。
  6. MultiDiscrete:表示一系列离散空间,每个元素中有数量不同的动作。
>>> from gym.spaces import Box, Discrete, Dict, Tuple, MultiBinary, MultiDiscrete
>>>
>>> observation_space = Box(low=-1.0, high=2.0, shape=(3,), dtype=np.float32)
>>> observation_space.sample()
[ 1.6952509 -0.4399011 -0.7981693]
>>>
>>> observation_space = Discrete(4)
>>> observation_space.sample()
1
>>>
>>> observation_space = Discrete(5, start=-2)
>>> observation_space.sample()
-2
>>>
>>> observation_space = Dict ({"position": Discrete(2), "velocity": Discrete(3)})
>>> observation_space.sample ()
OrderedDict ([('position', 0), ('velocity', 1)])
>>>
>>> observation_space = Tuple((Discrete(2), Discrete(3)))
>>> observation_space.sample()
(1, 2)
>>>
>>> observation_space = MultiBinary(5)
>>> observation_space.sample()
[1 1 1 0 1]
>>>
>>> observation_space = MultiDiscrete([ 5, 2, 2 ])
>>> observation_space.sample()
[3 0 0]

封装 Wrappers

        封装是一种修改现有环境而无需直接修改底层代码的快捷方法。使用封装可以避免使用大量样板代码,并使环境更加模块化。可以组合封装来达到多种效果。大多数通过gym.make生成的环境已经默认被封装好了。

        封装必须先初始化一个基本环境,然后将这个环境连同参数(也许是可选的),传递给封装器的构造函数进行封装

>>> import gym
>>> from gym.wrappers import RescaleAction
>>> base_env = gym.make("BipedalWalker-v3")
>>> base_env.action_space
Box([-1. -1. -1. -1.], [1. 1. 1. 1.], (4,), float32)
>>> wrapped_env = RescaleAction(base_env, min_action=0, max_action=1)
>>> wrapped_env.action_space
Box([0. 0. 0. 0.], [1. 1. 1. 1.], (4,), float32)

封装器三个常用功能:

  1. 变换动作使其与环境交互
  2. 变换由环境返回的观测值
  3. 变换由环境返回的奖励值

(Transform actions before applying them to the base environment

Transform observations that are returned by the base environment

Transform rewards that are returned by the base environment)

        这样的封装器可以通过继承ActionwrapperObservationwrapperRewardwrapper类和实现各自的变换函数接口轻松实现。

        然而,有时你可能需要实现一个封装来实现一些更复杂的改动(例如,根据info中的数据修改奖励值)。这样的封装器可以通过继承Wrapper类来实现。

        Gym已经为你提供了很多常用的封装。下面是一些例子:

  1. TimeLimit:如果超过了最大时间步数(或者基本环境发出了完成信号),则发出完成信号。
  2. ClipAction:修正动作,使其位于动作空间内(类型为Box)。
  3. RescaleAction:规范动作,将动作重新处于指定的取值区域内。
  4. TimeAwareObservation:将时间步长的索引信息添加到观察中。在某些情况下有助于确保转换是马尔可夫的。(markov:即下一个step的状态只与当前的状态有关)

马尔可夫决策过程 - 维基百科,自由的百科全书 (wikipedia.org)

        如果想要对封装好的环境解封以便查看底层函数和环境的某些属性,你可以使用.unwrapped属性,如果环境已经是底层环境,调用他就会返回本身

>>> wrapped_env
<RescaleAction<TimeLimit<BipedalWalker<BipedalWalker-v3>>>>
>>> wrapped_env.unwrapped
<gym.envs.box2d.bipedal_walker.BipedalWalker object at 0x7f87d70712d0>

操纵模型 Playing within an environment

        通过gym.utils.play模块中的play函数,你也可以使用键盘与环境进行交互

from gym.utils.play import play
play(gym.make('Pong-v0'))

        上述指令开启了一个窗口用来交互,允许你用键盘来操纵智能体

        使用键盘操作需要一组键盘的映射表,映射表的类型为dict[tuple[int], int|None],它将键映射到对应操作,举个例子,如果同时摁下w和space意味着动作2,映射表key_to_action编写如下

{
    # ...
    (ord('w'), ord(' ')): 2,
    # ...
}

        举一个更完整的例子,假如想要用left和right方向键操作模型CartPole-v0,代码如下

import gym
import pygame
from gym.utils.play import play
mapping = {(pygame.K_LEFT,): 0, (pygame.K_RIGHT,): 1}
play(gym.make("CartPole-v0"), keys_to_action=mapping)

        我们从pygame中获得相应的按键id,如果未指定key_to_action的值,将会使用env中的默认映射值(若已提供)

        此外,如果想要在交互的时候显示实时数据,可以使用gym.utils.play.PlayPlot模块,下面是一些示例代码,展示了最后五秒中的奖励值

def callback(obs_t, obs_tp1, action, rew, done, info):
    return [rew,]
plotter = PlayPlot(callback, 30 * 5, ["reward"])
env = gym.make("Pong-v0")
play(env, callback=plotter.callback)

官方文档(科学)

Basic Usage - Gym Documentation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值