OpenSpiel 观测张量布局(observation_tensor_layout)详解:CHW / HWC 约定与张量解释实战
人工智能强化学习深度学习【免费下载链接】open_spielOpenSpiel is a collection of environments and algorithms for research in general reinforcement learning and search/planning in games.项目地址https://gitcode.com/gh_mirrors/op/open_spiel点击查看免费下载在 OpenSpiel 中game.observation_tensor_layout()用于查询每个游戏观测张量observation tensor的维度排列约定是正确解读state.observation_tensor()返回的扁平向量、并将其重塑为神经网络输入的关键一步。本文以 docs/api_reference/game_observation_tensor_layout.md 为核心结合源码open_spiel/spiel.h、open_spiel/spiel_globals.h与集成测试 playthrough 数据系统讲解 CHW 与 HWC 两种布局的区别、查询方法、如何与 shape/size 配套使用以及如何在新游戏或模型代码中正确处理布局信息。一、核心概念什么是观测张量布局OpenSpiel 的观测系统把游戏状态编码为张量形式tensor-like format其设计初衷是直接服务于强化学习与神经网络实验。与信息状态张量information state tensor类似观测张量的实际内容在 C 底层State::ObservationTensor和 Python 侧state.observation_tensor()都是以一维扁平向量1-D vector返回的这一点在 open_spiel/spiel.h 的注释中有明确说明the actual observation is returned in a 1-D vector byState::ObservationTensor— see the documentation of that function for details of the data layout.因此要正确使用观测数据必须同时拿到三样东西形状shapegame.observation_tensor_shape()返回各维度大小组成的整数列表布局layoutgame.observation_tensor_layout()返回维度排列顺序是CHW还是HWC大小sizegame.observation_tensor_size()返回扁平向量的总元素数即各维度大小的乘积。observation_tensor_layout()正是回答扁平向量中每个位置对应哪个维度索引这个问题的接口它返回的取值定义在 open_spiel/spiel_globals.h// Layouts for 3-D tensors. For 2-D tensors, we assume that the layout is a // single spatial dimension and a channel dimension. If a 2-D tensor should be // interpreted as a 2-D space, report it as 3-D with a channel dimension of // size 1. We have no standard for higher-dimensional tensors. enum class TensorLayout { kHWC, // indexes are in the order (height, width, channels) kCHW, // indexes are in the order (channels, height, width) };这段源码注释还澄清了两个容易被忽视的约定2-D 张量约定按单一空间维度 通道维度解释如果某个 2-D 张量本意是一个 2-D 空间应把它表示为带size 1通道维度的 3-D 张量更高维张量OpenSpiel 目前没有定义更高维度的标准布局。二、CHW 与 HWC两种布局的语义与区别在 Python 绑定中该枚举通过 pybind11 暴露为pyspiel.TensorLayout见 open_spiel/python/pybind11/pyspiel.ccpy::enum_open_spiel::TensorLayout(m, TensorLayout) .value(HWC, open_spiel::TensorLayout::kHWC) .value(CHW, open_spiel::TensorLayout::kCHW);两种布局的索引顺序分别为布局索引顺序说明TensorLayout.CHW(channels, height, width)通道维度在最外层空间维度在最后与多数深度学习框架如 PyTorch 的 NCHW 约定一致TensorLayout.HWC(height, width, channels)空间维度在前通道维度在最后与图像处理常见的 NHWC 约定一致默认值是 CHWGame基类的虚函数ObservationTensorLayout()默认返回TensorLayout::kCHWopen_spiel/spiel.h。从集成测试 playthrough 记录来看绝大多数游戏都沿用该默认值例如井字棋、围棋、五子棋、国际象棋等。需要特别指出的是绝大多数游戏返回 CHW但实际张量通常是 1-D 或 2-D 的此时布局只是名义约定见下文第三节。真正以 3-D 张量返回观测的游戏其维度顺序才需要严格对照布局解读。目前仓库源码中显式覆盖并返回TensorLayout::kCHW的游戏包括 open_spiel/games/go/go.h 和 open_spiel/games/phantom_go/phantom_go.h 等仓库内尚无返回kHWC的游戏实例。三、配套接口shape 与 size 的组合使用原文档明确指出observation_tensor_layout()的用途是在根据game.observation_tensor_shape()给定的形状解读state.observation_tensor()返回的扁平向量时确定维度顺序。因此它必须与下面两个接口配套理解详见 docs/api_reference/game_observation_tensor_shape_size.mdobservation_tensor_shape()返回观测张量各维度大小的整数列表observation_tensor_size()返回观测张量所需扁平向量的总元素数。这两个接口在 open_spiel/spiel.h 中的实现如下virtual std::vectorint ObservationTensorShape() const { SpielFatalError(ObservationTensorShape unimplemented.); } virtual TensorLayout ObservationTensorLayout() const { return TensorLayout::kCHW; } // The size of the (flat) vector needed for the observation tensor-like format. int ObservationTensorSize() const { std::vectorint shape ObservationTensorShape(); return shape.empty() ? 0 : absl::c_accumulate(shape, 1, std::multipliesint()); }可见ObservationTensorSize()就是 shape 各维度值的连乘积shape 为空时为 0。三者的关系可以总结为observation_tensor_size() prod(observation_tensor_shape())四、实战示例一Leduc Poker 的 1-D 观测原文档给出的示例是 Leduc Poker。下面逐行验证其输出并补充更完整的可运行脚本import pyspiel game pyspiel.load_game(leduc_poker) print(game.observation_tensor_layout()) # TensorLayout.CHW print(game.observation_tensor_shape()) # [16]以默认参数2 人、suit_isomorphism加载时Leduc 的观测张量是一维的长度为 16布局名义上为 CHW。这个形状由 open_spiel/games/leduc_poker/leduc_poker.cc 计算得到std::vectorint LeducGame::ObservationTensorShape() const { // One-hot encoding for player number (who is to play). // 2 slots of cards (total_cards_ bits each): private card, public card // Followed by the contribution of each player to the pot if (suit_isomorphism_) { return {(num_players_) (total_cards_) (num_players_)}; } else { return {(num_players_) (total_cards_ * 2) (num_players_)}; } }即 2轮到谁行动的 one-hot 6total_cards_ 6两轮卡牌槽位 2两名玩家各自的底池贡献16。这些编码段在扁平向量中按声明顺序依次排列解读时可参考 open_spiel/games/leduc_poker/leduc_poker.h 中的接口声明。再看完整的三接口组合用法import pyspiel game pyspiel.load_game(leduc_poker) state game.new_initial_state() layout game.observation_tensor_layout() # TensorLayout.CHW shape game.observation_tensor_shape() # [16] size game.observation_tensor_size() # 16 print(layout, shape, size) print(state.observation_tensor()) # 16 个元素的扁平向量注意对于 1-D 观测向量[16]只有一个维度CHW 只是名义上的布局值不存在实际的 H/W/C 拆分。五、实战示例二Tic-Tac-Toe 的真 3-D 观测与 Leduc 不同井字棋tic_tac_toe的观测是真正的 3-D 张量此时布局才有实际的索引语义。playthrough 记录 open_spiel/integration_tests/playthroughs/tic_tac_toe.txt 给出的基准输出为ObservationTensorShape() [3, 3, 3] ObservationTensorLayout() TensorLayout.CHW ObservationTensorSize() 27即 shape 为(channels3, height3, width3)。其中 3 个通道分别表示X 棋子位置、O 棋子位置、空位每个通道是一张 3×3 的棋盘平面。这与 playthrough 中打印的观测张量可视化一致三个 3×3 平面并排显示见同一文件的ObservationTensor(0)段落。对应 Python 代码import pyspiel game pyspiel.load_game(tic_tac_toe) print(game.observation_tensor_layout()) # TensorLayout.CHW print(game.observation_tensor_shape()) # [3, 3, 3] print(game.observation_tensor_size()) # 27 state game.new_initial_state() obs state.observation_tensor() # 长度为 27 的扁平向量 # 按 CHW 布局重塑为 (C, H, W) import numpy as np tensor np.array(obs).reshape(game.observation_tensor_shape()) # tensor[0] X 平面, tensor[1] O 平面, tensor[2] 空位平面如果某个游戏的布局是 HWC则应将扁平向量重塑为(H, W, C)。布局不同重塑的 reshape 顺序就不同——这就是为什么在写与具体游戏解耦的通用 RL 代码时必须动态读取observation_tensor_layout()而不是硬编码维度顺序。六、跨游戏视角从 playthrough 看布局的多样性OpenSpiel 的集成测试为每个注册游戏生成 playthrough 记录由 open_spiel/python/algorithms/generate_playthrough.py 自动输出ObservationTensorShape() / ObservationTensorLayout() / ObservationTensorSize()三行基准信息是查询任意游戏观测约定的最权威参考。以下是从 open_spiel/integration_tests/playthroughs 中抽取的几个典型例子游戏ShapeLayoutSize说明tic_tac_toe[3, 3, 3]CHW27真 3-DC3 通道对应 X/O/空amazons[4, 10, 10]CHW400真 3-D4 通道 × 10×10 棋盘antichess[16, 8, 8]CHW1024真 3-D16 通道 × 8×8 棋盘breakthrough[3, 8, 8]CHW192真 3-D3 通道 × 8×8 棋盘2048[4, 4]CHW162-D按单空间维 通道维解释catch[10, 5]CHW502-Dleduc_poker[16]CHW161-D纯扁平编码blackjack[189]CHW1891-D可以看到3-D 观测如 amazons、antichess、breakthrough通常对应通道平面叠加式的棋盘编码此时 CHW 布局决定重塑顺序至关重要2-D 观测如 2048、catch按源码注释约定解释为一个空间维度 通道维度1-D 观测如各种扑克、桥牌、21 点是纯扁平编码布局仅为名义值解读时只需按 shape 与文档化的分段布局展开。七、与信息状态张量布局的对照OpenSpiel 的 API 家族中还有一个孪生接口information_state_tensor_layout()open_spiel/spiel.h其默认值同样是kCHWPython 绑定见 open_spiel/python/pybind11/pyspiel.cc。二者的语义完全对称观测张量observation tensorstate.observation_tensor()的解读依据信息状态张量information state tensorstate.information_state_tensor()的解读依据仅当GameType.provides_information_state_tensor为 True 时可用。信息状态关注的是某玩家视角下的不完全信息如自己手里的牌 公共信息而观测张量通常对应全局状态的部分可观测编码。在设计算法时需要根据任务选择正确的张量类型并各自读取其 shape 与 layout。八、实践要点与排查建议通用代码务必动态查询不要假设所有游戏都是 CHW。虽然当前仓库中绝大多数游戏默认 CHW但布局是每个游戏可覆盖的虚函数写可复用的 RL/神经网络代码时应通过game.observation_tensor_layout()动态获取再按对应顺序 reshape。size 必须等于 shape 的连乘积game.observation_tensor_size()是扁平向量的长度也是len(state.observation_tensor())的期望值两者不一致通常说明游戏实现有误或参数不匹配。2-D / 3-D 的解释规则3-D 按(C, H, W)或(H, W, C)解读2-D 按单空间维 通道维解读更高维没有标准避免依赖未定义行为。查阅 playthrough 基准对任意游戏直接在 open_spiel/integration_tests/playthroughs 目录下打开对应game.txt前三行即给出权威的 shape / layout / size 基准输出。自定义新游戏时若观测编码是多通道棋盘务必在Game子类中同时实现ObservationTensorShape()与ObservationTensorLayout()保证二者自洽并用 playthrough 测试验证生成方式参考 open_spiel/python/algorithms/generate_playthrough.py。总结observation_tensor_layout()是 OpenSpiel 观测张量 API 中承上启下的关键接口它连接了扁平的一维返回向量与带维度的张量语义直接决定 reshape 的维度顺序。理解 CHW/HWC 约定、与observation_tensor_shape()/observation_tensor_size()的配套关系以及 1-D/2-D/3-D 观测各自的解释规则是在 OpenSpiel 中正确构建基于观测的强化学习与神经网络管线的必要前提。更多相关方法可参考 docs/api_reference.md 中的 Core API 文档。赞分享人工智能强化学习深度学习【免费下载链接】open_spielOpenSpiel is a collection of environments and algorithms for research in general reinforcement learning and search/planning in games.项目地址https://gitcode.com/gh_mirrors/op/open_spiel点击查看免费下载相关推荐OpenSpiel 张量布局TensorLayout完全指南解读 information_state_tensor_layout 与 CHW/HWC 语义OpenSpiel 张量布局TensorLayout完全指南解读 information_state_tensor_layout 与 CHW/HWC 语义人工智能强化学习深度学习TVM TIRx 张量布局Layout详解从 S/R/O 规格到 TMEM 与 SMEM 布局实战TVM TIRx 张量布局Layout详解从 S/R/O 规格到 TMEM 与 SMEM 布局实战 导读 TIRx 是 TVM 中面向现代加速器尤其是模型编译深度学习推理引擎3种方法彻底告别网易云音乐灰色歌曲解锁海外限制与版权屏障3种方法彻底告别网易云音乐灰色歌曲解锁海外限制与版权屏障 你是否也曾面对网易云音乐里那些灰色的歌曲列表感到无奈那些因为版权限制或地域封锁而无法播放的音乐就网络后端上一篇use-gesture依赖管理peerDependencies设置下一篇gh_mirrors/re/rebase安全配置指南保护代码仓库的5个关键步骤创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

