Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 数据太复杂,模型无法学习?_Python_Tensorflow_Machine Learning_Tflearn - Fatal编程技术网

Python 数据太复杂,模型无法学习?

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]

目前,我正在为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]
  [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
    

    我不确定你想用图片做的事情是否可行。我已经看到这适用于超级马里奥兄弟,但WC3是一种更复杂的情况。为了得到正确的结论,你需要每个角色的每个动作的图片


    您的模型可能无法处理未向其显示的情况(以类似的方式)。您可以尝试使用模板匹配来提取角色的动作,并在(x,y)位置而不是CNN图像上教授模型。

    假设我只想将其限制为一场比赛。我知道这有点复杂,但要教这个模型还是太多了?我认为这太复杂了。模型必须了解游戏如何运作的基本概念。这对于国际象棋或跳棋来说更容易,但对于WC3,模型还需要学习很多其他东西(许多不同的角色、它们的优点、背景)。你的模型必须知道图像的时间序列(递归神经网络)。你可以很容易地开始,看看它会把你引向何方。取一个字符并在屏幕上移动。然后使用这些框架过度拟合您的模型。一旦成功(它应该),你可能会意识到让一个模特玩它有多困难。以及您需要的培训数据量。当您为网络设计层时,您对层的大小和顺序有何想法?老实说,这是一个反复试验的过程。我的出发点是GTAV自驾教程中的图层设置。然后,为了防止过度拟合,我删除了一层又一层,然后放弃了配置它们,当它没有给出任何结果时,试图知道这是否可行。作为一个非常小的注释,您应该规范化输入数据。使用[-1.0,1.0]或[0.0,1.0]比使用[0255]容易得多。(但可能还是太难了。)