В настоящее время я работаю над искусственным интеллектом для игры RTS (точнее, Warcraft 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]
[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 действий и изменения на экране не слишком драматичны, поэтому это действительно сложный набор данных. Тем не менее я хотел бы спросить, есть ли другие способы улучшить изучение модели в таком случае. Я пробовал:
- Снижение скорости обучения (до 1e ^ 5)
- Количество различных методов активации / оптимизаторов / слоев в конфигурации модели
- Изменение количества действийучиться (например, я выбросил действия перемещения из пула обучения)
Вот как я получаю данные:
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