问题描述
我有一个简单的游戏,屏幕上有一个弹跳的球,并且玩家可以左右移动屏幕并向上射箭以弹出球,每次玩家击球时,球都会爆裂并分成两个较小的球,直到达到最小尺寸并消失。 我正在尝试使用一种基于python整洁库的遗传算法以及关于本片关于https://www.youtube.com/watch?v=MMxFDaIOHsE&list=PLzMcBGfZo4-lwGZWXz5Qgta_YNX3_vLS2的本教程的遗传算法来解决该游戏,因此我有一个配置文件,其中我必须指定在该文件中必须有多少个输入节点。网络中,我曾想过要输入玩家的x坐标,玩家的x坐标与球的x坐标之间的距离以及玩家的y坐标与球的y坐标之间的距离。
我的问题是,在游戏开始时,我只有一个球,但是经过几步移动后,屏幕上可能会有更多的球,所以我应该有更多的输入节点,屏幕上的球也更多我必须提供给网络的输入坐标越多。
那么如何以可变方式设置输入节点的数量呢?
"""
# 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)))
解决方法
这是一个很好的问题,据我所知,对于像NEAT这样的简单ML算法,谷歌搜索还没有解决。
由于NEAT会显式地编码每个单个神经元和连接,因此显然无法在此处应用深度NN的传统大小调整方法(填充,裁剪,RNN,中间层等)。
我也不知道有什么通用的方法/技巧可以使输入大小对传统的NEAT算法变得可变,坦率地说,我认为没有。尽管我可以想到对算法的一些更改,使之成为可能,但是我认为这对您没有帮助。
因此,我认为您有3种选择:
-
将输入大小增加到算法应跟踪的最大球数,并将不存在的球的x-diff / y-diff值设置为其他不可能的数字(例如-1)。如果存在球,则实际上为这些x-diff / y-diff输入神经元设置值,并在它们消失时再次将其设置为-1。然后让NEAT弄清楚。同样值得考虑的是连接2个单独的NEAT NN,第一个NN具有2个输入,1个输出,第二个NN具有1个(玩家pos)+ x(最大球数)输入和2个输出(左,右)。第一个NN为每个球的位置生成一个输出(并且每个球都相同),第二个NN获取第一个NN的输出并将其转换为动作。另外:最大球数不必一定是可显示球的最大数,但也可以限制为10,并且仅考虑10个最接近的球。
-
每个动作侧只考虑1个球(使输入1 + 2 * 2)。可以考虑每侧最低的球或每侧最近的球。这样的预处理可以使这样简单的NN任务变得很容易解决。也许您可以在测试环境中增加惯性,从而增加非线性度,使其始终总是传送/急转至最低球并不是那么容易。
-
您将整个观测空间输入到NEAT(或统一下采样的分数)中,例如整个游戏,无论分辨率如何,最低但仍然明智。我知道这个观察空间很大,但是NEAT在处理这样的空间时效果很好。
我知道这不是您可能希望的NEAT的可变输入大小选项,但是在不显着更改底层NEAT算法的情况下,我不知道任何此类常规选项/技巧
但是,如果有人知道更好的选择,我很高兴得到纠正!