python - 使用随机游戏数据进行监督学习

标签 python tensorflow machine-learning keras

目标

我对机器学习相当陌生,经过一些在线教育,这是我的第一个真正的项目。这是一种名为 Ouril 的游戏,您和对手各有六座“房子”,其中有四颗起始石。你交替玩一个房子并分配它的棋子,这可能会导致你吃掉对手的棋子。捕获 25 颗 gem 即可获胜。

该项目的目标是拥有一个训练有素的函数,可以在给定当前游戏状态的情况下预测一步棋的好坏,以便机器人可以选择最佳预测的棋步并进行操作。

设置

我构建了一些非人工智能机器人(随机机器人、最大机器人、最小最大机器人),并让它们互相玩很多游戏。游戏将每个下棋 Action 记录到一个 json 文件中。我使用记录的移动来训练具有 Tensorflow 后端的 Keras 模型。该模型由一些具有 sigmoid 激活函数的密集层组成,因为我希望预测值在 -1 到 1 之间。

model = Sequential()
model.add(Dense(12, input_shape=(15,), init='uniform', activation='sigmoid'))
model.add(Dense(12, init='uniform', activation='sigmoid'))
model.add(Dense(1, init='uniform', activation='sigmoid'))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])

训练数据

游戏中的每一步都会这样记录:[4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 0, 0, 0] 前12个字段是每个房子的棋子数量,然后是这一步正在玩的房子,然后是我和对手当前的得分,最后是这一步的得分。

起初,我将一步棋的得分简单地定义为该步棋所捕获的棋子的数量。我根据这些数据训练模型,准确率达到了 0.7 左右。我确信这可以改进,但是有了这种数据,模型的最高预测将与我已有的 max-bot 一样好。

所以我让分数取决于玩家的下一步 Action 。如果玩家一步拿走 4 个房子,他的前三个分数会增加 2、1 和 0.5,而对手最后的分数也会相应减少。

问题

使用这个新的训练数据,我只能得到大约 0.1 的准确度。

我认为这是因为新数据更加同质(分数更接近 0),而且还因为在该数据中,同一 Action 可能有许多不同的分数。

由于这是一个非常广泛的问题,因此这里有一些具体的问题:

  • 有更好的方法来表示我的数据中的分数吗?
  • 我的模型中还需要其他层吗?还有其他参数吗?
  • mean_squared_error 是该问题的拟合损失函数吗?
  • Keras 是否是解决此问题的错误工具(也许是线性回归?)

谢谢

<小时/>

来源:https://github.com/sra448/ouril-game/blob/master/learning/learn.py

最佳答案

The goal of this project is to have a trained function that predicts how good a move is, given the current game state, so that the bot can pick the best predicted move and play it.

实现此目的的一种方法是将游戏数据库中的每个 Action 作为输入示例,并使用游戏的结果(+1 或 -1)作为每个示例的标签。

这种方法的优点是,您不必尝试和设计有关移动的特征,例如它捕获了多少石头 - 这可能相关也可能不相关。

缺点是每个单独的 Action 对最终游戏结果的预测能力很弱,因为它可能相关,也可能不相关。为了平衡这一点,您需要大量的训练数据。

另一个弱点是您的机器人可能永远不会执行某些类型的 Action ,因此它们不会出现在您的训练集中。为了避免这个问题,您可能需要为机器人的 Action 添加一些随机性。这是 AlphaGo 最新迭代中使用的方法。

当然,您可以结合这两种方法并使用最终的游戏结果作为训练标签,但也可以包括捕获了多少石子等特征。这样模型就可以自己决定这些特征的重要性。

Is there a better way to represent the score in my data?

您当前的表示存在一个大问题:您将搬家位置编码为房屋号码。你的神经网络将不知道如何正确解释这一点。您应该改用 one-hot 编码。

您还提到每次移动都会分配石子,但我不明白您如何对石子的分布进行编码。

我会考虑以下编码:

[4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] # houses
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0] # move origin
[0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0] # move destinations / #of stones at each
[0, 0, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0] # capture locations / sizes

如果特定的编码不代表合法的举动,请原谅我 - 我不完全理解规则。希望您应该明白这个想法。

您可以使用这四个数组作为一维卷积神经网络的单个输入中的 channel 。我相信 CNN 在这里会表现得更好,因为它更擅长捕捉局部结构。

Is mean_squared_error a fitting loss function for this problem?

是的。

最后一点:您获得的准确性并不能很好地表明您的值(value)函数有多好。更重要的是它如何对彼此之间的潜在移动进行评分。真正的测试是当您插入值(value)网络来评估 Action 时,您的机器人的表现如何。

编辑: 最后一点:考虑构建一个 MCTS机器人。您可以仅根据游戏规则构建它(几乎不需要或不需要策略知识),它应该比您拥有的强大得多,并且应该为您的值(value)网络项目提供更好的培训数据。

关于python - 使用随机游戏数据进行监督学习,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48853066/

相关文章:

python - 在 Scipy 中将 csr 矩阵列的每个元素相乘

python - 对 Tensorflow 中保存/恢复经过训练的权重和偏差感到困惑

python - TF : how to solve ValueError: Variable . ..重量已经存在,不允许。您是要设置 reuse=True

如果 __init__ 中没有变量,Pythonic 方式设置变量

tensorflow - 如何在Tensorflow中检查张量是否为空

c++ - 如何从 C++ 使用 Keras SavedModel

python - 运行时错误: Assertion `cur_target >= 0 && cur_target < n_classes' failed

python-3.x - 如何使随机森林分类器更快?

python - 有什么方法可以仅使用 tensorflow.estimator.train_and_evaluate() 保存最佳模型吗?

python - 多处理 Queue.get() 挂起