python - 贪吃蛇游戏的深度 Q 学习

标签 python keras deep-learning reinforcement-learning q-learning

我正在做一个基于 Keras Plays Catch 的项目代码。我已将游戏更改为简单的贪吃蛇游戏,为了简单起见,我在棋盘上用一个点表示蛇。如果 Snake 吃了奖励,它将获得 +5 分,如果撞墙,它将获得 -5 分,每移动一次 -0.1 分。但它没有学习策略并给出了可怕的结果。这是我的游戏 play 函数

def play(self, action):
    if action == 0:
        self.snake = (self.snake[0] - 1, self.snake[1])
    elif action == 1:
        self.snake = (self.snake[0], self.snake[1] + 1)
    elif action == 2:
        self.snake = (self.snake[0] + 1, self.snake[1])
    else:
        self.snake = (self.snake[0], self.snake[1] - 1)

    score = 0
    if self.snake == self.reward:
        score = 5
        self.setReward()
    elif self.isGameOver():
        score = -5
    else:
        score = -0.1

    return self.getBoard(), score, self.isGameOver()

返回类似这样的东西(1 是蛇,3 是奖励,2 代表墙):

 [[2. 2. 2. 2. 2. 2. 2. 2. 2. 2.]
 [2. 0. 0. 0. 0. 0. 0. 0. 0. 2.]
 [2. 0. 0. 0. 0. 0. 0. 0. 0. 2.]
 [2. 0. 0. 0. 0. 0. 0. 0. 0. 2.]
 [2. 0. 0. 0. 0. 0. 0. 0. 0. 2.]
 [2. 0. 0. 0. 0. 1. 0. 0. 0. 2.]
 [2. 0. 0. 0. 0. 0. 3. 0. 0. 2.]
 [2. 0. 0. 0. 0. 0. 0. 0. 0. 2.]
 [2. 0. 0. 0. 0. 0. 0. 0. 0. 2.]
 [2. 2. 2. 2. 2. 2. 2. 2. 2. 2.]]

这是my code for q learning on gist .

我不知道我做错了什么,但它玩的大多数游戏都会卡在一个循环中(上下或左右),或者它会直接撞到墙上,而且有很小的机会在它撞到墙上之前吃掉奖励。我怎样才能改进它并使其发挥作用?

最佳答案

如果您的蛇从未达到奖励,它可能永远不会获得 +5 分。不是每次移动使用恒定的 0.1 惩罚,而是对每个图 block 使用基于距离的成本可能会有所帮助。换句话说,您游戏中的智能体并不知道​​奖励的存在。

我认为最终你会得到类似 A* path finding 的结果.至少启发式是相似的。


更新:

考虑到您发布的完整代码,您的损失函数和分数不匹配!当分数高时,模型的损失是随机的。

尝试将游戏得分最大化作为您的目标。

关于python - 贪吃蛇游戏的深度 Q 学习,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54302176/

相关文章:

python - 如何登录/注销 Facebook 用户到 Facebook 应用程序?

python - 从 pandas 的已知索引中获取行数据

python - Keras fit_generator 一次训练一个样本,而我从生成器中生成多个样本

TensorFlow 多标签准确度指标

python - Keras 推理损失和前向传播不匹配

python - 模块 'tensorflow.python.keras.api._v2.keras.layers' 没有属性 'CuDNNLSTM'

python - 来自 Transformers 的 BertForSequenceClassification 的大小不匹配和多类问题

python - 使用 Python 请求,我可以将 "data"添加到准备好的请求中吗?

python - 在 python 中,函数应该更改列表还是制作副本并返回?

deep-learning - 法泰 : ValueError: __len__() should return >= 0