其他分享
首页 > 其他分享> > 女神在我玩王者的时候约我看电影,可我又不能挂机坑队友。那就只能写一个帮我打王者荣耀的AI了

女神在我玩王者的时候约我看电影,可我又不能挂机坑队友。那就只能写一个帮我打王者荣耀的AI了

作者:互联网

大家好,这里是为代码封神的封神榜(有点吹牛皮了,哈哈)。还是新人初来乍到,希望大家多多指教。

——————————————————
不知道兄弟们有没有遇到这样的情况,当你正在玩王者的时候,战局焦灼。结果这时候心仪已久的女神(之一)发来一条消息,问我有时间一起看电影吗?
在这里插入图片描述

我这暴脾气,这怎么能忍!
在这里插入图片描述
当场我就要夺门而出了,可是想到我也不能辜负一直陪我战斗的兄弟们啊。正纠结之时,瞥见了室友写了一半的Python作业,瞬间心生一计。

干脆自己写一个替我打王者荣耀的是AI算了,这样游戏女神两不误。在这里插入图片描述
那接下来看我操作吧!

该项目包括训练数据收集、数据处理、模型训练和模型应用完整开发流程。

该项目用后裔的100多局对战数据训练了一个模型作为演示,大家学会以后可以自己收集数据,训练自己的AI英雄。

接下来我们就来拆解下这个项目,我讲解项目的原则一贯是简洁、通俗,尽量做到小白也能看懂。

先来考虑下大致的实现思路,看到这个项目的第一眼我是比较懵的,完全不知道怎么搞。其实换个角度,想想我们玩游戏的过程,或许就能找到一些思路。

我们玩游戏的时候,大脑会根据当前的游戏画面来判断该进行什么样操作。游戏画面其实就是一张图片,如果把图片和图片对应的操作输入到算法模型,让算法自己去学习图片与操作之间的关系。当给出新的图片,如果算法能正确输出对应的操作,那我们就可以在游戏开始后,把游戏画面不断输入到算法模型中,算法模型不断产生对应操作并执行,这样便实现了程序自动玩游戏的功能。

所以,我们就把AI玩游戏的问题抽象成了计算机视觉(cv)的问题。那么要解决的核心问题有两个,第一,图片和图片的操作怎么收集,第二,用什么算法模型。

在后面的讲解中会解决这两个问题。

01 收集训练数据

收集训练数据就是我们在玩游戏的时候把游戏画面以及操作记录下来。

获取游戏画面

首先需要在 Windows 电脑上安装 scrcpy,它能将安卓手机投射到电脑,这样我们就可以在电脑上截取游戏画面了。

在这里插入图片描述

代码很简单,调用了“取图”函数,“窗口名称”参数是运行 scrcpy 的窗口名称。该函数会调用系统能力将当前窗口画面保存为图片

在这里插入图片描述

这个项目还有一大特点是变量名和函数名大量地使用中文名定义,虽然 Python3 支持这样做,但很少见,个人觉得英文名更好。

获取图片对应的操作

我们没办法直接获取手机上的触控事件和手势,只能通过电脑来中转,将手机上的操作转换为电脑上的键盘操作,比如:手机的上下左右移动,转为按键’w’、‘a’、‘s’、‘d’。

在这里插入图片描述
在这里插入图片描述

当有按键按下时调用该函数,它会根据具体的按键设置相应的变量,并保存到“操作列”变量里,这里定义的按键覆盖了王者荣耀的大部分操作。

有了按键处理函数,我们就可以定义一个监听器,不断监听按键操作

在这里插入图片描述

除了 on_press 函数外,这里还有个 on_release 函数,估计大家也猜到了,它用来监听按键被释放的。跟 on_press 类似,根据释放的键设置对应的变量。

保存图片及对应操作

首先将“操作”处理成文字性的描述,并格式化。

在这里插入图片描述

“操作词典”变量是map类型的,存了3个key,分别是 “图片号” 、“移动操作”和“动作操作”。

“移动操作”是通过调用“处理方向”函数,将按键转化“上移”、“左移”等文字性描述。

“动作操作” 指点击“攻击”、“一技能”、“二技能”之类的操作。

设置好变量后, 将图片以及操作写入文件。

在这里插入图片描述

最终,写入的文件效果如下:
在这里插入图片描述
在这里插入图片描述

将操作发送到手机

前面我们用电脑按键代替了手机操作,但还没有真正地将操作发送至手机。

完成这一步需要用到另一个工具 pyminitouch,它可以用代码控制安卓手机的多点触摸以及手势。

在这里插入图片描述
在这里插入图片描述

变量“设备”是用 pyminitouch 创建出来的而对象,调用“发送”函数,将“移动操作”、“动作操作”发送到手机,“操作查询字典”会把文字描述的动作转为手机能识别的代码。比如:

在这里插入图片描述

02 训练数据预处理

预处理的目的是为了将数据处理成算法模型能够识别的格式,主要是将图片和操作数字化,构造“张量”。“张量”是深度学习里的概念,把它理解成多维数组就行。

在这里插入图片描述

定义ResNet模型

调用 ResNet 深度学习模型对图片进行处理。

代码1:在这里插入图片描述

代码2:

在这里插入图片描述

代码2 中的第13行代表使用英伟达显卡,第14行使用 torchvision 提供的 resnet101 模型,pretrained=true 代表使用已经在 ImageNet 上已经预训练好的模型。第15行是在 torchvision 提供的 resenet101 模型基础上,自定义自己的深度学习模型 —— myResnet。

myResNet 类继承自 nn.Module,forward 函数定义了具体的神经网络,对于 ResNet101 来说,第1层–conv1卷积层+bn+relu+maxpool; 第2~10层–layer1; 第11~22层–layer2;第23~91层–layer3; 第92~100层–layer4; 第101层:avgpool层+fc层,网络结构图如下:

