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

一、说明

        在 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 个输入中的每一个都将被表示并“显示”给模型,即10;如果特定方格已被占用,则该方格的位置将表示为1,如果为空,则表示为0

        例如,考虑以下棋盘状态:

上图中的棋盘状态可以表示为以下整数数组,其中每个方格表示为01,其中每个方格在数组中的位置如上图所示:

[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中找到。

  1. 初始化一个新的神经网络。
  2. 通过选择模型认为最佳的动作组合来收集几百种状态、动作和奖励经验(
  3. 将当前游戏的状态转换为整数列表。
  4. 根据模型认为最好的选择一种动作(但可能不是,因为模型还不知道任何事情!)或随机动作。偶尔会选择随机动作来鼓励探索。在此处阅读有关探索与开发的更多信息。
  5. 执行(玩)该动作并观察该动作所给予的奖励。
  6. 将此状态、动作、奖励“体验”存储到一个集合中。
  7. 循环遍历所有这些收集到的状态、动作和奖励经验,每次根据经验进行训练(更新神经网络权重),以便在给定状态和动作的情况下更好地近似正确的奖励。
  8. 计算 Q 值(即时/未来奖励)应该是多少(即时/未来奖励的混合,代表该决策的总奖励)。
  9. 要求模型预测它认为的奖励(Q 值)什么。
  10. 该模型的预测可能不正确,因为它还不知道任何事情。
  11. 通过根据步骤 1 中计算的正确 Q 值进行训练来“纠正”模型。
  12. 对每一次经历都反复这样做。
  13. 反复重复上述步骤,直到模型学会如何有效、合法地玩游戏!

在此处查看 GitHub 上的完整训练脚本。

七、结果

在train.py模块中设置好上述训练过程后,我让它运行了大约 4 个小时。在这 4 个小时里,经过 85,000 个状态、动作和奖励体验的训练后,我的模型成功学会了完美地玩游戏。该模型可以从任何状态完美地玩游戏——从新的游戏位置(空白板)甚至“随机”位置。每次玩游戏时,它总是在每场“游戏”中得分 16(满分),并且从不做出非法举动。

我的模型经过了 85,000 次经验(移动)的训练,但我认为没有必要训练这么多。正如训练日志文件中显示的那样,最佳性能似乎在 4,500 次经验(移动)标记附近实现。

您可以从下面的模型检查点部分下载我训练的模型,并在assess.py脚本中运行它。

附代码

该项目的所有代码均为开源,https://github.com/TimHanewich/tetris-ai-mini

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/66607.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大湾区经济网与澳门红刊杂志社签署战略合作

大湾区经济网澳门1月9日电(王强)2025年1月9日,在粤港澳大湾区建设稳步推进的时代背景下,大湾区经济网与澳门红刊杂志社成功签署了合作协议,标志着双方在媒体战略合作领域迈出了坚实的一步,将共同为粤港澳大…

力扣 二叉树的最大深度

树的遍历,dfs与bfs基础。 题目 注意这种题要看根节点的深度是0还是1。 深度优先遍历dfs,通过递归分别计算左子树和右子树的深度,然后返回左右子树深度的最大值再加上 1。递归会一直向下遍历树,直到达到叶子节点或空节点。在回溯…

Mac 安装psycopg2出错:Error:pg_config executable not found的解决

在mac 上执行pip3 install psycopg2-binary出现如下错误: Error:pg_config executable not found然后我又到终端里执行 brew install postgresql16 显示 Warning: You are using macOS 15. We do not provide support for this pre-release version. It is expe…

Chapter 4.6:Coding the GPT model

4 Implementing a GPT model from Scratch To Generate Text 4.6 Coding the GPT model 本章从宏观视角介绍了 DummyGPTModel,使用占位符表示其构建模块,随后用真实的 TransformerBlock 和 LayerNorm 类替换占位符,组装出完整的 1.24 亿参数…

IDEA的Git界面(ALT+9)log选项不显示问题小记

IDEA的Git界面ALT9 log选项不显示问题 当前问题idea中log界面什么都不显示其他选项界面正常通过命令查询git日志正常 预期效果解决办法1. 检查 IDEA 的 Git 设置2. 刷新 Git Log (什么都没有大概率是刷新不了)3. 检查分支和日志是否存在4. 清理 IDEA 缓存 (我用这个成功解决)✅…

埃安UT正式入局纯电小车之争,海豚能否守擂成功

文/王俣祺 导语:2025年刚刚来临,第一波车市竞争就开打了,早在去年广州车展就吸睛无数的埃安 UT ,日前正式开启预售,被称为比亚迪海豚的“最强对手”,主要是其价格和配置也确实全面对标了 比亚迪海豚。那么&…

从configure.ac到构建环境:解析Mellanox OFED内核模块构建脚本

在软件开发过程中,特别是在处理复杂的内核模块如Mellanox OFED(OpenFabrics Enterprise Distribution)时,构建一个可移植且高效的构建系统至关重要。Autoconf和Automake等工具在此过程中扮演着核心角色。本文将深入解析一个用于准备Mellanox OFED内核模块构建环境的Autocon…

从企业级 RAG 到 AI Assistant , Elasticsearch AI 搜索技术实践

文章目录 01 AI 搜索落地的挑战02 Elasticsearch 向量性能 5 倍提升03 Elasticsearch 企业版 AI 能力全面解读04 阿里云 Elasticsearch 将准确率提升至 95%05 AI Assistant 集成通义千问大模型实现 AI Ops01 AI 搜索落地的挑战 在过去一年中,基座大模型技术的快速迭代推动了 …

java中的日期处理:只显示日期,不显示时间的两种处理方式

需要记录某个操作的操作时间,数据库中该字段为DATE类型; 插入数据的时候,使用数据库函数NOW()获取当前日期并插入: <insert id="batchInsertOrgTestersByProjectId">insert into project_org_testers(project_unid, org_tester_id,franchise_date) value…

c# 常见的几种取整场景

软件取整&#xff0c;通常指的是在计算机软件中对数值进行取整操作&#xff0c;即将一个浮点数或小数转换为整数&#xff0c;同时确定如何处理小数部分。取整操作在编程和数学计算中非常常见&#xff0c;不同的取整方法适用于不同的场景。 常见的取整方法 向零取整&#xff08…

修仙模拟器代码分析

修仙模拟器代码分析 1. 概述 这是一个基于Python开发的修仙模拟器游戏&#xff0c;通过面向对象编程实现了一个具有丰富功能的文字冒险游戏系统。游戏模拟了修仙世界中的各种元素&#xff0c;包括修炼境界、灵根、门派、社交关系等多个方面。 2. 核心类结构 2.1 数据类&…

leetcode 面试经典 150 题:两数之和

链接两数之和题序号1题型数组解题方法1. 哈希表&#xff0c;2. 暴力法难度简单熟练度✅✅✅✅✅ 题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输…

如何在 Ubuntu 22.04 上安装 Nagios 服务器教程

简介 在本教程中&#xff0c;我们将解释如何在 Ubuntu 22.04 上安装和配置 Nagios&#xff0c;使用 Apache 作为 Web 服务器&#xff0c;并通过 Let’s Encrypt Certbot 使用 SSL 证书进行保护。 Nagios 是一个强大的监控系统&#xff0c;它可以帮助组织在 IT 基础设施问题影…

Nginx代理同域名前后端分离项目的完整步骤

前后端分离项目&#xff0c;前后端共用一个域名。通过域名后的 url 前缀来区别前后端项目。 以 vue php 项目为例。直接上 server 模块的 nginx 配置。 server{ listen 80; #listen [::]:80 default_server ipv6onlyon; server_name demo.com;#二配置项目域名 index index.ht…

【大数据基础】大数据概述

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈大数据技术原理与应用 ⌋ ⌋ ⌋专栏系统介绍大数据的相关知识&#xff0c;分为大数据基础篇、大数据存储与管理篇、大数据处理与分析篇、大数据应用篇。内容包含大数据概述、大数据处理架构Hadoop、分布式文件系统HDFS、分布式数…

linux-定制化rpm(rpmbuild)

一. 引文&#xff1a; 为实现我们的快速安装&#xff0c;特定服务需求的服务部署需求&#xff0c; 我们选择了通过source编译后定制成rpm&#xff0c;存放至自定义yum仓库&#xff0c;通过yum工具规范化管理及部署服务。目前比较常用的rpm打包方式分别为rpmbuild和fpm(在rpmbui…

解决Qt打印中文字符出现乱码

在 Windows 平台上&#xff0c;默认的控制台编码可能不是 UTF-8&#xff0c;这可能会导致中文字符的显示问题。 下面是在 Qt 应用程序中设置中文字体&#xff0c;并确保控制台输出为 UTF-8 编码&#xff1a; 1. Qt 应用程序代码 在 Qt 中&#xff0c;我们可以使用 QApplic…

测试用例颗粒度说明

当我们在编写测试用例时&#xff0c;总是会遇到一个问题&#xff1a;如何确定测试用例的颗粒度&#xff1f;测试用例过于粗糙&#xff0c;可能无法全面覆盖系统的细节&#xff1b;而颗粒度过细&#xff0c;又会导致测试重复、冗余。掌握合适的颗粒度&#xff0c;不仅可以提高测…

【大模型(LLM)面试全解】深度解析 Layer Normalization 的原理、变体及实际应用

系列文章目录 大模型&#xff08;LLMs&#xff09;基础面 01-大模型&#xff08;LLM&#xff09;面试全解&#xff1a;主流架构、训练目标、涌现能力全面解析 02-【大模型&#xff08;LLM&#xff09;面试全解】深度解析 Layer Normalization 的原理、变体及实际应用 大模型&…

VoiceBox:基于文本引导的多语种通用大规模语音生成

VoiceBox:基于文本引导的多语种通用大规模语音生成 Voicebox: Text-Guided Multilingual Universal Speech Generation at Scale Voicebox是由MetaAI发布的一个类似大语言模型的生成式语音模型。它是一种基础模型,可以完成类似大语言模型的功能,可以针对语音数据进行编辑、…