14

我正在研究一个基于NEAT 算法的神经网络,该算法学习在 Python 2.7 中播放Atari Breakout克隆,并且我已经完成了所有工作,但我认为使用更好的算法来计算物种适应度可以大大改善进化.

神经网络的输入是:

  • 桨中心的X坐标
  • 球心的X坐标
  • 球心的Y坐标
  • 球的 dx(X 方向的速度)
  • 球的 dy(Y 方向的速度)

输出是:

  • 向左移动桨
  • 向右移动桨
  • 不要移动桨

我可用于物种适应度计算的参数是:

  • breakout_model.score- int:该物种所玩游戏的最终得分
  • breakout_model.num_times_hit_paddle- int:球拍击球的次数
  • breakout_model.hits_per_life- : 桨在生命int中击球的次数,以列表的形式;例如,第一个元素是第一个生命的值,第二个元素是第二个生命的值,依此类推,直到 4
  • breakout_model.avg_paddle_offset_from_ball- decimal:球与桨中心在 X 方向上的平均直线距离
  • breakout_model.avg_paddle_offset_from_center- decimal:框架中心和桨中心之间 X 方向的平均直线距离
  • breakout_model.time- int:游戏的总时长,以帧为单位
  • breakout_model.stale- boolean:游戏是否因陈旧而人为终止(例如,球被卡住直接垂直弹跳并且桨不动)

如果您认为我需要更多关于游戏最终状态的数据而不仅仅是这些数据,我可能会实施一种方法来非常容易地获得它。

这是我目前的健身计算,我认为这不是很好:

def calculate_fitness(self):
    self.fitness = self.breakout_model.score
    if self.breakout_model.num_times_hit_paddle != 0:
        self.fitness += self.breakout_model.num_times_hit_paddle / 10
    else:
        self.fitness -= 0.5
    if self.breakout_model.avg_paddle_offset_from_ball != 0:
        self.fitness -= (1 / self.breakout_model.avg_paddle_offset_from_ball) * 100
    for hits in self.breakout_model.hits_per_life:
        if hits == 0:
            self.fitness -= 0.2
    if self.breakout_model.stale:
        self.fitness = 0 - self.fitness
    return self.fitness

这是我认为适应度计算应该做的,语义上:

  • 显然,分数应该对整体适应度产生最显着的影响。也许0分应该会对健康产生轻微的负面影响?
  • 桨每生命击球的次数应该有一些影响,但对贡献/重量没有那么重要。例如,如果该数字为 0,则它甚至没有真正尝试击球,因此它应该有负面影响
  • 桨击球的次数也应该有一定的影响,其贡献应该基于得分。例如,如果它没有多次击球,也没有得分很多,那应该会产生显着的负面影响;如果它没有多次击球但得分很高,那应该会产生显着的积极影响。总的来说,(我认为)这个值越接近游戏得分,这个值对适应度的贡献/权重就越小
  • 框架中心和桨中心之间的 X 方向平均距离应该基本上鼓励桨的中心“休息”位置
  • 如果游戏因陈旧而人为结束,要么这应该有显着的负面影响,要么应该自动强制适应度为 0.0;我不确定哪种情况会更好

我不确定如何对所有这些值进行操作以使它们适当地影响整体适应度。

提前感谢您提供的任何帮助。

4

1 回答 1

2

我将最小化您的适应度函数中的条件逻辑,仅在您希望将适应度得分强制为 0 或重大惩罚的情况下使用它。我只是决定分数的每个组成部分应该有多少权重并相乘。负分量只会增加理解适应度函数的复杂性,并没有真正的好处;该模型从分数的相对差异中学习。所以我的函数版本看起来像这样:

def fitness(...):
    if total_hits == 0:
        return 0
    return (game_score/max_score) * .7 \
           + game_score/total_hits * .2 \
           + game_score_per_life/hits_per_life * .1

(顺便说一句:我没有包括“距画面中心的距离”,因为我认为那是作弊;如果保持靠近中心是为了最大限度地提高游戏效率,那么代理应该自己学习。如果你偷偷摸摸所有的智能都融入了适应度函数,那么你的代理根本就不智能。)

于 2017-01-17T19:45:47.493 回答