在这里插入图片描述

跟代码里定义的是一样的。

图片转张量

在这里插入图片描述

首先调用 PIL (python 图片库)里的Image类的open函数,读取图片,然后调用 resnet101(img)输出“图片张量”,由于python的特性最终会调用 forward 函数,然后在神经网络中进行计算,提取图片的特征,输出张量。

最后调用 torch.cat 方法,逐个将“图片张量”合并。

操作转张量

在这里插入图片描述

将图片对应的“移动操作”和“动作操作”拼接成一个字符串,如:“上移_攻击”、“左下移_二技能”。然后通过“词数词典”把文字映射成数字。该字典内容如下:

在这里插入图片描述

将转换后的数字存在“操作序列”变量里。

保存张量

在这里插入图片描述

将“图片张量”转成 numpy 类型,和“操作序列”一起保存到在文件里。“图片张量np”是一个二维数组,每一行对应一张图片的张量,“操作序列”是一维数组,每个数字代表图片对用的操作。

03 模型训练

定义模型

在这里插入图片描述
在这里插入图片描述

get_model 函数定义 Transformer 模型,调用该函数即可获取。Transformer 也是深度学习模型,最开始用于 nlp,目前逐渐用于计算机视觉中。

这里的 Transoformer 类也是自定义的,继承自 nn.Module。

在这里插入图片描述

同样的,在 forward 函数里定义网络结构。forward 用到的 decoder 变量对应的 Decoder 类也是继承自 nn.Module 的自定义类,里面也有 forward 函数。道理都是一样的,这里就不赘述了,感兴趣的可以根据源码看它的网络结构。

最终其实是ResNet+Transformer组成的大的神经网络。

模型训练

有了模型,就可以读入训练数据进行模型训练了。

在这里插入图片描述

在这里插入图片描述

从之前预处理的文件中读取“图片张量”和“操作序列”。它们经过分块、分组处理,最终构造出第98~100行的三个变量。由于分块、分组过程只是数据简单聚合,并不复杂,这里就不展开说了。

大家或许会有疑问,两个变量怎么生成了三个变量?“图片张量np”对应生成“图片_分_torch”这没问题,那另外两个呢?

我们看第55行代码,向“操作序列”插入了一个元素,取值是128。128在字典里对应的“移动操作”和“动作操作”分别是“无移动”和“无动作”。虽然插入的值没什么实际含义,但带来的结果是原本“操作序列”里的数据整体向下移动一行。

在这里插入图片描述

在代码里,“操作_分_torch”是由“操作序列”直接生成的,这就导致该数组里每一个“操作”不是当前图片的“操作”,而是下一张的。换句话说,当前图片在“操作_分_torch”变量里的操作是上一个图片的操作。

“目标输出_分_torch”也是由“操作序列”生成,但经过了索引的修正,所以图片对应在该数组里的“操作”是正确的。

我们截一段数据转换的代码看一下就明白了

在这里插入图片描述

第65行对“游标” +1,所以能取到真正的“操作”。我也做了一张图,更直观的去理解这个过程。

假设预处理文件里有4张图片,对应的操作分别是“无操作_无操作”、“右移_无操作”、“右移_攻击”和“右移_一技能”。构造出来的“图片_分_torch”、“操作_分_torch”和“目标输出_分_torch”如下:

在这里插入图片描述

接着上面代码第104行,将“图片_分_torch”和“操作_分_torch”输入模型,得出预测的“操作”,存入“输出_实际_A”变量中。这行代码的现实意义是,从多张图片以及图片对应的历史操作来预测当前应该执行什么操作。

有了预测值,那就需要跟实际值去比较,从而更新模型。

在这里插入图片描述
在这里插入图片描述

第107行,计算预测的“操作”与真实“操作”之间的差距,然后第110行、第112行进行参数调优,优化算法使用的是 Adam。

这样不断地去预测、调优,最终达到一个效果较好的模型,输出保存

在这里插入图片描述

04 模型训练

有了模型,最后要做的就是运行模型,让程序自动玩游戏。

到这里,最初提到的两个问题已经解决了,最复杂的部分也讲完了,所以这部分我们快速进行。

首先,加载保存的算法模型。

在这里插入图片描述

然后截取游戏的图片,并转为“图片张量”

在这里插入图片描述

还得记得收集训练数据的代码吗,这里的图片就是调用“取图”函数获取的。变量“抽样np”是上一个图片预测的“操作”,含义跟训练是一致的,用它来生成“操作序列”。

调用模型,预测应该当前应该进行什么“操作”

在这里插入图片描述

用法跟模型训练过程一样。

变量“输出_实际_A”是模型的输出,需要将其转成数字,再根据字典将数组转成文字性操作

在这里插入图片描述

同时,这里我们也看到了“抽样np”变量。我们最终需要的是第293行“指令集”变量。它是一个长度为2的数组,第一个元素存放“移动操作”、第二个元素存放的是“动作操作”。

最后,用 pyminitouch 将这两个操作发送出去

在这里插入图片描述
在这里插入图片描述

这样,整个项目就介绍完了。

整个过程其实就是收集数据、模型训练、模型预测的过程。重点要解决的就是如何样本数据化,以及如何设计、训练模型。

感兴趣的朋友也可以下载源码动手运行一下,作者提供了一个已训练好的模型,可以直接拿来使用。

代码可以私聊我一下,新人还不能上传资源QAQ。

标签:训练,王者,AI,模型,张量,变量,操作,挂机,图片
来源: https://blog.csdn.net/Python4857/article/details/121256425