从0实现基于Alpha zero的中国象棋AI(会分为多个博客,此处讲解蒙特卡洛树搜索)

news2024/11/24 8:53:48

从0实现基于Alpha zero的中国象棋AI

0.0、前言

​ 题主对于阿尔法狗的实现原理好奇,加上毕业在即,因此选择中国象棋版的阿尔法zero,阿尔法zero是阿尔法狗的升级版。在完成代码编写的历程中,深刻感受到深度学习环境的恶劣,网络上固然资料繁多,但要么水平不行,不知所云,要么国外课程,门槛过高。因而碰壁良多,才想着自己写一篇博文,完整详细的阐述作为普通人的我以及大家如何去一步步实现中国象棋AI。

​ 同时,预先说明:题主认为学习深度学习一定要有目标,如完成一个垃圾检测等等,具体落实到项目,以完成项目为驱动力,无关知识了解即可,切勿系统学习,贪多。深度学习庞大而深奥,一个小方向就足以研究一生。

​ 总体而言,想要基于python编写阿尔法zero需要使用到如下知识:

  • 熟悉python语法
  • 知道如何使用pytorch完成卷积神经网络与残差神经网络
  • 会使用Anaconda创建虚拟环境

默认读者有以上三者基础,没有也无所吊谓,只是无法敲出代码,理论才是最重要的。

​ 阿尔法zero算法主要由两部分组成:残差神经网络与蒙特卡洛树搜索。这二者也是下面会详细阐述的内容,同时会扩展到卷积神经网络与原生蒙特卡洛树搜索。

0.1、阿尔法狗 和 阿尔法 zero区别

阿尔法狗:需要预先收集大量棋局信息制作成数据集,对神经网络进行训练,然后在人机对弈时会结合神经网络的输出与蒙特卡洛树搜索进行落子

阿尔法zero:无需事先准备棋局数据,通过自我对弈,在对弈过程中收集棋局信息,然后将信息制作成数据集对神经网络进行训练,在自我对弈与人机对弈中同样使用神经网络与蒙特卡洛树搜索进行落子

很显然,对于普通人来讲,不需要额外数据的阿尔法zero更适合

1.0、原生蒙特卡洛树搜索

​ 鉴于阿尔法zero所需知识过多,若直接概览全局,反而不知所云。因此题主边提出问题边讲解,让读者知道为啥要这样做,而不是这样做就行了。

1.1、穷举法

​ 我们以最简单的井字棋为例,在一个空白的棋盘上选择哪一步落子为当前方最优捏?

​ 最简单的方法就是穷举、如红方落在左上角位置,黑方落在旁边,一直交替落子最终分出胜负,然后棋局回归到红方落子在左上角位置,此时黑方再选择不同地方落子,再次交替落子,再次分出胜负。直到黑方无未重复落子位置,则记录模拟次数以及这些次数中红胜利的次数形成,红落子在左上角的胜率,仿照上述行为,模拟出空棋盘下红方所有可以落子的行动以及行动对应的胜率,最终选择胜率最大的作为真实落子。

​ 可以看到,上述方法确实是有用的,但缺点也很明显,需要庞大的算力支持,如果将游戏改为象棋或者围棋,是不可能支撑如此庞大的运算。

​ 因此,我们需要一种算法,能够减少计算量,使其更加高效。

​ 蒙特卡洛树搜索应运而生。

1.2、原生蒙特卡洛树搜索

​ 原生的蒙特卡洛树搜索会从开始到随机策略,逐渐过渡到有一定选择性的策略。具体如下:

​ 原生蒙特卡洛树搜索有四步骤:选择,扩展,模拟,反向传播、

​ 先大致讲一下原生蒙特卡洛树搜索:

​ 通过算法选择输入局面的所有可能落子中一个,生成子节点(子节点被选择次数加一,总搜索次数加一),以子节点开始模拟红黑方交替落子,直至分出胜负,若红胜且子节点为红方落子,则子节点价值设置为1,然后重新以初始局面选择所有落子可能中一个,且某些动作已生成子节点且存在价值,则计算此动作的最终值需加入此节点价值进行计算。然后重复以上步骤,最终输出被选择次数多的落子动作为真实落子。

