使用强化学习训练神经网络玩俄罗斯方块

一、说明
在 2024 年暑假假期期间,Tim学习并应用了Q-Learning (一种强化学习形式)来训练神经网络玩简化版的俄罗斯方块游戏。在本文中,我将详细介绍我是如何做到这一点的。我希望这对任何有兴趣将强化学习应用于新领域的人有所帮助!
正如您在下面的 GIF 中看到的,经过约 6,000 场游戏或约 85,000 次单独动作的训练后,该模型成功“学会”了如何有效且高效地玩简化的俄罗斯方块游戏:

二、游戏
为了在尽可能简单的游戏环境中演示 Q-Learning 的过程,我使用了俄罗斯方块游戏的一个非常简化的版本。“棋盘”是 4 行 4 列,一个 4x4 矩阵。游戏非常简单:AI 代理必须选择将单个框逐一“放入”4 列中的哪一列,目标是最终填满棋盘上的所有 16 个方格。
尽管这个游戏对你我来说似乎非常简单易玩,但实际上有很多可能出错的地方。如果人工智能无法学习游戏的本质,它就会不断进行随机操作,最终做出非法操作。
例如,考虑以下情况:

如果模型不理解游戏,而是随机玩游戏,则有 25% 的概率它会选择将一个方块放入第 4 列(最右边的列)。这将是一个非法举动,使游戏无效,并且不允许 AI 达到 16 分的 100% 得分!
我训练这个模型的目标是让模型有效、高效地玩游戏,避免非法动作,并在每场比赛中达到最高分 16 分。
三、方法:Q 学习
为了训练 AI 玩这个简化版的俄罗斯方块游戏,我们将使用Q-Learning。Q -Learning 是机器学习中的一种强化学习算法。Q-Learning 的目标是找到任何潜在游戏状态的最佳动作选择策略。但这是什么意思呢?
在深入研究 Q-Learning 方法之前,让我们首先了解什么是“Q-Table”,因为这是 Q-Learning 中的一个核心概念。
您可以将 Q 表视为系统记录和存储的长列表(表格),该列表映射了在任何给定情况下它选择的任何可能的下一步行动将带来的奖励。例如,请考虑下表:

使用上面的 Q 表,系统可以通过查看该状态下每个潜在下一步行动的值来“查找”游戏任何状态下的最佳下一步行动(游戏状态在这里用两个整数表示,这是一种非常简单的表示)。例如,对于状态 (2,1),放入第 2 列将是下一个最佳行动,因为这将导致预期奖励为0.5,这是此位置所有可能动作中的最高值。
通过反复玩游戏,最终系统可以从游戏的每个潜在状态中玩出每个潜在动作!一旦它做到了这一点,它就会有一个词汇表,记录在游戏的任何场景中哪些动作是最佳选择。唯一的挑战是,在绝大多数游戏中,潜在场景的数量实在是太多了。在大多数游戏中,有数百万、数十亿甚至数万亿个潜在的独特状态。存储如此长的表格是不可能的。而要玩完所有这些例子?那将花很长时间!
因为 Q 表太大,无法收集和存储,所以我们求助于神经网络。神经网络的规模要小得多,通过观察游戏过程和收集奖励,可以学习游戏中的潜在模式。这些模式使神经网络能够理解和估计与某些位置的某些动作相关的奖励,而无需存储表格;这很像我们人类的学习方式!实际上,该模型正在学习模拟“Q 表”。
当我们建立一个模型并通过 Q-Learning 进行训练时,我们会反复让模型通过自我对弈来遇到、行动和观察。换句话说,在游戏的每个“步骤”中,游戏的当前情况(模型必须对此做出决定)称为状态。模型看到状态,然后决定下一步应该怎么做;这一举动称为动作。在对游戏执行选定的动作(动作)后,模型会观察发生了什么——这一举动是否让情况变得更好?更糟?这被称为奖励。
该模型会自己反复玩游戏……数千次!最终,该模型收集了如此多的状态、动作、奖励对(称为“经验”),以至于它可以从这些经验中学习,并充分了解哪些状态下的哪些动作会带来最高奖励(最成功)。
四、神经网络模型
TensorFlow顺序神经网络将用于估计上述给定位置中每个潜在移动的估计奖励。我使用Keras API 使神经网络的高级操作更容易。
如上所述,每次要求模型决定下一步该怎么做时,都会向其呈现游戏的当前“状态”。这是对游戏整体情况的简单表示,包括模型在决定下一步做什么时应考虑的所有标准。
在这个迷你俄罗斯方块游戏中,“状态”非常简单:4x4 棋盘上有 16 个方格,因此有 16 个唯一输入。16 个输入中的每一个都将被表示并“显示”给模型,即1或0;如果特定方格已被占用,则该方格的位置将表示为1,如果为空,则表示为0。
例如,考虑以下棋盘状态:

