Python机器学习之游戏自动驾驶(三)

编程入门 行业动态 更新时间:2024-10-15 12:32:40

Python<a href=https://www.elefans.com/category/jswz/34/1771242.html style=机器学习之游戏自动驾驶(三)"/>

Python机器学习之游戏自动驾驶(三)

3. 如何进行测试

在测试阶段关键在于如何通过python对电脑发出相应的按键操作,因为我们的目的是让神经网络根据游戏的画面给出对应的操作,要想给出对应的操作也需要用到最开始所说的win32包,下面给出发送按键操作指令的代码

import ctypes
import timeSendInput = ctypes.windll.user32.SendInputW = 0x11
A = 0x1E
S = 0x1F
D = 0x20# C struct redefinitions
PUL = ctypes.POINTER(ctypes.c_ulong)class KeyBdInput(ctypes.Structure):_fields_ = [("wVk", ctypes.c_ushort),("wScan", ctypes.c_ushort),("dwFlags", ctypes.c_ulong),("time", ctypes.c_ulong),("dwExtraInfo", PUL)]class HardwareInput(ctypes.Structure):_fields_ = [("uMsg", ctypes.c_ulong),("wParamL", ctypes.c_short),("wParamH", ctypes.c_ushort)]class MouseInput(ctypes.Structure):_fields_ = [("dx", ctypes.c_long),("dy", ctypes.c_long),("mouseData", ctypes.c_ulong),("dwFlags", ctypes.c_ulong),("time",ctypes.c_ulong),("dwExtraInfo", PUL)]class Input_I(ctypes.Union):_fields_ = [("ki", KeyBdInput),("mi", MouseInput),("hi", HardwareInput)]class Input(ctypes.Structure):_fields_ = [("type", ctypes.c_ulong),("ii", Input_I)]# Actuals Functionsdef PressKey(hexKeyCode):extra = ctypes.c_ulong(0)ii_ = Input_I()ii_.ki = KeyBdInput(0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra))x = Input(ctypes.c_ulong(1), ii_)ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))def ReleaseKey(hexKeyCode):extra = ctypes.c_ulong(0)ii_ = Input_I()ii_.ki = KeyBdInput(0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra))x = Input(ctypes.c_ulong(1), ii_)ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))if __name__ == '__main__':for i in list(range(3))[::-1]:print(i + 1)time.sleep(1)PressKey(W)time.sleep(1)ReleaseKey(W)time.sleep(1)

这里面两个关键的函数就是PressKey和ReleaseKey,前面的是用来进行按下按键操作,后面的是用来进行释放按键的操作。

有了上述两个函数我们就可以让神经网络来自动驾驶了。下面给出代码

import cv2
import numpy as np
import time
import win32api
import win32con
import win32gui
import win32ui
from send_key import PressKey, ReleaseKey, W, A, S, D
import torch.nn as nn
import torch.nn.functional as func
import torch
from get_key import key_checkdef grab_screen(region=None):h_win = win32gui.GetDesktopWindow()if region:left, top, x2, y2 = regionwidth = x2 - left + 1height = y2 - top + 1else:width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)h_windc = win32gui.GetWindowDC(h_win)srcdc = win32ui.CreateDCFromHandle(h_windc)memdc = srcdc.CreateCompatibleDC()bmp = win32ui.CreateBitmap()bmp.CreateCompatibleBitmap(srcdc, width, height)memdc.SelectObject(bmp)memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY)signed_ints_array = bmp.GetBitmapBits(True)img = np.frombuffer(signed_ints_array, dtype='uint8')img.shape = (height, width, 4)img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)srcdc.DeleteDC()memdc.DeleteDC()win32gui.ReleaseDC(h_win, h_windc)win32gui.DeleteObject(bmp.GetHandle())return imgclass Net(nn.Module):def __init__(self):super().__init__()self.conv1 = nn.Conv2d(1, 48, kernel_size=11, stride=4)self.pool = nn.MaxPool2d(3, 2)self.conv2 = nn.Conv2d(48, 128, kernel_size=5, padding=2, groups=2)self.conv3 = nn.Conv2d(128, 64, kernel_size=3, padding=1)self.fc1 = nn.Linear(64*6*6, 2048)self.dropout = nn.Dropout(0.3)self.fc2 = nn.Linear(2048, 1024)self.fc3 = nn.Linear(1024, 3)def forward(self, x):                         # x = (batch, 1, 227, 227)x = x.view(-1, 1, 227, 227)x = self.pool(func.relu(self.conv1(x)))   # -> (batch, 48, 55, 55) -> (batch, 48, 27, 27)x = self.pool(func.relu(self.conv2(x)))   # -> (batch, 128, 27, 27) -> (batch, 128, 13, 13)x = self.pool(func.relu(self.conv3(x)))   # -> (batch, 64, 13, 13) -> (batch, 64, 6, 6)x = x.view(-1, 64*6*6)                   # -> (batch, 64*6*6)x = self.dropout(x)x = func.relu(self.fc1(x))                # -> (batch, 2048)x = self.dropout(x)x = func.relu(self.fc2(x))                # -> (batch, 1024)x = self.fc3(x)                           # -> (batch, 3)return xnet = Net()
net.load_state_dict(torch.load('net_state_dict.pkl', map_location=torch.device('cpu')))if __name__ == '__main__':net.eval()for i in list(range(4))[::-1]:print(i + 1)time.sleep(1)last_time = time.time()pause = Falsewhile True:if not pause:PressKey(W)screen = grab_screen(region=(170, 50, 850, 600))screen = cv2.resize(screen, (227, 227))out_tensor = func.softmax(net(torch.tensor(screen, dtype=torch.float)), dim=1)print('[%.2f, %.2f, %.2f]' %(out_tensor[-1, 0].item(), out_tensor[-1, 1].item(), out_tensor[-1, 2].data.item()))out_tensor1 = torch.argmax(out_tensor)out = out_tensor1.item()print('Frame took {} seconds'.format(time.time() - last_time))last_time = time.time()if out == 0:PressKey(A)ReleaseKey(D)print('left')elif out == 1 and out_tensor[-1, 1] >= 0.9:PressKey(D)ReleaseKey(A)print('right')else:ReleaseKey(A)ReleaseKey(D)print('forward')key = key_check()if 'T' in key:ReleaseKey(W)ReleaseKey(A)ReleaseKey(D)if pause:pause = Falseprint('Running!')time.sleep(1)else:print('Stopping!')pause = Truetime.sleep(1)

在这个代码中,我当时写的有几点我要说明一下,首先就是dropout我当时的处理是在测试时直接删除网络中的dropout层,这么做不太妥当,正确的做法应该是在训练时加上net.train(),而在测试时加上net.eval(),这样pytorch会自动屏蔽掉dropout和batchnorm。第二点就是由于我的训练数据不是太多,加上电脑性能不行,所以训练出来的网络效果可能没那么好,我在测试的时候也发现了问题,所以我就在测试代码中把那些神经网络不太确定的帧进行了屏蔽,直接改为了直行。修改后测试的效果有一定的提升。

更多推荐

Python机器学习之游戏自动驾驶(三)

本文发布于:2024-03-05 17:48:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1712965.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:机器   游戏   Python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!