再详细讲解(以井字棋为例)

1、初始局面为3X3的空棋盘。创建全局变量all_count:记录总搜索次数,输入此局面下应该为哪一方落子,这里默认红方

初始化一颗树的数据结构(后续以 A 表示此初始节点与棋盘),树中存储:

  • a_count=0(表示此节点被选中次数,但是初始节点用不到,后面节点才用得到)
  • 一个二维数组,表示空棋盘
  • value:表示此节点价值(初始节点用不到)
  • play:表示是红方还是黑方(初始节点用不到)

2、计算此局面下红方所有可能都落子动作,很显然有9种。

3、使用 上置信界算法 计算每一种落子动作的最终价值(此价值与节点中存储的价值不是一个东西),并选择值最大的动作生成子节点**(扩展**)

---------------------------------------------------------------------------------上置信界算法---------------------------------------------------------------------------------------

上置信界算法

​ 核心:兼顾探索与价值。

​ 解释:在此棋局中,若一味使用价值最大的作为子节点,会照成每次都选择相同节点,因初始时价值都为0,一旦选择一个子节点且价值大于0后,后续就只会选择此节点,若有其他落子潜在价值大于此也不会被选中,因此需要一种算法,让搜索次数增加的同时,选中次数小的动作其被选中的概率增加。只要符合算法思想,怎样设计算法都没问题,这里提供一个简单的:

UCB(上置信界) = value + c X 总搜索次数 / 节点被选中次数 + 1 (这里是为了方便理解,所以化繁为简,真实的算法可以适当更改以更贴合)

value:节点价值,c:偏置,就是一个自定义的常数,用来平衡探索与价值的

---------------------------------------------------------------------------------回到步骤---------------------------------------------------------------------------------------------

​ 由算法可知、当前局面下的 UCB 全部一样,都是 0,因为此时没有子节点生成,所有 9 种动作都没有价值 且都没有被选择,总次数也为 0 。所以我们还是会依据算法选择一个动作进行扩展,比如说是左上角第一个,这里无关紧要因为并非最终落子。

​ 选择左上角第一个后,总次数加一,创建子节点 B ,且其父节点为初始节点,子节点被选中次数加一,即:

在这里插入图片描述

4、模拟

​ 我们以子节点B为起始,模拟红黑双方交替落子,直至分出胜负。

​ 注意,交替落子不会生成子节点,且完全随机。(因为模拟的落子是没有 价值 这个变量,所以只能随机)若最终胜方与此子节点落子方一致则value变为1,反之变为-1

在这里插入图片描述

5、反向传播:就是上述value变为1了,由于只进行一次搜索只有一个子节点,且树深度为2,所以不能完全体现反向传播,后面会再讲。

6、此时才算进行完一次搜索,接下来进行第二次搜索,(注:总搜索次数增加应该是在搜索完成时增加,节点被访问次数是在节点被访问或者创建时增加)

7、同样以初始空棋盘为起点,再次计算上置信界值(常数我们设置为2,这里是为了方便演示所以尽量减少探索,注重价值),计算可知:因此,我们再次选择第一排第一个作为

在这里插入图片描述

8、由于选择的是已经存在的节点,因此我们不进行扩展,而是以此节点局面再次计算此节点局面下所有可能落子动作的UCB值,注意此时就是应该黑方落子了,所以是求黑方所有可能落子。由此局面可知,黑方有 8 种落子方式。我们分别求取这八种方式的 UCB 值,并选择落子动作进行扩展,同样这八种的UCB全为 2 (即此局面下不存在任何一个子节点,因此也就不存在价值),因此,我们选哪一个都可以,这里选第一排第二个,此时局面变为:

在这里插入图片描述

9、再次以 C 节点的局面作为模拟初始局面,此时若模拟结果是黑赢,那么此局面最终价值应该为:1

