ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Gymnasium Fundamental Spaces 完全指南:Box、Discrete、MultiBinary、MultiDiscrete 与 Text

Gymnasium Fundamental Spaces 完全指南:Box、Discrete、MultiBinary、MultiDiscrete 与 Text Gymnasium Fundamental Spaces 完全指南Box、Discrete、MultiBinary、MultiDiscrete 与 Text【免费下载链接】GymnasiumA standard API for single-agent reinforcement learning environments, with popular reference environments and related utilities (formerly Gym)项目地址: https://gitcode.com/GitHub_Trending/gy/Gymnasium本文是 Gymnasium前身 Gym单智能体强化学习环境 API 中基础空间Fundamental Spaces的系统性技术指南。空间Space定义了环境动作与观测的合法取值集合是所有 Gymnasium 环境action_space与observation_space的基石。读完本文你将掌握五个基础空间Box、Discrete、MultiBinary、MultiDiscrete、Text的构造参数、抽样sample、掩码抽样、种子控制seed、成员校验contains与边界行为如Box.is_bounded并理解其底层实现能够直接在自定义环境与强化学习代码中正确选用与使用它们。一、空间体系概览从抽象基类到五个基础空间在 Gymnasium 中所有空间都继承自抽象基类 Space该基类提供了统一的接口契约。五个基础空间是其中最常用、最基础的一层与组合空间Tuple、Dict、Sequence、Graph、OneOf共同构成完整的空间体系见 gymnasium/spaces/__init__.py。1.1 Space 基类的核心职责Space基类gymnasium/spaces/space.py为所有空间定义了三大核心用途明确交互格式规定合法动作长什么样、观测返回什么结构支持结构化数据让高度结构化的数据如Dict空间元素能被无损地展平为可用于学习代码的扁平数组随机抽样提供sample()方法生成随机元素是探索与调试的重要工具。基类还提供了统一的底层设施shape属性以不可变tuple返回空间形状space.pydtype属性元素的 NumPy 数据类型np_random属性惰性初始化的 NumPyGenerator只有真正调用sample时才创建避免不必要的性能开销space.pyis_np_flattenable判断该空间能否被展平为Boxcontains/__contains__等价于x in space的成员校验to_jsonable/from_jsonable与 JSON 数据格式互转供日志记录与通信使用__setstate__兼容加载旧版本 pickle 状态如旧字段名shape、np_random。1.2 种子机制可复现性的根基所有空间的seed()最终都调用 gymnasium/utils/seeding.py 中的np_random(seed)若seed为None自动生成一个随机种子否则要求传入非负 Python 整数否则抛出Error内部通过np.random.SeedSequence(seed)构造PCG64位生成器并返回(rng, np_seed)二元组其中np_seed是实际使用的熵值对None输入尤其重要——可以据此复现。这也是所有 Gymnasium 环境中reset(seed...)重置 RNG 的底层机制意味着空间抽样、环境转移、奖励计算可以做到全局可复现。1.3 环境中的真实用法Gymnasium 自带的环境几乎都以基础空间定义接口例如CartPoleself.action_space spaces.Discrete(2)self.observation_space spaces.Box(-high, high, dtypenp.float32)cartpole.pyAcrobotself.action_space spaces.Discrete(3)观测为 6 维Boxacrobot.pyLunarLanderself.action_space spaces.Discrete(4)连续版本用spaces.Box(-1, 1, (2,), dtypenp.float32)lunar_lander.pyMuJoCo 环境观测统一为Boxant_v5.py、half_cheetah_v5.py。import gymnasium as gym from gymnasium.spaces import Box, Discrete # 标准环境的接口即由基础空间构成 env gym.make(CartPole-v1) print(env.action_space) # Discrete(2) print(env.observation_space) # Box([...], [...], (4,), float32)二、Box欧几里得空间中的可能有界盒子Box表示 $\mathbb{R}^n$ 中一个可能有界的闭盒即 n 个闭区间的笛卡尔积。每个维度区间可以是 $[a, b]$、$(-\infty, b]$、$[a, \infty)$ 或 $(-\infty, \infty)$ 四种形式之一。它是最常用的观测空间向量、图像、传感器读数也可作为连续动作空间如推力、力矩。2.1 构造参数与形状推断Box的构造签名box.pyBox(low, high, shapeNone, dtypenp.float32, seedNone)关键参数参数类型说明low标量 或np.ndarray各维下界。若为标量则所有维度共用该下界若为整数须不小于-2**63high标量 或np.ndarray各维上界。若为标量则所有维度共用该上界若为整数须不大于2**63 - 2shapeSequence[int]可选。若不提供由low/high的 ndarray 形状推断二者皆为标量时默认形状(1,)dtype类型或字符串元素数据类型必须显式提供不能为None否则抛ValueErrorseedint或np.random.Generator可选抽样 RNG 的种子两种典型构造方式源码文档示例box.py from gymnasium.spaces import Box import numpy as np # 方式一各维共享同一组边界 显式 shape Box(low-1.0, high2.0, shape(3, 4), dtypenp.float32) Box(-1.0, 2.0, (3, 4), float32) # 方式二每维独立边界shape 从数组推断 Box(lownp.array([-1.0, -2.0]), highnp.array([2.0, 4.0]), dtypenp.float32) Box([-1. -2.], [2. 4.], (2,), float32)2.2 合法 dtype 与边界校验从源码可见严格的输入校验box.pydtype 必须为整数i、无符号整数u、浮点f或布尔b类型之一否则抛ValueError若low与high均为 ndarray形状必须一致若shape与low/high同时给出形状必须匹配所有low[i] high[i]否则抛ValueError边界值不允许为np.nan边界越出 dtype 表示范围如low dtype_min或high dtype_max时抛ValueError无符号整数与布尔 dtype不支持±np.inf边界有符号整数 dtype 遇到±np.inf时会被替换为 dtype 的极值。提示当 dtype 为整数类型时Box本质上就是一个离散空间例如图像像素Box(0, 255, shape(H, W, 3), dtypenp.uint8)。2.3 sample按区间形式选择分布的向量化抽样Box.sample(maskNone, probabilityNone)目前不支持任何掩码传入即抛gym.error.Errorbox.py。抽样策略按每个维度的区间形式自动选择分布向量化实现box.py区间形式抽样分布$[a, b]$均匀分布uniform$[a, \infty)$平移指数分布shifted exponential$(-\infty, b]$平移负指数分布shifted negative exponential$(-\infty, \infty)$正态分布normal整数与布尔 dtype 的样本会先np.floor再裁剪到 dtype 范围避免下溢/上溢对np.int64还做了额外的精度保护浮点无法精确表示 int64 极值见 box.py。 obs_space Box(low-1.0, high1.0, shape(3,), dtypenp.float32, seed42) obs_space.sample() array([ 0.77395606, -0.345801 , 0.9263729 ], dtypefloat32)2.4 is_bounded判断盒子的有界性is_bounded(mannerboth)返回盒子是否在某种意义上有界box.pymannerboth默认所有维度上下界都有限mannerbelow所有维度下界有限mannerabove所有维度上界有限传入其他值抛ValueError。底层依赖构造时记录的bounded_below与bounded_above布尔数组-inf low/high inf逐元素判断。该方法是测试中验证空间性质的标准手段见 tests/spaces/test_box.py。 Box(0, 1, shape(2,)).is_bounded(both) True Box(0, np.inf, shape(2,)).is_bounded(above) False2.5 contains 与其他实用方法contains(x)要求x为 ndarray、dtype 可无损转换、形状一致且逐元素落在[low, high]内非 ndarray 输入会先尝试np.asarray转换并给出日志警告box.pyto_jsonable将一批样本转为listsample.tolist()from_jsonable再转回 dtype 一致的 ndarray__repr__当边界为全等标量时只显示标量如Box(-1.0, 2.0, (3, 4), float32)避免冗长输出__eq__比较形状、dtype 与np.allclose(low/high)不要求精确相等。三、Discrete有限整数集Discrete表示形如 ${a, a1, \dots, an-1}$ 的有限整数子集是最典型的离散动作空间如 CartPole 的推左/推右、Acrobot 的 3 个力矩档位。3.1 构造参数Discrete(n, seedNone, start0, dtypenp.int64)参数类型说明n正整数元素个数必须为正否则抛ValueErrorstart整数最小元素默认0discrete.pydtype整数类型样本类型如int、np.int64、np.int32、np.uint8默认np.int64必须为整数类型否则抛TypeError注意n与start均须为整数类型否则抛TypeError源码中通过np.issubdtype(type(n), np.integer)校验。 from gymnasium.spaces import Discrete Discrete(2, seed42) # {0, 1} Discrete(2) Discrete(2, seed42).sample() np.int64(0) Discrete(3, start-1, seed42) # {-1, 0, 1} Discrete(3, start-1) Discrete(3, start-1, seed42).sample() np.int64(-1) Discrete(3, seed37, dtypenp.int32) # 指定 dtype Discrete(3, dtypeint32)3.2 sample掩码与概率抽样Discrete.sample(maskNone, probabilityNone)支持三种抽样模式discrete.py且mask与probability不能同时传入均匀抽样默认start np_random.integers(n)二元掩码抽样mask为形状(n,)、dtypenp.int8的数组1表示合法、0表示非法若全部为0无合法动作返回start作为兜底值概率掩码抽样probability为形状(n,)、dtypenp.float64的数组每个值在[0, 1]且总和必须为 1否则断言失败。 space Discrete(3, start-1, seed42) # 掩码只允许索引 2 对应的元素即 1 space.sample(masknp.array([0, 0, 1], dtypenp.int8)) np.int64(1) # 概率以 30% / 70% 抽样 space.sample(probabilitynp.array([0.0, 0.3, 0.7], dtypenp.float64)) np.int64(1)掩码抽样是动作屏蔽action masking技术的基础当某个动作在当前状态下不可行时用掩码将其排除。仓库教程 action_masking_taxi.py 展示了在 Taxi 环境中的完整实战用法。3.3 contains、比较与序列化contains(x)仅接受标量int或 0 维整数 ndarray要求start x start n且 dtype 可安全转换discrete.py__eq__n、start、dtype三者全部相等才相等to_jsonable转 Pythonint列表from_jsonable转回 dtype 标量__setstate__加载旧 pickle 时若缺少start字段自动补np.int64(0)保证向后兼容discrete.py。四、MultiBinaryn 维二进制数组空间MultiBinary的元素是固定形状的 0/1 二进制数组适合表示按键、开关、位向量等如 Atari 中的多个按键组合。元素 dtype 固定为np.int8。4.1 构造参数MultiBinary(n, seedNone)n可以是单个整数一维空间如MultiBinary(5)序列/数组多维空间如MultiBinary([3, 2])各维计数必须为正否则抛ValueError。 from gymnasium.spaces import MultiBinary MultiBinary(5, seed42) MultiBinary(5) MultiBinary(5, seed42).sample() array([1, 0, 1, 0, 1], dtypeint8) MultiBinary([3, 2], seed42) MultiBinary([3, 2]) MultiBinary([3, 2], seed42).sample() array([[1, 0], [1, 0], [1, 1]], dtypeint8)4.2 sample掩码语义更丰富的三种模式MultiBinary.sample(maskNone, probabilityNone)multi_binary.py默认逐元素独立公平抛硬币——np_random.integers(0, 2)二元掩码dtype 为np.int8、形状等于空间形状取值只能为0强制采样 0、1强制采样 1或2随机抛硬币概率掩码dtype 为np.float64、形状等于空间形状每个元素表示该位置为 1 的概率[0, 1]内逐元素伯努利抽样。 space MultiBinary(4, seed42) mask np.array([1, 0, 2, 2], dtypenp.int8) # 前两位固定后两位随机 space.sample(maskmask) array([1, 0, 1, 0], dtypeint8)contains(x)接受 ndarray 或可转数组的序列要求形状一致且所有元素为 0 或 1multi_binary.py。测试覆盖见 tests/spaces/test_multibinary.py。五、MultiDiscrete多个 Discrete 的笛卡尔积MultiDiscrete表示任意多个Discrete空间的笛卡尔积非常适合游戏手柄、键盘等“多个独立离散动作”的场景。5.1 构造参数MultiDiscrete(nvec, dtypenp.int64, seedNone, startNone)参数类型说明nvec整数列表或数组每个分类变量的取值个数也支持多维数组空间有多轴dtype整数类型必须为整数类型否则抛ValueErrorstart数组可选每个分类变量的起始值须与nvec形状一致默认全 0seedint/Generator可选nvec各维计数必须为正multi_discrete.py。仓库文档给出的经典例子multi_discrete.pyNintendo 手柄可抽象为 3 个离散空间——方向键Discrete(5)NOOP/上/右/下/左、按键 ADiscrete(2)、按键 BDiscrete(2)即MultiDiscrete([5, 2, 2])一次样本可能是array([3, 1, 0])。 from gymnasium.spaces import MultiDiscrete import numpy as np MultiDiscrete([5, 2, 2], seed42).sample() array([4, 0, 1]) # 多维 nvec空间本身可以有多个轴 MultiDiscrete(np.array([[1, 2], [3, 4]]), seed42).sample() array([[0, 0], [2, 2]])5.2 sample按每个动作位点分别掩码MultiDiscrete.sample(maskNone, probabilityNone)multi_discrete.py默认random * nvec start逐位点均匀抽样掩码mask为元组每个位点对应一个(n_i,)的np.int8数组某位点掩码全 0 时返回该位点的start值概率同样为元组每个位点对应np.float64数组值在[0, 1]且总和为 1。内部通过递归的_apply_mask处理多维情况multi_discrete.py支持任意轴深度的空间。5.3 索引、长度与 contains__getitem__(index)提取子空间——标量索引返回Discrete切片返回MultiDiscrete并共享 RNG 状态multi_discrete.py__len__返回len(nvec)对多维空间会给出日志警告contains(x)接受 ndarray 或序列要求形状一致、dtype 可转换且start x start (nvec - 1)逐元素成立实现特意避免减法运算可能导致的整数溢出multi_discrete.py。 space MultiDiscrete([5, 2, 2], seed42) space[0] Discrete(5) space[1:] # 切片返回 MultiDiscrete MultiDiscrete([2 2])六、Text受限字符集的字符串空间Text表示由给定字符集charset构成的字符串常用于语言类任务、指令生成、文本观测等。元素是 Pythonstr。6.1 构造参数Text(max_length, *, min_length1, charsetalphanumeric, seedNone)参数类型说明max_length整数字符串最大长度字符数必填min_length整数最小长度默认1防止空字符串须非负且 max_lengthcharsetset/frozenset/str字符集默认小写大写英文字母与 0-9 数字每个元素必须是单字符否则抛ValueErrorseedint/Generator可选源码示例text.py from gymnasium.spaces import Text import string Text(5) # 长度 1~5默认字符集 Text(1, 5, charset0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz) Text(min_length1, max_length10, charsetstring.digits) # 纯数字 Text(1, 10, charset0123456789)实现细节传入set/frozenset时会对字符排序以保证跨进程抽样、掩码与展平的一致性传入字符串时按给定顺序去重保留text.py。每个字符都有唯一索引character_index(char)供展平与掩码使用。6.2 sample长度与字符的双重控制Text.sample(maskNone, probabilityNone)的掩码为二元组(length, char_mask)text.pylength期望的字符串长度须在[min_length, max_length]内不传则随机选取char_mask长度为len(character_set)的np.int8数组掩码模式或np.float64数组概率模式字符掩码全 0 时若min_length 0返回空字符串否则抛ValueError无法构造合法样本概率模式下各概率值须在[0, 1]且总和为 1。 space Text(min_length1, max_length3, charsetabc, seed42) space.sample() cb space.sample(mask(3, np.array([1, 0, 0], dtypenp.int8))) # 固定长度 3、只允许字符 a aaacontains(x)要求x是字符串、长度在[min_length, max_length]内、且所有字符都属于字符集text.py。测试覆盖见 tests/spaces/test_text.py。七、基础空间的通用能力与选择指南7.1 所有基础空间共享的能力随机可复现seed(seed)或构造时传入seed配合 gymnasium/utils/seeding.py 的SeedSequencePCG64实现可保证采样序列完全可复现测试中通过多次抽样比对验证test_seed_reproducibility成员校验x in space等价于space.contains(x)掩码/概率抽样除Box外其余四个空间均支持掩码或概率抽样二者互斥用于动作屏蔽、受限抽样等场景序列化to_jsonable/from_jsonable支持与 JSON 数据互转展平五个基础空间的is_np_flattenable均为True可通过 gymnasium/spaces/utils.py 的flatten/flatten_space/unflatten/flatdim与Box互转便于接入神经网络输入。7.2 选型速查场景推荐空间示例连续向量观测/动作BoxCartPole 观测、MuJoCo 关节角单维离散动作DiscreteCartPole 左右推、Acrobot 力矩0/1 位向量、多按键MultiBinary游戏按键组合多个独立离散变量MultiDiscrete手柄方向键按钮字符串/文本Text文本观测、指令生成7.3 常见陷阱Box的dtype不能为None整数 dtype 下它是离散空间注意边界范围与抽样分布差异Discrete与MultiDiscrete的n/nvec必须为正start默认 0且部分环境 wrapper 假定 0 表示 NOOP 动作multi_discrete.pymask与probability不能同时传入且对 dtype、形状有严格断言Box不支持掩码抽样调用会直接抛错Text的charset元素必须是单字符否则样本会超出max_length并被contains拒绝。五个基础空间加上 组合空间Tuple、Dict、Sequence等构成了 Gymnasium 空间体系的完整拼图。理解它们的行为与边界是编写正确、健壮、可复现的强化学习环境的必要前提。【免费下载链接】GymnasiumA standard API for single-agent reinforcement learning environments, with popular reference environments and related utilities (formerly Gym)项目地址: https://gitcode.com/GitHub_Trending/gy/Gymnasium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表