Pytorch+Mnist数据集+Pyautogui自动化解决永劫无间匹配超1分钟自动换服务器问题
本文涉及的深度学习内容不做过多阐述,想深入了解的可以去B站搜资源
目录
前言
自从永劫无间加了北京、成都、广州三个服务器之后,多了一个智能匹配机制,也就是你进行匹配的时候,系统会自动根据你的所在位置计算出最优的服务器然后分配进去。
但是!这里有个缺点!
当你原本可以匹配到有20~30ms服务器的时候,如果这个服务器人少,你匹配的时间超过1分钟,系统就会自动给你分配到别的服务器!这就很坑爹了!
当然我们可以手动盯着匹配时间在到1分钟之前取消匹配再开始匹配,但谁愿意玩游戏愿意干这么繁琐的事情呢!
为了解决这个问题,博主想用Python来解决这个问题,实现自动化取消匹配按钮再开始匹配。
非代码部分
一、永劫无间设置
首先将永劫无间窗口化,并设置成比屏幕小的比例,设置好后不要拖动游戏窗口。
准备一张取消按钮的图片
二、获取匹配服务器时读秒位置
首先我们需要获取到屏幕上我们想要的内容
其实我们只需要获取到上图十位数位置这个框框里面的内容就行了,那么我们需要借助一个工具,就是这个网页👇
https://zhangweixi.cc/static/windows-xy.html
进到里面,把窗口化时候的永劫无间全屏截图并粘贴进去,像下图这样
(截图时需要先点击开始游戏再截图,不然看不到读秒位置)
然后点F11全屏,双击刚刚十位数框框的四个角落的坐标点,记下来就行了,博主的是这四个点,每个人都不一样。
#十位数
p1 = (922,1034)
p2 = (938,1034)
p3 = (922,1058)
p4 = (938,1058)
接下来就要开始代码部分了
代码部分
一、引入库
在本文中,我们将使用PyTorch训练一个卷积神经网络来识别MNIST的手写数字。没学过的朋友可能需要移步到别的博客入门一下什么是pytorch和mnist。
import pyautogui #自动操作鼠标
import cv2
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
import speech #语音提示
MNIST数据集
其实大概意思就是让电脑学会识别数字0~9,从而可以识别到匹配时间到50秒的时候取消匹配。
二、Speech介绍
Speech库
这个库就是用来提醒你匹配时间到啦要重新开始匹配
直接下载↓
pip install speech
但是注意! Python3.X版本的要修改一些代码,否则无法使用,具体看下面这位博主的博客👇
python speech模块的使用方法
三、Pyautogui介绍
直接下载↓
pip install pyautogui
Pyautogui是一个纯Python的GUI自动化工具,通过它可以让程序自动控制鼠标和键盘的一系列操作来达到自动化测试的目的。
简单来说我们要用它代替我们人手去点击匹配按钮!
但是!但是!但是!
在永劫无间这款游戏里面调用不了Pyautogui里面的函数,博主也是折磨了很久发现只能通过pyautogui.doubleClick()
方法勉强实现功能,具体使用方法就是将永劫无间窗口化,将VScode或者Pycharm(你的python编辑器)放置窗口最顶处,然后次窗口是永劫无间。
四、Pytorch训练Mnist数据集
注意:这里开始涉及高深知识,小白先入门
首先下载Mnist数据集和定义训练批次为512
BATCH_SIZE = 512
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('data', train = True, download = True,
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1037,), (0.3081,))
])),
batch_size = BATCH_SIZE, shuffle = True)
# 测试集
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('data', train = False, transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1037,), (0.3081,))
])),
batch_size = BATCH_SIZE, shuffle = True)
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1037,), (0.3081,))
])
构造一个简单的卷积神经网络
没学过的可以简单上百度了解一下
class ConvNet(nn.Module):
def __init__(self):
super().__init__()
#1*1*28*28
self.conv1 = nn.Conv2d(1, 10, 5)
self.conv2 = nn.Conv2d(10, 20, 3)
self.fc1 = nn.Linear(20 * 10 * 10, 500)
self.fc2 = nn.Linear(500, 10)
def forward(self, x):
in_size = x.size(0)
out= self.conv1(x) # 1* 10 * 24 *24
out = F.relu(out)
out = F.max_pool2d(out, 2, 2) # 1* 10 * 12 * 12
out = self.conv2(out) # 1* 20 * 10 * 10
out = F.relu(out)
out = out.view(in_size, -1) # 1 * 2000
out = self.fc1(out) # 1 * 500
out = F.relu(out)
out = self.fc2(out) # 1 * 10
out = F.log_softmax(out, dim = 1)
return out
定义参数以及模型保存路径
必须要保存模型,不然每次使用都要重新训练
model = ConvNet().to(DEVICE)
loss_function = nn.CrossEntropyLoss()
params = [p for p in model.parameters() if p.requires_grad]
optimizer = optim.Adam(params, lr=0.001)
epochs = 50
train_steps = len(train_loader)
val_num = len(test_loader)
min_loss =10000
save_path = './model_saved/normal.pth'
开始训练
for epoch in range(epochs):
model.train()
running_loss = 0.0
acc = 0.0
total = 0.0
for step, data in enumerate(train_loader):
images, labels = data
optimizer.zero_grad()
logits = model(images.to(DEVICE))
loss = loss_function(logits, labels.to(DEVICE))
loss.backward()
optimizer.step()
running_loss += loss.item()
_, predicted = logits.max(1)
total += labels.size(0)
acc += predicted.eq(labels.to(DEVICE)).sum().item()
# if epoch % 10 == 0:
print("训练次数{},损失Loss为{},准确率为{}".format(epoch, running_loss,acc/total))
if running_loss < min_loss:
min_loss = running_loss
torch.save(model.state_dict(), save_path)
训练50次后就得到了我们需要的识别模型啦
五、开始识别
首先调用刚刚训练好的模型
weights_path = './model_saved/normal.pth'
model = ConvNet().to(DEVICE)
model.load_state_dict(torch.load(weights_path, map_location=DEVICE))
开始识别
is_right = False
while not is_right: #进入循环,即循环判断是否到达50秒
pyautogui.screenshot('Part.png',region=(930,962,14,22)) #(930,962,14,22)中930,962是读秒框框的左上角(x,y)坐标,14是930向右延伸14个像素点,22是962向下延伸22个像素点
img = cv2.imread('Part.png')
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转灰度
img = cv2.resize(img,(28,28))
img = transform(img)
img = torch.unsqueeze(img, dim=0)
model.eval()
with torch.no_grad():
# predict class
output = torch.squeeze(model(img.to(DEVICE))).cpu()
predict = torch.softmax(output, dim=0)
predict_cla = torch.argmax(predict).numpy()
if predict_cla == 5: #这里就是判断是否到50秒
#找到取消按钮
cancel = pyautogui.locateOnScreen('cancel.png',confidence=0.5)#confidence一定要加
posi = pyautogui.center(cancel)
pyautogui.doubleClick(posi) #记住此时编辑器窗口一定是置顶状态,游戏窗口是次级
speech.say("火男开始燃烧啦!快点点击开始游戏啊!")
# is_right = True
# print(predict_cla)
六、使用说明
首先一定一定一定要!以管理员身份运行你的python编辑器(VScode或者Pycharm都行),不然Pyautogui不起作用!
第一步,先打开窗口化好的永劫无间,点击开始游戏
第二步,开始运行你的代码,此时不要动,且编辑器窗口不要遮挡住游戏界面里的读秒位置和取消按钮位置
第三步,静等,若50秒都匹配不上则会自动帮你取消并提醒你继续开始游戏
七、演示
自动化解决永劫无间匹配超1分钟自动换服务器问题