【强化学习】gymnasium自定义环境并封装学习笔记
【强化学习】gymnasium自定义环境并封装学习笔记
- gym与gymnasium简介
- gym
- gymnasium
- gymnasium的基本使用方法
- 使用gymnasium封装自定义环境
- 官方示例及代码
- 编写环境文件
- __init__()方法
- reset()方法
- step()方法
- render()方法
- close()方法
- 注册环境
- 创建包 Package(最后一步)
- 创建自定义环境示例
- 参考文献
gym与gymnasium简介
gym
-
gym(OpenAI Gym)和gymnasium是两个不同的Python库,它们都旨在为强化学习研究提供环境和工具
-
gym出现的原因:不同于监督学习那样需要的是数据集,强化学习需要的是运行任务所需的环境,研究人员需要拥有标准化的环境和模块化的强化学习代码,方便复用以及方便研究人员能够在相同的环境和条件下测试算法
-
gym通过提供一个统一的接口,
-
gym(OpenAI Gym)是由OpenAI团队开发的,是最早和最广泛使用的强化学习环境库之一
-
用于开发和比较强化学习算法的工具包和测试平台,提供了一个统一的接口来控制和交互各种环境
-
截止2023年,Gym 已经不再更新或维护,最新版本为v0.26.2
-
Gym的最新版本为v0.26.2,并且从这个版本开始,Gym的维护工作由Farama Foundation接手,并推出了Gymnasium
-
gym官网
gymnasium
- 所有Gym的开发工作已经转移到Gymnasium
- gymnasium是一个较新的库,它试图解决gym中的一些限制和问题,并提供更现代化的接口
- gymnasium设计时考虑了与gym的兼容性。它提供了一个兼容层,使得大多数gym环境可以直接在gymnasium中使用,无需或只需很少的修改
- gymnasium官网
gymnasium的基本使用方法
暂时先略过,日后补上,先介绍gymnasium封装自定义环境
使用gymnasium封装自定义环境
- gymnasium官方介绍封装自定义环境的文档,本文主要基于此文档
- 官方提供了示例代码,链接在此
- 安装gymnasium命令:
pip install gymnasium
官方示例及代码
- 官方使用的示例代码结构,如下所示
- wrappers是指包装器,用于修改或增强现有环境的行为,而不需要直接修改环境的源代码
- 使用 wrappers 的一个关键优势是它们提供了一种灵活的方式来修改和扩展环境的功能,而不需要改变环境本身的实现。这使得研究人员可以专注于算法的开发,同时利用 wrappers 来适应不同的实验条件和研究目标。
- env文件夹下的文件是环境名字
- 在命令行中可使用tree 命令查看目录及文件结构,windows下需要使用/F参数来显示文件
tree /F C:\path\to\directory
编写环境文件
- 所有自定义环境必须继承抽象类
gymnasium.Env
- 同时需要定义metadata,在 Gym 环境中,metadata 字典包含了环境的元数据,这些数据提供了关于环境行为和特性的额外信息
“render_modes”: 这个键的值是一个列表,指明了环境支持的渲染模式。在这个例子中,环境支持两种渲染模式:
“human”: 这种模式通常是指在屏幕上以图形界面的形式渲染环境,适合人类观察者观看。
“rgb_array”: 这种模式下,环境的渲染结果会以 RGB 数组的形式返回,这可以用于机器学习算法的输入,或者进行进一步的处理和分析。
“render_fps”: 这个键表示环境渲染的帧率,即每秒钟可以渲染的帧数。在这个例子中,4 表示环境将以每秒 4 帧的速率进行渲染。这通常用于控制渲染速度,使动画的播放更加平滑或符合特定的显示需
- 在环境文件中需要实现
__init__(),reset().setp(),render(),close()
等方法,确保环境能够按照强化学习的标准工作流程运行 - 定义action_space,智能体可以执行的动作类型和范围;定义observation_space,智能体可以观察到的状态的类型和范围
from gymnasium import spaces
- 连续的空间使用
spaces.Box
定义,low 和 high 参数指定了取值范围。 - 离散的空间使用
spaces.Discrete
,参数指定可能的数量
init()方法
- 初始化方法,用于设置环境的初始状态。这里可以定义环境参数、初始化状态空间和动作空间等
- 定义 action_space 和 observation_space时,需要从 Gymnasium 的 spaces 模块导入spaces
- spaces 模块提供了多种空间类型,用于表示强化学习环境中可能的动作和观察的类型和结构
import numpy as np
import pygameimport gymnasium as gym
from gymnasium import spacesclass GridWorldEnv(gym.Env):metadata = {"render_modes": ["human", "rgb_array"], "render_fps": 4}def __init__(self, render_mode=None, size=5):self.size = size # The size of the square gridself.window_size = 512 # The size of the PyGame window# Observations are dictionaries with the agent's and the target's location.# Each location is encoded as an element of {0, ..., `size`}^2, i.e. MultiDiscrete([size, size]).self.observation_space = spaces.Dict({"agent": spaces.Box(0, size - 1, shape=(2,), dtype=int),"target": spaces.Box(0, size - 1, shape=(2,), dtype=int),})# We have 4 actions, corresponding to "right", "up", "left", "down"self.action_space = spaces.Discrete(4)"""The following dictionary maps abstract actions from `self.action_space` tothe direction we will walk in if that action is taken.I.e. 0 corresponds to "right", 1 to "up" etc."""self._action_to_direction = {0: np.array([1, 0]),1: np.array([0, 1]),2: np.array([-1, 0]),3: np.array([0, -1]),}assert render_mode is None or render_mode in self.metadata["render_modes"]self.render_mode = render_mode"""If human-rendering is used, `self.window` will be a referenceto the window that we draw to. `self.clock` will be a clock that is usedto ensure that the environment is rendered at the correct framerate inhuman-mode. They will remain `None` until human-mode is used for thefirst time."""self.window = Noneself.clock = None
reset()方法
- 用于重置环境状态,在每个训练周期(episode)开始时,reset() 方法被调用以重置环境到一个初始状态
- 每次训练周期结束并且接收到结束信号(
done
标志)时,会调用 reset 方法来重置环境状态 - 用户可以通过
reset
方法传递一个seed
参数,用于初始化环境使用的任何随机数生成器,确保环境行为的确定性和可复现性
def reset(self, seed=None, options=None):# We need the following line to seed self.np_randomsuper().reset(seed=seed)# Choose the agent's location uniformly at randomself._agent_location = self.np_random.integers(0, self.size, size=2, dtype=int)# We will sample the target's location randomly until it does not coincide with the agent's locationself._target_location = self._agent_locationwhile np.array_equal(self._target_location, self._agent_location):self._target_location = self.np_random.integers(0, self.size, size=2, dtype=int)observation = self._get_obs()info = self._get_info()if self.render_mode == "human":self._render_frame()return observation, info
step()方法
step()
方法是环境与智能体交互的核心,包含了环境逻辑的核心部分step()
方法处理动作,更新环境状态,并返回五个值组成的元组(observation, reward, terminated, truncated, info)
:观察(observation)、奖励(reward)、是否终止(terminated)、是否截断(truncated)和附加信息(info)
五元组的含义(observation, reward, terminated, truncated, info)
观察(Observation):这是环境状态的表示,智能体根据这个观察来选择动作。观察可以是状态的一部分或全部,也可以是经过加工的信息,如图像、向量等。观察是智能体与环境交互的直接输入。
奖励(Reward):这是一个标量值,表示智能体执行动作后从环境中获得的即时反馈。奖励用于指导智能体学习哪些行为是好的,哪些是不好的。在许多任务中,智能体的目标是最大化其获得的总奖励。
是否终止(Terminated/Done):这是一个布尔值,表示当前周期(episode)是否结束。如果为 True,则表示智能体已经完成了任务,或者环境已经达到了一个终止状态,智能体需要重新开始新的周期。
是否截断(Truncated):这也是一个布尔值,与 done 相似,但表示周期结束的原因可能不是任务完成,而是其他原因,如超时、达到某个特定的中间状态或违反了某些规则。在某些实现中,truncated 可能与 done 相同或不被使用。
附加信息(Info):这是一个字典,包含除观察、奖励、终止和截断之外的额外信息。这些信息可以包括关于状态转换的元数据,如是否处于探索阶段、环境的内部计数器、额外的性能评估指标等。
def step(self, action):# Map the action (element of {0,1,2,3}) to the direction we walk indirection = self._action_to_direction[action]# We use `np.clip` to make sure we don't leave the gridself._agent_location = np.clip(self._agent_location + direction, 0, self.size - 1)# An episode is done iff the agent has reached the targetterminated = np.array_equal(self._agent_location, self._target_location)reward = 1 if terminated else 0 # Binary sparse rewardsobservation = self._get_obs()info = self._get_info()if self.render_mode == "human":self._render_frame()return observation, reward, terminated, False, info
- info可通过
_get_info
方法获取,该方法用于收集和返回除了观察和奖励之外的其他有用信息。这些信息可以包括关于环境状态的额外数据 _get_obs
方法负责将环境的内部状态转换为智能体可以观察的形式,通常涉及到从环境状态中提取相关信息,并将其格式化为智能体能够理解和使用的数据结构
def _get_obs(self):return {"agent": self._agent_location, "target": self._target_location}
def _get_info(self):return {"distance": np.linalg.norm(self._agent_location - self._target_location, ord=1)}
render()方法
- render 方法用于将环境的状态可视化
- 使用 Gymnasium 创建自定义环境时,PyGame 是一种流行的库,用于渲染环境的视觉表示。PyGame 允许创建图形窗口,并将环境的状态绘制到屏幕上,这对于需要视觉反馈的强化学习任务非常有用
渲染模式:
- “human”:以图形界面的形式渲染,适用于人类观察者。
- “rgb_array”:返回一个 RGB 图像数组,可以用于机器学习模型或进一步处理。
- 下面为示例代码中的render方法
def render(self):if self.render_mode == "rgb_array":return self._render_frame()def _render_frame(self):if self.window is None and self.render_mode == "human":pygame.init()pygame.display.init()self.window = pygame.display.set_mode((self.window_size, self.window_size))if self.clock is None and self.render_mode == "human":self.clock = pygame.time.Clock()canvas = pygame.Surface((self.window_size, self.window_size))canvas.fill((255, 255, 255))pix_square_size = (self.window_size / self.size) # The size of a single grid square in pixels# First we draw the targetpygame.draw.rect(canvas,(255, 0, 0),pygame.Rect(pix_square_size * self._target_location,(pix_square_size, pix_square_size),),)# Now we draw the agentpygame.draw.circle(canvas,(0, 0, 255),(self._agent_location + 0.5) * pix_square_size,pix_square_size / 3,)# Finally, add some gridlinesfor x in range(self.size + 1):pygame.draw.line(canvas,0,(0, pix_square_size * x),(self.window_size, pix_square_size * x),width=3,)pygame.draw.line(canvas,0,(pix_square_size * x, 0),(pix_square_size * x, self.window_size),width=3,)if self.render_mode == "human":# The following line copies our drawings from `canvas` to the visible windowself.window.blit(canvas, canvas.get_rect())pygame.event.pump()pygame.display.update()# We need to ensure that human-rendering occurs at the predefined framerate.# The following line will automatically add a delay to keep the framerate stable.self.clock.tick(self.metadata["render_fps"])else: # rgb_arrayreturn np.transpose(np.array(pygame.surfarray.pixels3d(canvas)), axes=(1, 0, 2))
close()方法
- close 方法用于在环境不再使用时进行清理操作,例如关闭图形界面窗口、释放资源或执行其他必要的清理任务
- 是一个没有参数也没有返回值的方法
- 如果环境使用 PyGame 或其他图形库创建了渲染窗口,close 方法应该关闭这些窗口。
def close(self):if self.window is not None:pygame.display.quit()pygame.quit()
注册环境
- 编写完上述与环境相关的代码后,需要注册自定义环境
- 注册自定义环境是为了使gymnasium检测到该环境
from gymnasium.envs.registration import registerregister(id="gym_examples/GridWorld-v0",entry_point="gym_examples.envs:GridWorldEnv",max_episode_steps=300,
)
- environment ID由三部分组成,①命名空间
gym_examples
(可选) ②强制名称GridWorld
③版本v0
(可选) - entry_point参数在注册自定义环境时使用,它指定了如何导入这个环境类
- 格式通常是
module:classname
- module 是包含环境类的 Python 模块的路径。
classname 是环境中具体的类的名称 - 其他可指定的参数如下所示:
- 经过注册的自定义环境GridWorldEnv可由以下命令创建
env = gymnasium.make('gym_examples/GridWorld-v0')
- gym-examples/gym_examples/envs/init.py 文件中需要包含以下的内容
from gym_examples.envs.grid_world import GridWorldEnv
创建包 Package(最后一步)
- 将代码构建为python的包,方便地在不同项目中重用自定义的环境代码
- 在
gym-examples/setup.py
中写入以下内容
from setuptools import setupsetup(name="gym_examples",version="0.0.1",install_requires=["gymnasium==0.26.0", "pygame==2.1.0"],
)
此处可以将"==“改为”>=",如果不打算做图形化可以删去pygame==2.1.0
安装自定义环境(在包含 setup.py
的目录中执行)
pip install -e .
- 安装成功后会生成gym_examples.egg-info文件夹
创建自定义环境示例
- 使用以下命令
import gym_examples
env = gymnasium.make('gym_examples/GridWorld-v0')
- 传参的版本
import gym_examples
env = gymnasium.make('gym_examples/GridWorld-v0', size=10)
参考文献
- Gymnasium Documentation:Make your own custom environment
- 深度强化学习:gymnasium下创建自己的环境(保姆式教程)
相关文章:

【强化学习】gymnasium自定义环境并封装学习笔记
【强化学习】gymnasium自定义环境并封装学习笔记 gym与gymnasium简介gymgymnasium gymnasium的基本使用方法使用gymnasium封装自定义环境官方示例及代码编写环境文件__init__()方法reset()方法step()方法render()方法close()方法 注册环境创建包 Package(最后一步&a…...

TLE9879的基于Arduino调试板SWD刷写接口
官方的Arduino评估板,如下图所示: 如果你有官方的调试器,应该不用关注本文章,如下图连接就是: 如果,您和博主一样需要自己飞线的话,如下图所示:PCB的名称在右边整理,SWD的…...

基于 Delphi 的前后端分离:之五,使用 HTMX 让页面元素组件化之面向对象的Delphi代码封装
前情提要 本博客上一篇文章,描述了使用 Delphi 作为后端的 Web Server,前端使用 HTMX 框架,把一个开源的前端图表 JS 库,进行了组件化。 上一篇文章仅仅是描述了简单的前端代码组件化的可能性,依然是基于前端库的 JS…...

讲透计算机网络知识(实战篇)01——计算机网络和协议
一、计算机网络和协议 1、网络和互联网络 1.1 网络、互联网、Internet 用交换机、集线器连接在一起的计算机构成一个网络。 用路由器连接多个网络,形成互联网。 全球最大的互联网:Internet。 1.2 网络举例 家庭互联网 图中的无线拨号路由器既是路由…...

8个宝藏APP,个个都牛逼哈拉!
AI视频生成:小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 目前win7已经逐渐淡出人们的视野,大部分人都开始使用win10,在日常工作和使用中,创客们下载神奇的软件能大幅提…...

使用docker构建java应用
1、docker简介 Docker是一个开源的容器化平台,可以帮助开发人员将应用程序及其依赖项打包成一个可移植的容器。容器化是一种轻量级的虚拟化技术,可以使应用程序在不同的操作系统和环境中具有一致的运行方式。 使用Docker带来的好处包括: 简…...

Oracle 存储过程
Oracle存储过程 创建存储过程 CREATE OR REPLACE PROCEDURE UPDATE_EMPLOYEE_SALARY(p_employee_id IN NUMBER,p_employee_salary IN NUMBER )AS BEGINUPDATE employeesSET salary p_employee_salaryWHERE employee_id p_employee_id;COMMIT;EXCEPTIONWHEN NO_DATA_FOUND T…...

下载站名文件
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 得到了请求地址与请求参数后,可以发现请求参数中的出发地与目的地均为车站名的英文缩写。而这个英文缩写的字母是通过输入中文车站名转换…...

345453
38744...

Java操作redis
目录 一:Jedis 二:使用Spring Data Redis Redis 的 Java 客户端很多,官方推荐的有三种: 1.Jedis 2.Lettuce 3.Redisson 同时,Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在S…...

【数据结构(邓俊辉)学习笔记】图03——拓扑排序
文章目录 0. 概述1. 零入度算法1. 1 拓扑排序1. 2 算法 2. 零出度算法2.1 算法2.2 实现2.3. 复杂度 0. 概述 学习下拓扑排序 1. 零入度算法 1. 1 拓扑排序 首先理解下拓扑排序 其实老师经常干这事,如编讲义,将已经知道的知识点串起来变成讲课序列。那…...

C#参数使用场景简要说明
C#参数使用场景简要说明 1、传值参数 方法、类成员的初始化 2、输出参数 方法返回值不能满足,需要多个返回值时; 3、引用参数 方法需要修改变量需带回原变量时; 4、具名参数 代码可读性高,参数可交换位置 5、方法扩展(…...

线性代数|机器学习-P10最小二乘法的四种方案
文章目录 1. 概述2. SVD奇异值分解3. 最小二乘法方程解4. 最小二乘法图像解释5. Gram-Schmidt 1. 概述 当我们需要根据一堆数据点去拟合出一条近似的直线的时候,就会用到 最小二乘法 .根据矩阵A的情况,有如下四种方法 在r n m 时,SVD奇异…...

【Android面试八股文】你能描述一下JVM中的类加载过程吗?
文章目录 一、Java类的生命周期二、JVM类加载过程1. 加载(Loading)2. 链接(Linking)a. 验证(Verification)b. 准备(Preparation)b.1 准备阶段的初始值b.2 用户定义的初值b.3 常量的初始化c. 解析(Resolution)3. 初始化(Initialization)3.1 什么是 `<clinit>`…...

MYSQL八、MYSQL的SQL优化
一、SQL优化 sql优化是指:通过对sql语句和数据库结构的调整,来提高数据库查询、插入、更新和删除等操作的性能和效率。 1、插入数据优化 要一次性往数据库表中插入多条记录: insert into tb_test values(1,tom); insert into tb_tes…...

鸿蒙轻内核M核源码分析系列二一 02 文件系统LittleFS
1、LFS文件系统结构体介绍 会分2部分来介绍结构体部分,先介绍LittleFS文件系统的结构体,然后介绍LiteOS-M内核中提供的和LittleFS相关的一些结构体。 1.1 LittleFS的枚举结构体 在openharmony/third_party/littlefs/lfs.h头文件中定义LittleFS的枚举、…...

【ARMv8/ARMv9 硬件加速系列 3 -- SVE 指令语法及编译参数详细介绍】
文章目录 SVE 汇编语法SVE 单通道谓词SVE 测试代码 SVE 软件和库支持SVE 编译参数配置-marcharmv8-alseprofilememtagsve2-aessve2-bitpermcryptosve2sve2-sha3sve2-sm4 SVE 汇编语法 在介绍 SVE 汇编指令语法之前,先介绍下如何判断自己所使用的芯片是否实现了SVE功…...

Java版+ SaaS应用+接口技术RESTful API 技术开发的智慧医院HIS系统源码 专注医院管理系统研发 支持二开
Java版 SaaS应用接口技术RESTful API WebSocket WebService技术开发的智慧医院HIS系统源码 专注医院管理系统研发 支持二开 医院住院管理系统(Hospital Information System简称HIS)是一门医学、信息、管理、计算机等多种学科为一体的边缘科学ÿ…...

工业机器人远程运维,增强智慧工厂运营管理
1、需求背景 随着工业自动化技术的普及和工业机器人应用的增加,制造业对于生产线稳定性和效率的要求不断提高。然而,传统的现场监控方式存在着地理位置限制、实时监控难度大以及诊断能力有限等问题,迫切需要一种更具灵活性和效率的监控方式。…...

理解Python的元类
1.type()函数 type 函数是一个内置函数,用来获取一个对象的类型。它可以接受一个参数,返回这个参数的数据类型。type也可以用来创建类,type就是元类 x333 list["ab"] tuple (1, "a", True, 3.14) dict {name: Alice,…...

web前端黑马下载:探索学习资源的海洋
web前端黑马下载:探索学习资源的海洋 在数字化时代,Web前端技术日益成为互联网行业的核心驱动力。为了跟上这一趋势,众多学习者纷纷投身于Web前端的学习之中。而在这个过程中,“黑马”作为一个备受瞩目的品牌,其Web前…...

最新版jd-gui下载
对于java开发的工程师来说,jd-gui应该是经常会用到的工具了 官网的jd-gui目前只支持到JAVA13,更新版本JAVA编译出来的JAR包就反编译不出来了 此版本支持到了JAVA23 如果需要win以外的其他版本,可以查看我的其他上传 如果不想花积分&#…...

(051)FPGA时钟--->(001)时钟介绍
(001)时钟介绍 1 目录 (a)FPGA简介 (b)Verilog简介 (c)时钟简介 (d)时钟介绍 (e)结束 1 FPGA简介 (a)FPGA(Field Programmable Gate Array)是在PAL (可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电…...

Java程序员英语单词通关:
Java程序员英语单词通关: abstract - 抽象的 boolean - 布尔值 break - 打断 byte - 字节 case - 情况,实例 catch - 捕获 char - 字符 class - 类 continue - 继续 default - 默认,通常 do - 做,运行 double - 双精度…...

数据库开发-Mysql03
目录 1. 多表查询 1.1 概述 1.1.1 数据准备 1.1.2 介绍 1.1.3 分类 1.2 内连接 1.3 外连接 1.4 子查询 1.4.1 介绍 1.4.2 标量子查询 1.4.3 列子查询 1.4.4 行子查询 1.4.5 表子查询 1.5 案例 2. 事务 2.1 介绍 2.2 操作 2.3 四大特性 3. 索引 3.1 介绍 3…...

0-1 背包问题(动态规划 查询背包元素)
描述 给定n种物品和一个背包,物品i的重量是Wi,其价值为Vi,问如何选择装入背包的物品,使得装入背包的物品的总价值最大? 在选择装入背包的物品时,对每种物品i只能有两种选择,装入或者不装入…...

elasticsearch快照生成与恢复
Elasticsearch快照生成与恢复的场景主要涉及到数据的备份与恢复需求。当需要对Elasticsearch集群中的数据进行备份,或者在数据丢失、损坏等情况下需要恢复数据时,就可以使用快照功能。 快照生成的方法通常包括以下步骤: 1、创建一个快照仓库…...

178.二叉树:最大二叉树(力扣)
代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…...

跨境电商中的IP隔离是什么?怎么做?
一、IP地址隔离的概念和原理 当我们谈论 IP 地址隔离时,我们实际上是在讨论一种网络安全策略,旨在通过技术手段将网络划分为不同的区域或子网,每个区域或子网都有自己独特的 IP 地址范围。这种划分使网络管理员可以更精细地控制哪些设备或用…...

【C++】stack、queue和deque的使用
💗个人主页💗 ⭐个人专栏——C学习⭐ 💫点击关注🤩一起学习C语言💯💫 目录 导读 一、stack 1. stack介绍 2. stack使用 二、queue 1. queue介绍 2. queue使用 三、deque 1. deque介绍 2. deque的…...