10、反向传播:我们通过模拟知道了C节点价值,此时需要将价值回传,即通过子节点寻找父节点,又因为父节点是另一方落子,所以父节点更新后价值应该为:(父节点原价值 - 子节点价值)/ 2。也就是B节点更新后价值

由于B节点的父节点为初始节点,所以不需要再将价值传递给初始节点了。

同时,总搜索次数加一,即all_count = 2,至于节点被访问次数,则是按照关系链来进行增加,比如上述节点C次数需要加一,其父节点B在反向传播时也需要加一。所以最终结果如下:

在这里插入图片描述

11、此时我们再次计算初始局面(空棋盘)时个落子动作的UCB值:

在这里插入图片描述

由图可知,我们可取第一排第二个作为节点 D 进行扩展:

在这里插入图片描述

12、然后就是继续模拟,反向传播,然后再次从初始节点开始进行新一轮搜索,如此循环往复直到到达指定搜索次数。

13、最终,我们会选择初始节点下的子节点中被访问次数最大的作为蒙特卡洛树搜索的输出,如上图中,子节点有 2 个,且B节点次数大于D节点,因此我们选择B节点作为输出,也就是第一排第一个的动作。

总结:

优点:

​ 纵观全部原生蒙特卡洛树搜索,最关键处就是上置信界算法和模拟这两者去抉择最优解。它比穷举法更加高效,通过算法可以不需要全部遍历完就能选择出相对优解。同时又保留了一部分穷举的特点,模拟操作可以真实知道对应动作的价值,并且在后续选择中由开始的注重探索过渡到注重价值。

缺点:

​ 经过上述过程可以看出,虽然能够节省大部分时间,但是我们每一次搜索的模拟步骤中必须要到达终局,这对于大型棋类游戏而言还是不太适合,还是需要算力,因此,基于残差神经网络的蒙特卡洛树搜索应运而生。

1.3、基于残差神经网络的蒙特卡洛树搜索

在原蒙特卡洛树搜索基础上增加了两个东西,策略与价值。

也就是原来的 上置信界算法 算法被修改为:

在这里插入图片描述

上述讲解value值时还要细节没提到,等下会详细讲。

先说说残差神经网络的输出,一般神经网络只输出只有一个,但是为啥需要两个输出呢?

正常情况其实我们只需要价值输出即可,即value值,在模拟时用到,但是这里还加了一个概率输出。

说实话,有用,但是具体为啥一定需要就找不到很有说服力的依据。

再说说策略输出到底输出的是啥?

若将空棋盘输入到残差神经网络。因为刚开始红方有9种可能落子,所以策略网络最终会输出每一个可能动作被选择的概率,如下:

其和应该是1,这里只是示例,随便设置了几个数值。

策略输出相当于神经网络对当前局面的预判,它认为某些落子动作更有价值,就会提高对应概率,这样在计算此局面所有动作的UCB值时加入,可提高对应动作的值,使最优解能够更明显,这也是为啥我说有用的地方。

价值网络输出:就是输出一个值,这个值可以当做当前局面的价值来看(可以看作当前局面对于落子方的有利程度)。但是一般我们不直接将此局面的价值设置为此节点价值。而是通过模拟这个步骤获得节点最终价值。

模拟步骤会与原生蒙特卡洛树搜索不同!

原生蒙特卡洛树搜索一定是要达到终究,无论双方交替落子多少次,但是基于残差神经网络的蒙特卡洛树搜索由于残差神经网络可以输出每个局面的价值,即每次交替落子的局面价值,这样存储每个局面价值,然后交替落子一定步骤后,即使未到达终局也可以使用反向传播的方式求取平均价值作为此子节点价值。当然,在指定次数中若出现终局则价值以终局价值为准。

总结:基于残差神经网络的蒙特卡洛树搜索,有两方面提示:

1、神经网络会输出每个动作的概率,这样可以更加准确找到最优解,因为概率越大最终值越大。