用 ENTRYPOINT 封装命令行工具:udemy-docker-mastery 中 cmatrix 矩阵屏保镜像的构建实战

用 ENTRYPOINT 封装命令行工具:udemy-docker-mastery 中 cmatrix 矩阵屏保镜像的构建实战

示例工程 【免费下载链接】udemy-docker-mastery Docker Mastery Udemy course to build, compose, deploy, and manage containers from local development to high-availability in the cloud 项目地址: https://gitcode.com/gh_mirrors/ud/udemy-docker-mastery …

2026/10/12 1:37:53 阅读更多 →
Slang IR 参考索引导航:按家族检索 Slang IR 指令集、解读 opcode 溯源列

Slang IR 参考索引导航:按家族检索 Slang IR 指令集、解读 opcode 溯源列

编译器图形学编程语言 【免费下载链接】slang Making it easier to work with shaders 项目地址: https://gitcode.com/GitHub_Trending/sl/slang 点击查看 免费下载 本指南围绕 Slang 编译器的 IR 指令参考文档子树(docs/generated/design/ir-referenc…

2026/10/12 1:37:53 阅读更多 →
一条命令让 AI Agent 具备逆向工程能力:REA 快速上手

一条命令让 AI Agent 具备逆向工程能力:REA 快速上手

一条命令让 AI Agent 具备逆向工程能力:REA 快速上手 【免费下载链接】rea Reverse engineer anything with agents, from app behavior down to native binaries. 项目地址: https://gitcode.com/GitHub_Trending/rea2/rea REA(Reverse Engineer…

