在 python 中设置可变数量的输入节点

set variable number of input nodes in python neat

我有一个简单的游戏,其中有一个球在屏幕上弹跳,玩家可以在屏幕左右移动并向上射箭弹出球,每次玩家击球时,球爆裂并分裂成两个较小的球,直到它们达到最小尺寸并消失。 我正在尝试使用基于 python neat 库的遗传算法和关于 flappy bird https://www.youtube.com/watch?v=MMxFDaIOHsE&list=PLzMcBGfZo4-lwGZWXz5Qgta_YNX3_vLS2 的本教程来解决这个游戏,所以我有一个配置文件,我必须在其中指定有多少输入节点必须在网络中,我曾想将玩家的 x 坐标、玩家的 x 坐标与球的 x 坐标之间的距离以及玩家的 y 坐标与球的 y 坐标之间的距离作为输入。

我的问题是,在游戏开始时我只有一个球,但经过几次移动后屏幕上可能会有更多球,所以我应该有更多的输入节点,球上的球越多屏幕越多,我必须提供给网络的输入坐标越多。

那么如何可变的设置输入节点个数呢?

配置-feedforward.txt文件

"""
# network parameters
num_hidden              = 0
num_inputs              = 3 #this needs to be variable
num_outputs             = 3
"""

python 文件

    for index,player in enumerate(game.players):
        balls_array_x = []
        balls_array_y = []

        for ball in game.balls:
            balls_array_x.append(ball.x)
            balls_array_x.append(ball.y)




        output = np.argmax(nets[index].activate(("there may be a number of variable arguments here")))


        #other...

最终代码

for index,player in enumerate(game.players):
    balls_array_x = []
    balls_array_y = []

    for ball in game.balls:
        balls_array_x.append(ball.x)
        balls_array_y.append(ball.y)

  
    distance_list = []
    player_x = player.x
    player_y = player.y
    
    i = 0

    while i < len(balls_array_x):
        dist = math.sqrt((balls_array_x[i] - player_x) ** 2 + (balls_array_y[i] - player_y) ** 2)
        distance_list.append(dist)
        i+=1

    i = 0

    if len(distance_list) > 0:
        nearest_ball = min(distance_list)

        output = np.argmax(nets[index].activate((player.x,player.y,nearest_ball)))

这是一个很好的问题,据我快速搜索 Google 可以看出,像 NEAT 这样的简单 ML 算法还没有解决。

Deep NN 的传统大小调整方法(填充、裁剪、RNN、middle-layers 等)显然不能在这里应用,因为 NEAT 显式编码每个神经元和连接。

我也不知道有什么通用的 method/trick 可以使传统 NEAT 算法的输入大小可变,坦率地说,我认为没有。虽然我可以想到对算法进行一些更改来实现这一点,但我想这对你没有帮助。


因此我认为您有 3 个选择:

  • 您将输入大小增加到算法应跟踪的最大球数,并将 non-existent 个球的 x-diff/y-diff 值设置为不可能的数字(例如 -1 ).如果球出现,你实际上设置了那些 x-diff/y-diff 输入神经元的值,并在它们消失时再次将它们设置为 -1。然后让 NEAT 解决。同样值得考虑连接 2 个独立的 NEAT NN,第一个 NN 有 2 个输入,1 个输出,第二个 NN 有 1(玩家位置)+ x(最大球数)输入和 2 个输出(左,右)。第一个 NN 为每个球位置生成一个输出(并且每个球都相同),第二个 NN 获取第一个 NN 的输出并将其转化为一个动作。另外:最大球数不一定是最大可显示球数,也可以限制为10个,只考虑最近的10个球。

  • 您只考虑每个动作方 1 个球(使您的输入为 1 + 2*2)。这可能是考虑每侧最低的球或每侧最近的球。这样的预处理可以使如此简单的 NN 任务变得非常容易解决。也许您可以在您的测试环境中添加惯性,从而添加一个 non-linearity,这使得总是 teleport/hurry 到最低的球不是那么简单。

  • 您将整个观察结果 space 输入 NEAT(或均匀下采样的分数),例如整个游戏在任何分辨率下都是最低但仍然合理的。我知道这个观察 space 是巨大的,但是 NEAT 在处理这样的 space 方面效果很好。


我知道这不是您可能希望的 NEAT 的可变输入大小选项,但我不知道有任何这样的通用选项option/trick在不显着改变底层 NEAT 算法的情况下。

不过,如果有人知道更好的选择,我很乐意得到纠正!