Python 数据太复杂,模型无法学习?
目前,我正在为RTS游戏(确切地说是魔兽争霸III)的人工智能工作。我正在使用TFlearn来教模型如何自己玩游戏。我收集数据的方式如下:Python 数据太复杂,模型无法学习?,python,tensorflow,machine-learning,tflearn,Python,Tensorflow,Machine Learning,Tflearn,目前,我正在为RTS游戏(确切地说是魔兽争霸III)的人工智能工作。我正在使用TFlearn来教模型如何自己玩游戏。我收集数据的方式如下: [image array in grayscale] = [x-axis position of action, y-axis position of action, tokenized type of action] 例如,实际数据如下所示: [[[36] [39] [38] ... [12] [48] [65]] [[30]
[image array in grayscale] = [x-axis position of action, y-axis position of action, tokenized type of action]
例如,实际数据如下所示:
[[[36]
[39]
[38]
...
[12]
[48]
[65]]
[[30]
[48]
[ 0]
...
[34]
[49]
[ 8]]
[[28]
[29]
[23]
...
[93]
[38]
[53]]
...
[[ 0]
[ 0]
[ 0]
...
[ 0]
[ 0]
[ 4]]
[[ 0]
[ 0]
[ 0]
...
[ 0]
[ 0]
[ 0]]
[[ 0]
[ 0]
[ 0]
...
[60]
[19]
[43]]]=[1, 1, 35]
这意味着,在图像阵列(灰度)上显示的情况下,鼠标应设置在1-x和1-y位置,并应采取适当的动作(鼠标动作或键盘按下动作,取决于未调整的值)
尽管如此,我对正确的模型拟合有问题。我有30000帧,对于模型来说似乎太少,无法正确学习,因为在拟合模型后进行预测的情况下,它总是给出相同的输出:
[1,1,0]
我几乎可以肯定,这是因为需要学习的帧数很少。我正在尝试学习一个模型,大约60个动作和屏幕上的变化都不是太戏剧化,所以这真的是一组很难的数据。尽管如此,我还是想问,在这种情况下,是否有其他方法可以改进模型的学习。我试过:
import os
import cv2
import mss
import pyWinhook as pyHook
import pythoncom
import numpy as np
def get_screen():
with mss.mss() as sct:
screen = np.array(sct.grab((0, 0, 1366, 768)))
screen = cv2.cvtColor(screen, cv2.COLOR_BGR2GRAY)
screen = cv2.resize(screen, (136, 76))
return screen
def get_data():
# file names for training data arrays
file_name = 'training_data.npy'
copy_file_name = 'training_data_copy.npy'
# deciding if previous file with data is saved. If yes, it is opened. If not it's created
if os.path.isfile(file_name):
print('File exists, loading previous data!')
print(os.path.realpath(file_name))
training_data = list(np.load(file_name, allow_pickle=True))
np.save(copy_file_name, training_data)
else:
print('File does not exist, starting fresh!')
training_data = []
# saving data after acquiring 2500 sets of inputs and screenshots
def save_data(screen, output):
training_data.append([screen, output])
if len(training_data) % 2500 == 0:
print(len(training_data))
np.save(file_name, training_data)
print("Frames taken: " + str(len(training_data)))
index = len(training_data) - 1
print(training_data[index])
# getting inputs and screen on mouse event
def OnMouseEvent(event):
action = event.MessageName
screen = get_screen()
output = [event.Position, 0]
if action == 'mouse move':
output[1] = 'move'
elif action == 'mouse left down':
output[1] = 'left'
elif action == 'mouse right down':
output[1] = 'right'
save_data(screen, output)
return True
# getting inputs and screen on keyboard event
def OnKeyboardEvent(event):
if event == 'Delete':
np.save(file_name, training_data)
print("Save and exit")
exit()
screen = get_screen()
output = [(1,1), event.Key]
ctrl_pressed = pyHook.GetKeyState(pyHook.HookConstants.VKeyToID('VK_CONTROL'))
shift_pressed = pyHook.GetKeyState(pyHook.HookConstants.VKeyToID('VK_SHIFT'))
try:
if ctrl_pressed and int(pyHook.HookConstants.IDToName(event.KeyID)) in range(10):
output[1] = 'bind' + event.Key
except ValueError:
pass
try:
if shift_pressed and int(pyHook.HookConstants.IDToName(event.KeyID)) in range(10):
output[1] = 'add' + event.Key
except ValueError:
pass
save_data(screen, output)
return True
# create a hook manager
hm = pyHook.HookManager()
# watch for all mouse events
hm.MouseLeftDown = OnMouseEvent
hm.MouseRightDown = OnMouseEvent
#hm.MouseMove = OnMouseEvent
hm.KeyUp = OnKeyboardEvent
# set the hook
hm.HookMouse()
hm.HookKeyboard()
# wait forever
try:
pythoncom.PumpMessages()
except KeyboardInterrupt:
pass
# looping getting data
while True:
pass
这是我的模型配置:
import tflearn
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.estimator import regression
from tflearn.layers.normalization import local_response_normalization
import tensorflow as tf
def trainingmodel(width, height, lr):
network = input_data(shape=[None, width, height, 1], name='input')
network = conv_2d(network, 96, 11, strides=4, activation='relu')
network = max_pool_2d(network, 3, strides=2)
network = local_response_normalization(network)
network = conv_2d(network, 256, 5, activation='relu')
network = max_pool_2d(network, 3, strides=2)
network = local_response_normalization(network)
network = conv_2d(network, 384, 3, activation='relu')
network = conv_2d(network, 256, 3, activation='relu')
network = max_pool_2d(network, 3, strides=2)
network = local_response_normalization(network)
network = fully_connected(network, 4096, activation='tanh')
network = dropout(network, 0.25)
network = fully_connected(network, 3, activation='softmax')
sgd = tflearn.optimizers.SGD(learning_rate=0.01, lr_decay=0.96, decay_step=100)
network = regression(network, optimizer='adam',
loss='categorical_crossentropy',
learning_rate=lr, name='targets')
model = tflearn.DNN(network, checkpoint_path='model_training_model',
max_checkpoints=1, tensorboard_verbose=2, tensorboard_dir='log')
return model
我不确定你想用图片做的事情是否可行。我已经看到这适用于超级马里奥兄弟,但WC3是一种更复杂的情况。为了得到正确的结论,你需要每个角色的每个动作的图片
您的模型可能无法处理未向其显示的情况(以类似的方式)。您可以尝试使用模板匹配来提取角色的动作,并在(x,y)位置而不是CNN图像上教授模型。假设我只想将其限制为一场比赛。我知道这有点复杂,但要教这个模型还是太多了?我认为这太复杂了。模型必须了解游戏如何运作的基本概念。这对于国际象棋或跳棋来说更容易,但对于WC3,模型还需要学习很多其他东西(许多不同的角色、它们的优点、背景)。你的模型必须知道图像的时间序列(递归神经网络)。你可以很容易地开始,看看它会把你引向何方。取一个字符并在屏幕上移动。然后使用这些框架过度拟合您的模型。一旦成功(它应该),你可能会意识到让一个模特玩它有多困难。以及您需要的培训数据量。当您为网络设计层时,您对层的大小和顺序有何想法?老实说,这是一个反复试验的过程。我的出发点是GTAV自驾教程中的图层设置。然后,为了防止过度拟合,我删除了一层又一层,然后放弃了配置它们,当它没有给出任何结果时,试图知道这是否可行。作为一个非常小的注释,您应该规范化输入数据。使用[-1.0,1.0]或[0.0,1.0]比使用[0255]容易得多。(但可能还是太难了。)