2026/10/12 1:36:52 阅读更多 →

最新新闻

【深度学习新浪潮】Meta Muse 智能体:它是什么?有哪些特点?为什么突然火了?

【深度学习新浪潮】Meta Muse 智能体:它是什么?有哪些特点?为什么突然火了?

1. 引言 近期,Meta Muse 智能体在 AI 领域引发广泛关注,开发者、创作者与科技从业者纷纷展开讨论。许多初次接触者不禁疑惑:这是 Meta 推出的又一款大模型?抑或仅是蹭热度的 AI 玩具? 事实并非如此。Meta Muse 是 Meta 在 AI 智能体方向的一次战略性布局,它并非简单的对…

2026/10/12 2:24:22 阅读更多 →
Spring-boot-3 -注解 yaml配置 -日志

Spring-boot-3 -注解 yaml配置 -日志

4、核心技能1. 常用注解SpringBoot 摒弃 XML 配置方式,改为全注解驱动1. 组件注册Configuration 自定义配置类、SpringBootConfiguration 用来标注SpringBoot主启动类的Bean 可以在自定义配置类面创建对象交给ioc容器,组件在容器中的名字为方法名、Scope…

2026/10/12 2:24:22 阅读更多 →
Neuroimage: 动态功能连接方法的重测信度比较

