【问题标题】:Need help designing fitness evaluation for a NEAT algorithm-based neural network需要帮助为基于 NEAT 算法的神经网络设计适应度评估
【发布时间】:2017-04-14 00:28:48
【问题描述】:

我正在研究一个基于 NEAT algorithm 的神经网络,该网络学习在 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,那么它甚至没有真正尝试击球,所以它应该会产生负面影响
  • 桨击球的次数total也应该有一些影响,其贡献应该基于得分。例如如果它没有多次击球,也没有获得多少分,那应该会产生显着的负面影响;如果它没有多次击球但得分很高,那应该会产生显着的积极影响。总的来说,(我认为)这个值越接近游戏得分,这个值对适应度的贡献/权重就越小
  • 在 X 方向上框架中心和桨中心之间的平均距离应该基本上鼓励桨的中心“休息”位置
  • 如果游戏因过时而人为结束,要么这会产生显着的负面影响,要么会自动强制适应度为 0.0;我不确定哪种情况会更好

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

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

【问题讨论】:

  • 也许健身的最佳标准类似于以下内容:(得分/击球次数)- 未击球次数。 IE。您希望最大限度地提高每次击球的得分并尽量减少未击球的次数。
  • 您应该首先定义您认为“玩得好”对游戏意味着什么,然后才能合理地为其定义适应度函数。您想按照 Alex 的建议最大化每次击球的得分吗?
  • @Alex 我最初有这么简单的东西,但它导致它的行为似乎是如果它从一次桨击中击中超过一个挡块就会故意错过球,并且会得到陷入该局部最小值;我不知道如何帮助它摆脱这个最小值,所以我慢慢开始让适应度函数变得越来越复杂,希望能解决这个问题。
  • @mjones.udri 鉴于一次击球击打超过一个挡块有助于最大化“每次击球得分”,而“故意错过球”对“每次击球得分”和最大限度地减少桨未命中的次数。除非由于某些错误,否则我不太了解您所描述的行为。
  • @Alex 它是本地最小值。假设它打破了足够多的积木,让球能够越过积木墙,然后在积木和天花板之间弹跳几次;发生这种情况的最小桨击数为 3(因为有 3 排砖)。然后它看到它只击中了 4 次球并打破了一堆砖块,所以score / (num_paddle_hits) 是一个高比例,所以它然后故意错过(至少,它做了一些 看起来 喜欢的行为它是故意丢失的)。

标签: python algorithm python-2.7 machine-learning fitness


【解决方案1】:

我会尽量减少适应度函数中的条件逻辑,仅在您希望将适应度得分强制为 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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    • 2020-03-27
    • 2011-02-28
    • 1970-01-01
    • 2018-04-30
    • 2011-04-07
    • 2013-06-30
    相关资源
    最近更新 更多