需要帮助设计基于NEAT算法的神经网络的适应度评估

mjo*_*dri 14 python algorithm machine-learning fitness python-2.7

我正在研究基于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
Run Code Online (Sandbox Code Playgroud)

以下是我认为健身计算应该做的,语义上:

  • 显然,得分应该对整体健康产生最显着的影响.也许得分为0会对健身产生轻微的负面影响吗?
  • 每次击球击球的次数应该有一定的效果,但不是贡献/重量的重要性.例如,如果这个数字是0,它在那一生中根本没有真正尝试击球,所以它应该有负面影响
  • 球拍击球总数的次数也应该有一些效果,其贡献应该基于得分.例如,如果它没有多次击球并且也没有得分很多,则应该产生显着的负面影响; 如果它没有多次击球,但得分高,那应该会产生显着的积极影响.总的来说,(我认为)这个值越接近于游戏得分,这个值对健身的贡献/重量就越小
  • 在框架中心和桨叶中心之间沿X方向的平均距离应基本上鼓励桨叶的中央"静止"位置
  • 如果游戏由于陈旧而人为地结束,或者这应该具有显着的负面影响,或者它应该自动强制适应度为0.0; 我不确定哪种情况会更好

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

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

mat*_*000 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
Run Code Online (Sandbox Code Playgroud)

(旁白:我没有包括“距画面中心的距离”,因为我认为这是作弊;如果为了最大限度地提高游戏效率,保持在中心附近是一件好事,那么代理应该自己了解这一点。如果你偷偷摸摸将所有智能都投入到适应度函数中,那么您的代理根本就不智能。)