Neuroimage: 动态功能连接方法的重测信度比较

本篇文献发表在Neuroimage杂志。所发布内容旨在与大家分享学术新知,促进交流学习版权归原作者或原出处所有,感谢各位学者的辛勤付出与研究成果。1.引言大脑的功能组织具有丰富的时空结构,可以使用功能连接指标进行探测。功能连接被定义为两个…

2026/10/12 2:24:22 阅读更多 →
page_alloc __rmqueue

page_alloc __rmqueue

__rmqueue() 是伙伴系统分配路径的核心调度器。它在持有 zone->lock 的前提下,按照碎片化风险从低到高的顺序,依次尝试不同的分配策略,直到成功或彻底失败。核心作用与策略链它的本质是一个多级降级策略链:先尝试最“干净”的方…

2026/10/12 2:24:22 阅读更多 →
游戏引擎中物理步进与动画采样的同步机制解析

游戏引擎中物理步进与动画采样的同步机制解析

1. 这不是教科书,是我在三个项目里拆过七次引擎后写下的物理与动画系统手记“游戏引擎架构深度解析(三):物理与动画系统”——看到这个标题,你大概率正卡在某个角色落地时穿模、布料抖动像癫痫发作、或者刚加完一个新关…

2026/10/12 2:24:22 阅读更多 →
产业与汇率全景分析深入分析多表格形成一篇文章

产业与汇率全景分析深入分析多表格形成一篇文章

产业与汇率全景深度分析:汇率是外生变量,产业是底层根基引言汇率从来不是孤立的数字,它是一国产业竞争力、贸易结构、资本流动、宏观政策、全球供需格局共同定价的结果;反过来,汇率波动又会重塑产业成本、订单、利润、…

2026/10/12 2:23:21 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →