Данные слишком сложны для изучения модели? - PullRequest
0 голосов
/ 25 октября 2019

В настоящее время я работаю над искусственным интеллектом для игры 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 действий и изменения на экране не слишком драматичны, поэтому это действительно сложный набор данных. Тем не менее я хотел бы спросить, есть ли другие способы улучшить изучение модели в таком случае. Я пробовал:

  1. Снижение скорости обучения (до 1e ^ 5)
  2. Количество различных методов активации / оптимизаторов / слоев в конфигурации модели
  3. Изменение количества действийучиться (например, я выбросил действия перемещения из пула обучения)

Вот как я получаю данные:

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

1 Ответ

0 голосов
/ 25 октября 2019

Я не уверен, что то, что вы пытаетесь сделать, вообще возможно с помощью картинок. Я видел, что это применимо к Super Mario Brothers, но WC3 - более сложный сценарий. Чтобы получить правильные выводы, вам понадобятся картинки каждого хода для каждого персонажа.

Ваша модель, вероятно, не сможет справиться с ситуациями, которые ей не показывались (аналогичным образом). Вы можете попытаться извлечь движения для персонажей, используя сопоставление с шаблоном, и научить модель позициям (x, y) вместо изображений с CNN.

...