注意
转到末尾下载完整的示例代码。
环境(Environments)、TED 和变换(transforms)入门¶
作者: Vincent Moens
注意
要在 notebook 中运行此教程,请在开头添加一个安装单元格,其中包含
!pip install tensordict !pip install torchrl
欢迎来到入门教程!
下面列出了我们将要涵盖的主题。
如果你很赶时间,可以直接跳到最后一个教程:你的第一个训练循环。如果遇到不清楚的地方或想了解特定主题,可以从那里回溯其他“入门”教程!
强化学习中的环境(Environments)¶
标准的强化学习 (RL) 训练循环涉及一个模型(也称为策略),该模型经过训练以在特定环境中完成一项任务。通常,这个环境是一个模拟器,它接受动作作为输入,并产生观察结果以及一些元数据作为输出。
在本文档中,我们将探索 TorchRL 的环境 API:我们将学习如何创建一个环境、如何与它交互,以及它使用的数据格式。
创建环境¶
本质上,TorchRL 不直接提供环境,而是提供封装了模拟器的其他库的包装器。envs
模块可以被视为通用环境 API 的提供者,也是模拟后端(如 gym (GymEnv
)、Brax (BraxEnv
) 或 DeepMind Control Suite (DMControlEnv
))的中心枢纽。
创建环境通常与底层后端 API 一样简单。以下是使用 gym 的示例
from torchrl.envs import GymEnv
env = GymEnv("Pendulum-v1")
运行环境¶
TorchRL 中的环境有两个关键方法:reset()
,用于启动一个回合,以及 step()
,用于执行由 actor 选择的动作。在 TorchRL 中,环境方法读写 TensorDict
实例。本质上,TensorDict
是一种用于张量的通用键值数据载体。使用 TensorDict 而非普通张量的好处是,它可以让我们互换地处理简单和复杂的数据结构。由于我们的函数签名非常通用,它消除了适应不同数据格式的挑战。简单来说,在这个简短的教程之后,你将能够操作简单和高度复杂的环境,因为它们的用户界面 API 相同且简单!
让我们让环境动起来,看看 tensordict 实例是什么样的
reset = env.reset()
print(reset)
现在让我们在动作空间中采取一个随机动作。首先,采样动作
reset_with_action = env.rand_action(reset)
print(reset_with_action)
这个 tensordict 的结构与从 EnvBase()
获得的相同,只是多了一个 "action"
条目。你可以像访问普通字典一样轻松访问该动作
print(reset_with_action["action"])
现在我们需要将这个动作传递给环境。我们将把整个 tensordict 传递给 step
方法,因为在更高级的场景(如多智能体强化学习或无状态环境)中可能需要读取多个张量
stepped_data = env.step(reset_with_action)
print(stepped_data)
同样,这个新的 tensordict 与前一个相同,只是它有一个 "next"
条目(它本身也是一个 tensordict!),其中包含我们的动作产生的观察结果、奖励和完成状态。
我们将这种格式称为 TED,即 TorchRL 回合数据格式(TorchRL Episode Data format)。它是库中表示数据的普遍方式,无论是动态表示(如这里)还是静态表示(如离线数据集)。
在环境中运行 rollout 所需的最后一点信息是如何将 "next"
条目提升到根部以执行下一步。TorchRL 提供了一个专门的函数 step_mdp()
来完成这项工作:它过滤掉你不需要的信息,并提供一个数据结构,该结构对应于在马尔可夫决策过程 (MDP) 中执行一步之后的观察结果。
from torchrl.envs import step_mdp
data = step_mdp(stepped_data)
print(data)
环境 rollout¶
写下这三个步骤(计算动作、执行一步、在 MDP 中前进)可能会有些繁琐和重复。幸运的是,TorchRL 提供了一个方便的函数 rollout()
,允许你随意在一个闭环中运行它们
rollout = env.rollout(max_steps=10)
print(rollout)
这些数据看起来很像上面的 stepped_data
,不同之处在于其 batch-size,它现在等于我们通过 max_steps
参数提供的步数。tensordict 的神奇之处不止于此:如果你对环境中某个单一转换感兴趣,你可以像索引张量一样索引 tensordict
transition = rollout[3]
print(transition)
TensorDict
会自动检查你提供的索引是键(在这种情况下,我们沿键维度索引)还是像这里的空间索引。
像这样执行(没有策略),rollout
方法可能看起来相当无用:它只是运行随机动作。如果有一个策略可用,可以将其传递给该方法并用于收集数据。
尽管如此,先运行一个简单的、无策略的 rollout 对于快速查看环境预期行为很有用。
为了体会 TorchRL API 的通用性,请注意 rollout 方法是普遍适用的。它适用于所有用例,无论你是在使用像这里这样的单个环境、跨多个进程的多个副本、多智能体环境,甚至是其无状态版本!
变换环境¶
大多数时候,你会希望修改环境的输出,使其更好地满足你的需求。例如,你可能希望监控自上次重置以来执行的步数、调整图像大小或将连续的观察结果堆叠在一起。
在本节中,我们将研究一个简单的变换,即 StepCounter
变换。变换的完整列表可以在这里找到。
变换通过 TransformedEnv
与环境集成
from torchrl.envs import StepCounter, TransformedEnv
transformed_env = TransformedEnv(env, StepCounter(max_steps=10))
rollout = transformed_env.rollout(max_steps=100)
print(rollout)
如你所见,我们的环境现在多了一个条目 "step_count"
,它记录了自上次重置以来的步数。由于我们在变换构造函数中传递了可选参数 max_steps=10
,我们在 10 步后截断了轨迹(没有像我们使用 rollout
调用时那样完成 100 步的完整 rollout)。我们可以通过查看 truncated 条目来看到轨迹被截断了
print(rollout["next", "truncated"])
这是 TorchRL 环境 API 简短介绍的全部内容!
下一步¶
要进一步探索 TorchRL 的环境功能,请查看
将
step()
、step_mdp()
和reset()
方法打包在一起的step_and_maybe_reset()
方法。一些环境(如
GymEnv
)通过from_pixels
参数支持渲染。查看类文档字符串了解更多!批处理环境,特别是
ParallelEnv
,它允许你在多个进程上运行同一个(或不同的!)环境的多个副本。通过 Pendulum 教程设计自己的环境,并学习关于 specs 和无状态环境。
查看关于环境的更深入教程,请参考专门教程;
如果你对多智能体强化学习 (MARL) 感兴趣,请查看多智能体环境 API;
TorchRL 有许多工具可以与 Gym API 交互,例如通过
register_gym()
将 TorchRL 环境注册到 Gym 注册表中,通过set_info_dict_reader()
读取信息字典的 API,或借助set_gym_backend()
控制 gym 后端的方式。