2、由于神经网络还可以输出某个局面价值,使用我们在模拟步骤时,不需要一定到达终局就能够获得价值。

且随着神经网络训练次数的增加,概率与价值的值会越贴近正确值。如上,也是为何需要残差神经网络辅助的原因。

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

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

相关文章

零门槛快速创业:GPT和AI工具的秘密武器

在不到一周的时间里,David创建了一个按需印刷的Etsy商店,该商店具有引人注目的标识和大量独特的文字和艺术。 我最近花了大约一周的时间来建立Etsy店面。在本文中,我将向你展示我如何(可能更有趣的是,在哪里&#xff…

YOLOv5:TensorRT加速YOLOv5模型推理

YOLOv5:TensorRT加速YOLOv5模型推理 前言前提条件相关介绍TensorRT加速YOLOv5模型推理YOLOv5项目官方源地址将训练好的YOLOv5模型权重转换成TensorRT引擎YOLOv5 best.pt推理测试TensorRT Engine推理测试小结 参考 前言 由于本人水平有限,难免出现错漏&am…

笔试强训8

作者:爱塔居 专栏:笔试强训 作者简介:大三学生,希望和大家一起进步 day13 一. 单选 1.下列关于视图的说法错误的是: A 视图是从一个或多个基本表导出的表,它是虚表B 视图一经定义就可以和基本表一样被查询…

Python遍历网格中每个点

遍历网格中每个点 1. 问题描述2. Python实现2.1 网格参数初始化2.2 遍历赋值2.3 矩阵赋值1. 问题描述 最近需要实现一个对矩阵赋值并对矩阵表示的网格参数进行测试的任务,写了一段代码提供参考。 假设网格的长宽均为 2. Python实现 2.1 网格参数初始化 首先定义好需要划分…

【小呆的力学笔记】非线性有限元的初步认识【三】

文章目录 1.2.2 基于最小势能原理的线性有限元一般格式1.2.2.1 离散化1.2.2.2 位移插值1.2.2.3 单元应变1.2.2.4 单元应力1.2.2.5 单元刚度矩阵1.2.2.6 整体刚度矩阵1.2.2.7 处理约束1.2.2.8 求解节点载荷列阵1.2.2.9 求解位移列阵1.2.2.10 计算应力矩阵等 1.2.2 基于最小势能原…

基于深度学习的高精度推土机检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于深度学习的高精度推土机检测识别系统可用于日常生活中检测与定位推土机目标,利用深度学习算法可实现图片、视频、摄像头等方式的推土机目标检测识别,另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型训…

通过location实现几秒后页面跳转

location对象属性 location对象属性 返回值location.href获取或者设置整个URLlocation.host返回主机(域名)www.baidu.comlocation.port 返回端口号,如果未写返回空字符串location.pathname返回路径location.search返回参数location.hash返回…

【SCADA】关于KingSCADA仿真驱动的应用

大家好,我是雷工! 在有些时候我们需要用到虚拟仿真的数据,例如在效果演示时为了有良好的动态效果。在KingSCADA软件中可以通过Simulate驱动作为虚拟设备实现这一功能需求。 下面为大家演示该功能的应用: 一、KingIOServer工程设计…

Go实现跨域Cors中间件

概述 本版本主要实现cors中间件 github 地址:Sgin 欢迎star,将会逐步实现一个go web框架 内容 通过建造者模式创建我们的跨域中间件Cors \ 我们了解到,当使用XMLHttpRequest发送请求时,如果浏览器发现违反了同源策略就会自动加…

StableDiffusion入门教程

目录 介绍模型的后缀ckpt模型&#xff1a;safetensors模型文件夹VAE 模型在哪下载Hugging face:<https://huggingface.co/models>下载SD官方模型文生图模型标签介绍 C站&#xff1a;<https://civitai.com/>筛选模型的类型CheckPoint Type &#xff08;模型的类型&a…

Python学习笔记 - 探索元组Tuple的使用

欢迎各位&#xff0c;我是Mr数据杨&#xff0c;你们的Python导游。今天&#xff0c;我要为大家讲解一段特殊的旅程&#xff0c;它与《三国演义》有关&#xff0c;而我们的主角是元组&#xff08;tuple&#xff09;。 让我们想象这样一个场景&#xff0c;三国演义中的诸葛亮&am…

pandas数据预处理

pandas数据预处理 pandas及其数据结构pandas简介Series数据结构及其创建DataFrame数据结构及其创建 利用pandas导入导出数据导入外部数据导入数据文件 导出外部数据导出数据文件 数据概览及预处理数据概览分析利用DataFrame的常用属性利用DataFrame的常用方法 数据清洗缺失值处…

Cesium教程 (3) 矢量切片mvt-imagery-provider加载

Cesium教程 (3) 矢量切片mvt-imagery-provider加载 目录 0. 矢量切片 1. 开源项目 2. 环境 3. 代码 4. TODO 0. 矢量切片 WMTS&#xff1a;加载最快&#xff0c;图片格式&#xff0c;样式固定&#xff1b; WMS&#xff1a;加载数量大则慢&#xff0c;但可以点击查询等&am…

htmlCSS-----CSS选择器(上)

目录 前言&#xff1a; 1.初级选择器 &#xff08;1&#xff09;ID选择器 &#xff08;2&#xff09;class选择器 &#xff08;3&#xff09;标签选择器 &#xff08;4&#xff09;通配选择器 前言&#xff1a; CSS选择器是CSS页面处理的重要组成部分&#xff0c;前面讲到…

MMPose关键点检测实战

安装教程 https://github.com/TommyZihao/MMPose_Tutorials/blob/main/2023/0524/%E3%80%90A1%E3%80%91%E5%AE%89%E8%A3%85MMPose.ipynb git clone https://github.com/open-mmlab/mmpose.git -b tutorial2023 -b代表切换到某个分支&#xff0c;保证分支和作者的教程一致 ra…

基于SpringBoot+Thymeleaf+Mybatis+Html校园二手交易平台

基于SpringBootThymeleafMybatisHtml校园二手交易平台 一、系统介绍1、系统主要功能&#xff1a;2、环境配置 二、功能展示1.主页(客户)2.登陆&#xff08;客户&#xff09;3.我的购物车(客户)4.我的订单&#xff08;客户&#xff09;5.主页&#xff08;管理员&#xff09;6.订…

mybatisplus数据权限插件学习初探 动态表名更换插件 防止全表更新与删除插件

文章目录 学习链接 mybatisplus数据权限插件学习初探前言案例建表用户表订单表 环境准备UserUserMapperUserMapper.xmlOrdersOrdersMapperOrdersMapper.xml 配置UserTypeEnumUserContextHolderCustomizeDataPermissionHandlerMybatisPlusConfig 测试测试类bossdeptManagerclerk…

Redis通信协议、过期回收策略

Redis通信协议-RESP协议 Redis是一个CS架构的软件&#xff0c;通信一般分两步&#xff08;不包括pipeline和PubSub&#xff09;&#xff1a; 客户端&#xff08;client&#xff09;向服务端&#xff08;server&#xff09;发送一条命令 服务端解析并执行命令&#xff0c;返回…

二级指针骚操作实现链表虚拟头节点

重点是不用像其他文章里那样&#xff0c;用一个普通节点成员变量当头节点&#xff0c;节省一点空间占用&#xff0c;反正我觉得有点骚。就不详细交代技术背景了&#xff0c;简而言之&#xff0c;就是链表中第一个节点前没有节点了&#xff0c;只有一个指向它的指针&#xff0c;…

强化学习基础篇[3]:DQN、Actor-Critic详解

【强化学习原理+项目专栏】必看系列:单智能体、多智能体算法原理+项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍:【强化学习原理+项目专栏】必看系列:单智能体、多智能体算法原理+项目实战、相关技巧(调参、画图等、趣味项目实现、学术应…