PyTorch强化学习实战(3)——Gymnasium API扩展功能

PyTorch强化学习实战(3)------Gymnasium API扩展功能

    • [0. 前言](#0. 前言)
    • [1. 包装器 (Wrapper)](#1. 包装器 (Wrapper))
    • [2. 渲染环境](#2. 渲染环境)
    • [3. 更多包装器功能](#3. 更多包装器功能)
    • 小结
    • 系列链接

0. 前言

我们已经学习了编写智能体必需的 Gymnasium 核心功能,其余 API 功能部分虽然非必需,但能显著提升开发效率和代码整洁度。接下来,我们简要地介绍一下 Gymnasium API 的扩展功能。

1. 包装器 (Wrapper)

在实际应用中,我们经常需要以通用方式扩展环境功能。例如:某个环境提供的观测值可能需要先存入缓冲区,再向智能体提供最近 N 次观测记录------这在动态电子游戏场景中很常见,因为单帧画面往往无法反映完整游戏状态。又如需要对图像像素进行裁剪或预处理,使其更易于智能体处理;或对奖励分数进行归一化操作等。这类需求具有共同特征:都需要在现有环境外"包裹"额外处理逻辑,为此,Gymnasium 提供了包装器 (Wrapper) 这一便捷框架,类结构如下图所示。

Wrapper 类继承自 Env 类,其构造函数仅接受一个参数------需要被"包装"的 Env 类实例。若要扩展功能,需要重新定义想扩展的方法,如 step()reset(),但必须调用父类的原始方法。为方便访问被包装环境,Wrapper 提供两个属性:env 指向当前包装的环境(可能也是包装器),而 unwrapped 属性则指向最底层的原始环境。

为处理更具体的需求,例如只需处理环境观测值 (observation) 或仅需处理动作 (action) 的 Wrapper 类,可通过其子类实现特定信息的过滤。具体实现类如下:

  • ObservationWrapper:需重写父类的 observation(obs) 方法。obs 参数来自被包装环境的观测值,该方法应返回传给智能体的观测值
  • RewardWrapper:通过暴露 reward(rew) 方法修改传给智能体的奖励值,例如将其缩放至目标范围、基于历史动作添加折扣系数等
  • ActionWrapper:需重写 action(a) 方法,该方法可调整智能体传给被包装环境的动作

(1) 为使概念更直观,假设我们需要截获智能体发出的动作流,并以 10% 的概率将当前动作替换为随机动作。这种做法是解决"探索-利用困境"最实用且有效的方法之一。通过随机动作的注入,可强制智能体探索环境,使其偶尔偏离既定策略轨迹。使用 ActionWrapper 类可轻松实现该功能:

python 复制代码
import gymnasium as gym 
import random 

class RandomActionWrapper(gym.ActionWrapper): 
    def __init__(self, env: gym.Env, epsilon: float = 0.1): 
        super(RandomActionWrapper, self).__init__(env) 
        self.epsilon = epsilon

通过调用父类的 __init__ 方法初始化包装器,并保存随机动作概率 epsilon

(2) 重写父类方法,用于调整智能体的动作:

python 复制代码
    def action(self, action: gym.core.WrapperActType) -> gym.core.WrapperActType:
        if random.random() < self.epsilon: 
            action = self.env.action_space.sample() 
            print(f"Random action {action}") 
            return action 
        return action

每次执行动作时,系统都会以 epsilon 的概率从动作空间中采样随机动作,取代智能体原本要执行的动作。值得注意的是,通过使用 action_space 和包装器抽象,我们编写的这段通用代码适用于 Gymnasium 中任何环境。控制台打印的提示信息仅用于演示包装器的工作状态,实际生产代码中无需保留。

(3) 应用这个包装器。首先创建标准 CartPole 环境,然后将其传入包装器构造函数:

python 复制代码
if __name__ == "__main__":
    env = RandomActionWrapper(gym.make("CartPole-v1"))

我们把包装器当作普通的 Env 实例来使用,而不使用原始的 CartPole。由于 Wrapper 类继承自 Env 类并保持相同接口,我们可以根据需要任意嵌套包装器------这是一种强大、优雅且通用的解决方案。

(4) 以下是与随机智能体几乎相同的代码,区别在于我们每次都执行相同的动作 0

python 复制代码
    obs = env.reset()
    total_reward = 0.0

    while True:
        obs, reward, done, _, _ = env.step(0)
        total_reward += reward
        if done:
            break

    print(f"Reward got: {total_reward:.2f}")

运行代码后,能够看到包装器已经生效(控制台会随机出现"触发随机动作"的提示)。虽然智能体始终试图执行动作 0,但包装器会以 10% 的概率将其替换为随机动作,这直观展示了包装器对动作流的干预能力。

python 复制代码
Random action 1
Reward got: 10.00

接下来,了解如何在程序运行时渲染环境。

2. 渲染环境

渲染功能通过两个包装器实现:HumanRenderingRecordVideo。这两个类替代了原 OpenAI Gym 库中已移除的 Monitor 包装器(该包装器能记录智能体表现数据,并可选录制运行视频)。

Gymnasium 库中,可以通过两个类来观察环境内部状态。第一个是 HumanRendering,,它会打开一个独立的图形窗口,实时显示环境画面。要使环境支持渲染,初始化时必须传入参数 render_mode="rgb_array"。该参数指示环境从其 render() 方法返回像素数据,而该方法会被 HumanRendering 包装器调用。

(1) 因此,若要使用 HumanRenderer 包装器,需要修改随机智能体的代码:

python 复制代码
if __name__ == "__main__":
    env = gym.make("CartPole-v1", render_mode="rgb_array")
    env = gym.wrappers.HumanRendering(env)

运行代码时,环境渲染窗口将会出现。由于随机智能体无法长时间保持杆平衡(最多 10-30 步),当 env.close() 方法被调用时,窗口会迅速关闭。

(2) 另一个实用的包装器是 RecordVideo (视频录制),它能捕捉环境中的像素画面,生成智能体运行过程的视频文件。其使用方式与 HumanRendering 类似,但需额外指定存储视频文件的目录参数。若目录不存在,系统将自动创建:

python 复制代码
if __name__ == "__main__":
    env = gym.make("CartPole-v1", render_mode="rgb_array")
    env = gym.wrappers.RecordVideo(env, video_folder="video")

运行代码后,程序会生成游戏进行视频。该包装器在无图形界面的远程机器上运行智能体时尤为实用。

3. 更多包装器功能

Gymnasium 还提供大量其他包装器,可以对 Atari 游戏图像进行标准化预处理,进行奖励归一化,堆叠观测帧,实现环境向量化,设置时间限制等。

小结

在本节中,我们学习了如何以模块化的方式扩展现有环境的功能,并熟悉了使用包装器可视化智能体活动的方法。

系列链接

PyTorch强化学习实战(1)------强化学习(Reinforcement Learning,RL)详解
PyTorch强化学习实战(2)------强化学习环境库Gymnasium

相关推荐
微刻时光2 小时前
影刀RPA应用落地全流程指南:从需求到运维的实战手册
运维·人工智能·机器人·自动化·rpa·影刀rpa
Yeats_Liao2 小时前
华为开源自研AI框架昇思MindSpore应用案例:基于ResNet50的中药炮制饮片质量判断
人工智能·华为
User_芊芊君子2 小时前
破解交互系统的“不可能三角”:低延迟、高并发与低成本的端到端实现
人工智能·dubbo·生活
Web3VentureView2 小时前
SYNBO深度参与Ethereum on Tour 上海交大站:从高校 Builder 到链上一级市场基础设施
人工智能·web3·区块链·加密货币·synbo
嵌入式老牛4 小时前
OpenCV与MFC混合编程中的图像格式转换研究
人工智能·opencv·mfc
Raink老师9 小时前
【AI面试临阵磨枪】Harness 的环境隔离(沙箱)如何设计?文件、网络、命令、权限四层隔离?
人工智能·ai 面试
人工智能AI技术10 小时前
Python 断言 assert 基础用法
人工智能
我是发哥哈10 小时前
横向评测:五款主流AI培训课程效果与选型分析
人工智能
GetcharZp10 小时前
告别昂贵显卡!llama.cpp 终极指南:在你的电脑上满速运行大模型!
人工智能