上图中的棋盘状态可以表示为以下整数数组,其中每个方格表示为0或1,其中每个方格在数组中的位置如上图所示:
[0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1 ]
因此,我们的神经网络在评估位置和下一步要走什么时会考虑16 个输入。那么输出呢?在 Q-Learning 中,神经网络旨在预测任何给定状态下每个可能动作的“Q 值”或估计的当前/未来奖励。由于我们正在玩的游戏有4 个潜在动作(在第 1、2、3 或 4 列中放置一个方块),我们的神经网络将有4 个输出。
我们的神经网络还会有多个隐藏层,它们是连接输入层和输出层的数学神经元层。这些隐藏层充当神经网络的“大脑”,通过训练不断调整以“学习”游戏的性质以及状态、动作及其相关奖励之间的关系。
以下是构建整个模型所使用的代码:
# 构建层
input_board = keras.layers.Input(shape=( 16 ,), name= "input_board" )
carry = keras.layers.Dense( 64 , "relu" , name= "layer1" )(input_board)
carry = keras.layers.Dense( 64 , "relu" , name= "layer2" )(carry)
carry = keras.layers.Dense( 32 , "relu" , name= "layer3" )(carry)
output = keras.layers.Dense( 4 , "linear" , name= "output" )(carry) #构建模型
self.model = keras.Model(inputs=input_board, output=output)
self.model.compile (optimizer=keras.optimizers.Adam(learning_rate= 0.003 ), loss= "mse" )
要查看构建和训练神经网络的代码,请在GitHub 上查看。要了解如何将游戏状态转换为扁平整数数组表示形式,请在此处查看该转换函数。
五、奖励函数
如上所述,神经网络旨在从游戏的任何给定状态近似每个潜在动作的Q 值。“Q 值”只是当前和未来奖励的混合体(即“从短期和长期来看,这一举动对我有多大帮助?”)的花哨术语。如果模型能够从任何状态近似所有四种可能动作的奖励,那么该模型可以简单地选择它认为将返回最大奖励的动作作为建议的下一个最佳动作。
但是,模型如何从本质上知道哪些动作是“好的”,哪些动作“不太好”,哪些动作是“坏的”?这就是我们作为设计此过程的人需要为 AI 代理提供一些指导的地方。这种指导称为奖励函数。
简而言之,奖励函数只是一个简单的函数,我们将编写它来以数学方式计算任何潜在举动的好坏。请记住,对于人工智能做出的每一个举动,它都会观察它做出这一举动所获得的奖励。我们定义了一个高级函数,可以粗略地计算出这一举动是好是坏。
我对这个迷你俄罗斯方块 AI 使用的奖励函数非常简单,可以在模块中的类score_plus()中的函数中找到:GameState类在tetris
def score_plus(self) -> float:# start at scoreToReturn:float = float(self.score())# penalize for standard deviationstdev:float = statistics.pstdev(self.column_depths())ToReturn = ToReturn - (stdev * 2)return ToReturn
首先,我已将系统设置为仅根据移动后和移动前的“score_plus”之间的差异来确定奖励。换句话说,score_plus模型在移动之前观察,移动,然后再次观察score_plus,差异(增加)即为奖励。
我的奖励函数非常简单。首先,score统计游戏的分数——这只是棋盘上被占据的方格数。之后,我使用一个简单的标准偏差函数来计算“列深度”的偏差,或者每列有多少个方格未被占据。
标准差越大,意味着棋盘的开发方式非常不平衡 — 即一边很高,而另一边不高;这对于俄罗斯方块游戏来说并不好。非常“水平”的棋盘反而等同于较小的标准差。通过从总分中减去柱深标准差,我们可以惩罚模型构建不均匀、不平衡的棋盘,从而激励构建平衡的棋盘。
六、训练过程
在我们建立好底层模型并建立奖励函数后,现在是时候训练模型了!如前所述,模型将自行运行,自己反复玩游戏。它将从零开始了解如何玩游戏 — 只是能够观察游戏、做出决定并查看该决定获得的奖励。
通过反复进行自我游戏并根据这些结果进行训练,神经网络最终形成了棋盘当前状态、可能做出的潜在决策以及此类决策的典型奖励之间的关系。一旦巩固了这种理解,尽可能地玩游戏就很简单了;我们所要做的就是始终选择模型预期会获得最大回报的移动(动作)!
更具体地说,以下是精简的训练过程。完整的训练脚本可以在train.py中找到。
- 初始化一个新的神经网络。
- 通过选择模型认为最佳的动作组合来收集几百种状态、动作和奖励经验(
- 将当前游戏的状态转换为整数列表。
- 根据模型认为最好的选择一种动作(但可能不是,因为模型还不知道任何事情!)或随机动作。偶尔会选择随机动作来鼓励探索。在此处阅读有关探索与开发的更多信息。
- 执行(玩)该动作并观察该动作所给予的奖励。
- 将此状态、动作、奖励“体验”存储到一个集合中。
- 循环遍历所有这些收集到的状态、动作和奖励经验,每次根据经验进行训练(更新神经网络权重),以便在给定状态和动作的情况下更好地近似正确的奖励。
- 计算 Q 值(即时/未来奖励)应该是多少(即时/未来奖励的混合,代表该决策的总奖励)。
- 要求模型预测它认为的奖励(Q 值)是什么。
- 该模型的预测可能不正确,因为它还不知道任何事情。
- 通过根据步骤 1 中计算的正确 Q 值进行训练来“纠正”模型。
- 对每一次经历都反复这样做。
- 反复重复上述步骤,直到模型学会如何有效、合法地玩游戏!
在此处查看 GitHub 上的完整训练脚本。
七、结果
在train.py模块中设置好上述训练过程后,我让它运行了大约 4 个小时。在这 4 个小时里,经过 85,000 个状态、动作和奖励体验的训练后,我的模型成功学会了完美地玩游戏。该模型可以从任何状态完美地玩游戏——从新的游戏位置(空白板)甚至“随机”位置。每次玩游戏时,它总是在每场“游戏”中得分 16(满分),并且从不做出非法举动。
我的模型经过了 85,000 次经验(移动)的训练,但我认为没有必要训练这么多。正如训练日志文件中显示的那样,最佳性能似乎在 4,500 次经验(移动)标记附近实现。
您可以从下面的模型检查点部分下载我训练的模型,并在assess.py脚本中运行它。

附代码
该项目的所有代码均为开源,https://github.com/TimHanewich/tetris-ai-mini
相关文章:
使用强化学习训练神经网络玩俄罗斯方块
一、说明 在 2024 年暑假假期期间,Tim学习并应用了Q-Learning (一种强化学习形式)来训练神经网络玩简化版的俄罗斯方块游戏。在本文中,我将详细介绍我是如何做到这一点的。我希望这对任何有兴趣将强化学习应用于新领域的人有所帮助…...
java中的日期处理:只显示日期,不显示时间的两种处理方式
需要记录某个操作的操作时间,数据库中该字段为DATE类型; 插入数据的时候,使用数据库函数NOW()获取当前日期并插入: <insert id"batchInsertOrgTestersByProjectId">insert into project_org_testers(project_un…...
腾讯云AI代码助手编程挑战赛——贪吃蛇小游戏
作品介绍 贪吃蛇小游戏需要控制蛇的移动方向,使其吃掉地图上随机出现的食物,每吃掉一个食物,蛇的身体就会增长一格,是一款老少皆宜的小游戏,我们可以用腾讯ai助手生成全部代码,简单方便快捷。 技术架构 …...
水水水水水
为了拿推广卷,但不想把我原本完整的文章拆成零散的多篇,只能出此下策随便发一篇,认真写的都笔记专栏里 5G与未来网络 5G技术一直是近几年讨论的热点。它不仅仅是提升手机上网速度,更是对万物互联(IoT)的一次…...
Spring整合SpringMVC
目录 【pom.xml】文件; 新建【applicationContext.xml】文件 新建【springmvc.xml】文件; 配置【src/main/webapp/WEB-INF/web.xml】文件; 新建【com.gupaoedu.service.IUserService】; 新建【com.gupaoedu.service.impl.Use…...
【Rust自学】10.4. trait Pt.2:trait作为参数和返回类型、trait bound
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 说句题外话,写这篇的时间比写所有权还还花的久,trait是真的比较难理解的概念。 10.4.1. 把trait作为参数 继续以…...
嵌入式系统 (2.嵌入式硬件系统基础)
2.嵌入式硬件系统基础 2.1嵌入式硬件系统的组成 嵌入式硬件系统以嵌入式微处理器为核心,主要由嵌入式微处理器、总线、存储器、输入/输出接口和设备组成。 嵌入式微处理器 嵌入式微处理器采用冯诺依曼结构或哈佛结构:前者指令和数据共享同一存储空间…...
Linux 下 Vim 环境安装踩坑问题汇总及解决方法(重置版)
导航 安装教程导航 Mamba 及 Vim 安装问题参看本人博客:Mamba 环境安装踩坑问题汇总及解决方法(初版)Linux 下Mamba 及 Vim 安装问题参看本人博客:Mamba 环境安装踩坑问题汇总及解决方法(重置版)Windows …...
OpenAI 故障复盘 - 阿里云容器服务与可观测产品如何保障大规模 K8s 集群稳定性
本文作者: 容器服务团队:刘佳旭、冯诗淳 可观测团队:竺夏栋、麻嘉豪、隋吉智 一、前言 Kubernetes(K8s)架构已经是当今 IT 架构的主流与事实标准(CNCF Survey[1])。随着承接的业务规模越来越大,用户也在使…...
安卓触摸对焦
1. 相机坐标说明 触摸对焦需要通过setFocusAreas()设置对焦区域,而该方法的参数的坐标,与屏幕坐标并不相同,需要做一个转换。 对Camera(旧版相机API)来说,相机的坐标区域是一个2000*2000,原点…...
jupyter出现“.ipynb appears to have died. It will restart automatically.”解决方法
原因 解决方法:更新jupyter的版本 1.打开anaconda prompt 2、更新jupyter版本 在anaconda prompt输入以下指令 conda update jupyter如图:...
20250108-实验+神经网络
实验3. 神经网络与反向传播算法 3.1 计算图:复合函数的计算图 实验要求1:基于numpy实现 ( y 1 , y 2 ) f ( x 1 , x 2 , x 3 ) (y_1,y_2) f(x_1,x_2,x_3) (y1,y2)f(x1,x2,x3) 的反向传播算法(不允许使用自动微分)&a…...
【权限管理】CAS(Central Authentication Service)
CAS(Central Authentication Service)是一种广泛应用的 单点登录(SSO) 协议,它允许用户在一个集中式的身份验证系统中登录一次后,便可以无缝访问多个应用系统,而无需重复登录。CAS 通过统一的身…...
Golang笔记:使用net包进行TCP监听回环测试
文章目录 前言TCP监听回环代码演示 附:UDP监听回环 前言 TCP是比较基础常用的网络通讯方式,这篇文章将使用Go语言实现TCP监听回环测试。 本文中使用 Packet Sender 工具进行测试,其官网地址如下: https://packetsender.com/ TC…...
《浮岛风云》V1.0中文学习版
《浮岛风云》中文版https://pan.xunlei.com/s/VODadt0vSGdbrVOBEsW9Xx8iA1?pwdy7c3# 一款有着类似暗黑破坏神的战斗系统、类似最终幻想的奇幻世界和100%可破坏体素环境的动作冒险RPG。...
Day10——爬虫
爬虫概念 网络请求 爬虫分类 基本流程 请求头...
10. C语言 函数详解
本章目录: 前言1. C 语言函数概述1.1 函数的定义与结构1.2 函数声明1.3 函数调用 2. 函数参数传递2.1 传值调用2.2 传引用调用(模拟)2.3 引用调用(C 特性) 3. 内部函数与外部函数3.1 内部函数3.2 外部函数3.3 示例:多个…...
NRC优先级中比较特殊的—NRC0x13和NRC0x31
1、基础知识 大家都了解 NRC0x13,表示长度错误和格式错误 NRC0x31,表示DID不支持和数据格式不支持 2、为什么说这两个NRC比较特殊 看下图的标注部分: 2.1、先看NRC0x13 步骤一:仔细看是先判断Minmun Length Check ࿰…...
ref() 和 reactive() 区别
ref() 和 reactive() 都是 Vue 3 中用于创建响应式数据的方法,但它们之间存在一些关键差异。 首先,ref() 用于创建响应式的标量值,比如数字、字符串、布尔值等基本数据类型,以及对象和数组等复杂数据类型。当你使用 ref() 时&…...
深度学习与计算机视觉 (博士)
文章目录 零、计算机视觉概述一、深度学习相关概念1.学习率η2.batchsize和epoch3.端到端(End-to-End)、序列到序列(Seq-to-Seq)4.消融实验5.学习方式6.监督学习的方式(1)有监督学习(2)强监督学习(3)弱监督学习(4)半监督学习(5)自监督学习(6)无监督学习(7)总结:不同…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
