大家好,我是 Jack。
最近逛 B 站,看到了一个有意思的东西。
在原神游戏里,AI 全自动钓鱼,完全解放双手。
其实,这个内容,在我出这期视频的时候,就有人在评论区提到过了。
怎奈,本人没玩过原神,但一直知道它的大名。
今天,有位 up 主,做了这个AI 全自动钓鱼,推荐大家体验一下!
原神
在游戏圈,你可以没有玩过,但一定听过《原神》。
特别是在国外,原神可以说是火的一塌糊涂。
就在今年 9 月,这款从开放公测起便屡次登顶国内外讨论热度和手游吸金榜第一的开放世界冒险游戏更新了版本,添加 / 丰富了地图,并且上线了一款小游戏——钓鱼。游戏中多个水域都有钓鱼点,不同的位置可以钓不同的鱼。
很多玩家都在寻找钓鱼攻略,你还在愁在《原神》里钓不到鱼吗?今天我们为你送上这份迟到的提瓦特钓鱼指南。
这份钓鱼指南可以说是完全解放双手,不需要任何操作,只需要启动程序就能完成。上线短短几天,收获 1700+ 星。
项目地址:
https://github.com/7eu7d7/genshin\_auto\_fish
基于强化学习+YOLOX实现原神全自动钓鱼,半监督学习+迁移学习训练模型。不需要任何操作,只需要启动程序。完全解放双手(钓鱼太累了)。
我们先看下效果:
原理说明转自:
https://www.bilibili.com/read/cv13270965
算法原理
模型分为鱼群定位与识别和拉杆(和鱼博弈)两个部分。
拉杆部分使用opencv检测鱼是否上钩,并识别游标位置。确定游标位置后和鱼群博弈使用DQN强化学习算法(不想调PID太累了)。
训练过程中首先在仿真环境预训练一个AI,再迁移到原神环境中,毕竟仿真环境不会失败好训练,不需要太多轮。
鱼群定位与识别部分采用YOLOX定位鱼在屏幕中的位置并确定鱼的类别,鱼竿落点也一起定位。目标检测需要大量标注,太费时间,所以这里采用半监督学习+迁移学习的方式训练。
1. 拉杆部分
先从简单的开始,如果杆已经抛出去了该怎么吧鱼钓上来。
1.1 上钩检测与游标定位
要钓鱼首先要检测鱼有没有上钩,上钩了才能拉。我们可以看到,上钩与没上钩的图标是不一致的且有较大差异。如下图:
那是不是能直接找一个上钩的图像模板直接对比呢?上图可以看出后两张图的背景差异很大,而前两张背景相似,如果我们对比相似度的话,可能前两张反而更像。
比如我们使用psnr进行对比,左边两张图的PSNR为14.35,而右边两张只有9.5. 我们能分辨出来是因为前景和背景的对比,所以我们也要给程序这么一种对比,如果提取这些图像的边缘,就可以排除背景的干扰,canny边缘图如下:
这样处理后的图片就不会受背景影响了,也没有歧义,将这一个图作为模板进行对比便可以识别鱼有没有上钩了。
我们钓鱼过程中主要是看这一个力度调中的游标以及圆形的进度条:
但这一个东西的位置并不是固定的,y坐标有可能会变,使用我们需要找一个特征鲜明的东西来定位这个区域。这里我们选用最佳力度去的特征,这里的特征对比度高,较为鲜明:
将这一图像作为模板进行模板匹配(详情参考数字图像处理),便可以在图中找到力度条的位置,确定这一区域。
滑块的位置同样可以使用模板匹配,不过为了精度,我们将匹配范围限定在力度条这一局部区域内:
1.2 强化学习
在有了力度条的游标位置后就可以对鼠标进行控制,让其落在最佳区域内了。这里考虑到控制算法的人工成本和精度,使用强化学习实现(PID调参我再也不会碰了!)。这里只介绍强化学习和DQN的基本概念,具体细节可以参考知乎上关于强化学习和DQN的讲解。
强化学习与标准的监督学习最大的区别就是,强化学习是交互式学习的。标准的监督学习中每一组数据和标签都是独立的,模型的输出直接和数据集中获得的标签计算loss更新模型,不会对数据集产生影响。而强化学习中模型每一次输出都会作用于环境,会改变环境下一次所提供的数据。也就是说强化学习模型一下次能获得的数据是取决于上一次输出的动作的。它和环境间是交互式学习的。
DQN则是强化学习的一种神经网络实现,这种方式不直接从环境中获得模型的损失,模型获得的只是一个奖励(reward)。而模型的目标则是最大化长期奖励,loss则是通过奖励计算的,模型要规避在某一状态下低奖励的动作,而尽量做出高奖励的动作。由于使用神经网络实现,所以模型有泛化能力。为了防止模型只最大化短期奖励,DQN还设计了经验回放机制,不断回放先前的经验,防止遗忘(具体参考连续学习中的灾难性遗忘)。
1.3 仿真环境训练
在了解了强化学习的基本概念后就可以找一段DQN代码开始训练了(当然自己复现也行)。我们可以对力度条建模,最佳区域左右的位置和游标的位置可以写成一个三维向量(pl,pr,pn),这可以作为环境的状态(state)。而模型则输出两种动作,点或不点,则action是一个二维向量。任务比较简单所以模型也不用复杂,2层MLP+个ReLU层足够。
由于原神内短时间没有落在最佳区域就会失败,训练较为困难,所以先构建一个仿真环境进行预训练,训练好后再进行迁移学习。预训练的目的是让模型掌握一定的先验知识,在面对原神实际场景时可以有一定表现。就像去考试前会先做模拟题,从模拟题学会一些东西了才去考试再学。
控制力度这个问题可以进行简单建模,每过一段时间力度条会以随机的速度向随机的方向移动,同时长度也会随机变化。游标会被施加一个恒定的负向加速度,并在达到一定速度时停止。每次点击都会为游标施加一个瞬时较大的加速度,正向速度也有上限。根据这些条件,很容易就能构建一个仿真系统,模型在仿真系统内可以多学几轮。
1.4 迁移学习到原神环境
在仿真环境训练好后就可以将模型迁移到原神的实际环境中了,这里采用fine-tuning的方法。在一个数据集上预训练一个较好的模型,再固定部分层或以较低的学习率在其他数据上学习。
这是迁移学习中一种简单却非常有效的方法,可以快速实现不同域数据间模型的迁移。利用预训练的仿真环境模型,只需要40轮便可以迁移到原神环境中,并且训练过程中钓鱼很少会失败。
2 鱼群定位与识别
2.1 目标检测
关于目标检测和YOLOX的具体细节由于太过复杂这里不细讲,可以参考知乎的综述和解读的文章。这里只介绍目标检测任务的基本概念。
目标检测是计算机视觉近几年的一个热点问题,有很多优秀的模型。这是一个多任务学习问题,包括定位和分类。这些模型的主要任务是给一张图,在其他信息完全不知道的情况下确定图中哪些区域有物体和这些物体的类别。下面这张图展示了一些常见的视觉任务:
现在的目标检测主要分为one-stage和two-stage两大阵营。one-stage模型输入一张图像后直接让模型预测图中物体的包围框和这些框对应的类别。这里使用的YOLOX便是one-stage模型。而two-stage模型则先用RPN网络预测图中物体的包围框,和这些框里的是不是物体。之后把是物体的框的区域截出来,在去预测其中物体的类别和修正框的范围。one-stage相比two-stage要快的多,但精度会差一些,不过对于定位鱼这个任务,完全在可接受范围内。
2.2 半监督学习
半监督学习是指在数据集只有一部分标签的情况下,如何学习训练模型。这里打标签实在太累了,所以只有不到一半数据集打了标签。那剩下一部分怎么办呢。我们可以利用这一部分已经打了标签的数据集来处理剩下的数据集。
这里我们使用有标签的数据集先用迁移学习的方法,将在coco数据集上预训练的yolox模型迁移到这一部分数据集上。随后用这一训练好的模型为剩下的模型打上伪标签,之后再进行人工修正。毕竟稍微改改标签比自己从头打可轻松多了。要是无标签数据量足够的话也不需要人工修正了,直接根据置信度筛选迭代训练就可以了。
2.3 抛竿策略
训练好模型后就可以根据检测到的鱼的位置和鱼竿落点进行自动抛竿了。这里由于reward不好获取,所以没有采用强化学习的方式。由于定位的坐标是在二维图像的,而原神的鱼竿落点是三维的。所以这里使用迭代的方式逐步逼近落点。
越靠近与迭代步长应该越小,这里使用如下公式:
移动到鱼附近后进行抛竿,随后检测鱼上钩,长时间没有上钩就重抛。这样就可以完成全自动钓鱼。
整个项目原理并不复杂但涉及方面较广。想要更深入了解可以学习更多关于强化学习,数字图像处理,目标检测以及深度学习基础理论的相关知识。
项目说明
原神自动钓鱼 AI 由两部分模型组成:YOLOX、DQN。此外,该项目还用到了迁移学习,半监督学习来进行训练。模型也包含了一些使用 opencv 等传统数字图像处理方法实现的不可学习部分。
- YOLOX 用于鱼的定位和类型的识别以及鱼竿落点的定位;
- DQN 用于自适应控制钓鱼过程的点击,让力度落在最佳区域内。
环境部署
该项目是在 python 运行环境中使用的,需要先安装 python,这里推荐使用 anaconda。
配置环境:打开 anaconda prompt(命令行界面),创建新的 python 环境并激活(推荐 python3.7 或以下版本):
conda create -n ysfish python=3.6
conda activate ysfish
下载工程代码:使用 git 下载,或直接在 github 网页端下载后直接解压:
git clone https://github.com/7eu7d7/genshin_auto_fish.git
依赖库安装:切换命令行到本工程所在目录:
cd genshin_auto_fish
执行以下命令安装依赖:
python -m pip install -U pip
python requirements.py
如果要使用显卡进行加速需要安装 CUDA 和 cudnn, 安装后无视上面的命令用下面这条安装 gpu 版:
pip install -U pip
python requirements.py --cuda [cuda 版本]
# 例如安装的 CUDA11.x
python requirements.py --cuda 110
安装 yolox:切换命令行到本工程所在目录,执行以下命令安装 yolox:
python setup.py develop
预训练权重下载:下载预训练权重 (.pth 文件),yolox_tiny.pth 下载后将权重文件放在 工程目录 / weights 下。
YOLOX 训练工作流程:YOLOX 部分用半监督学习打标签。标注少量样本后训练模型生成其余样本伪标签再人工修正,不断迭代以提高精度。样本量较少所以使用迁移学习,在 COCO 预训练的模型上进行 fine-tuning。
将 yolox/exp/yolox_tiny_fish.py 中的 self.data_dir 的值改为解压后 2 个文件夹所在的路径。
训练代码:
python yolox_tools/train.py -f yolox/exp/yolox_tiny_fish.py -d 1 -b 8 --fp16 -o -c weights/yolox
DQN 训练工作流程:控制力度使用强化学习模型 DQN 进行训练。两次进度的差值作为 reward 为模型提供学习方向。模型与环境间交互式学习。
直接在原神内训练耗时较长,首先你需要制作一个仿真环境,大概模拟钓鱼力度控制操作。在仿真环境内预训练一个模型。随后将这一模型迁移至原神内,实现域间迁移。
仿真环境预训练代码:
python train_sim.py
原神游戏内训练:
python train.py
运行
以上准备就绪后,就可以运行钓鱼 AI,注意命令行窗口一定要以管理员权限启动。
显卡加速:
python fishing.py image -f yolox/exp/yolox_tiny_fish.py -c weights/best_tiny3.pth --conf 0.25 --nms 0.45 --tsize 640 --device gpu
cpu 运行:
python fishing.py image -f yolox/exp/yolox_tiny_fish.py -c weights/best_tiny3.pth --conf 0.25 --nms 0.45 --tsize 640 --device cpu
运行后出现 init ok 后按 r 键开始钓鱼,原神需要全屏。出于性能考虑检测框不会实时显示,处理运算后台进行。
作者:Jack Cui
原文:https://mp.weixin.qq.com/s/zA1jnCS6o1UNPum_FoUQlg
系列篇
更多AIoT领域有趣的算法应用及产品请关注有趣的AIoT应用专栏。