1

好的,所以我使用与 DeepMind 的 Atari 算法相同的想法创建了一个神经网络 Q-learner(除了我提供原始数据而不是图片(还))。

神经网络构建:

  • 9 个输入(0 表示空白点,1 表示“X”,-1 表示“O”)

  • 1 个具有 9-50 个神经元的隐藏层(尝试不同大小,激活函数 sigmoid)

  • 9 个输出(每个动作 1 个,输出 Q 值,激活函数 sigmoid)

  • MSE 损失函数
  • 亚当反向传播

由于梯度检查和大量测试,我 100% 确信网络是正确构建的。

Q 参数:

  • -1 输掉比赛的奖励
  • 如果尝试移动到已经占据的位置,则 -1 奖励(例如,X 已经在玩家 O 尝试放置“O”的位置)
  • 0 抽奖奖励
  • 0 奖励移动,不会导致终止状态
  • +1 获胜游戏奖励
  • 下一个状态(在 s,a,r,s' 中)是您自己和对手移动之后的状态。例如,空棋盘和玩家 X 先转牌并将“X”放在左上角。然后玩家O把“O”放在右上角。那么 s,a,r,s' 将是 s = [0,0,0,0,0,0,0,0,0], a = 0, r = 0, s' = [1,0,- 1,0,0,0,0,0,0]

问题

如果我在移动到已经占据的位置时给予 -1 奖励,我所有的 Q 值都会归零。如果我不这样做,网络就不会知道它不应该移动到已经被占用的地方,并且似乎学习任意 Q 值。我的错误似乎也没有缩小。

无效的解决方案

  • 我试图将奖励更改为 (0, 0.5, 1) 和 (0, 1) 但它仍然没有学习。

  • 我试图将状态显示为 0 表示空,0.5 表示 O,1 表示 X,但没有奏效。

  • 我试图在移动后立即给出下一个状态,但它没有帮助。

  • 我试过用 Adam 和 vanilla back prop,但结果还是一样。

  • 我已经尝试过重放内存和随机梯度下降的批次,但仍然相同
  • 将 sigmoid 更改为 ReLU 但没有帮助。
  • 各种现在想不起来的事

GitHub 中的项目:https ://github.com/Dopet/tic-tac-toe (对于丑陋的代码很抱歉,主要是由于所有这些代码重构,这应该很容易测试以查看算法是否有效)

要点:

  • TicTac 类具有游戏本身(使用抽象 Game 类的模板方法模式制作)
  • NeuralNetwork 类将一些数据记录到当前目录中名为 MyLogFile.log 的文件中
  • Block 和 Combo 类仅用于创建获胜情况
  • jblas-1.2.4.jar 包含 DoubleMatrix 库
4

2 回答 2

1

这是一个奖励/从输出层移除激活函数的问题。大多数时候我的奖励是 [-1, 1],我的输出层激活函数是从 [0, 1] 开始的 sigmoid。这导致网络在用 -1 奖励它时总是出错,因为输出永远不会小于零。这导致值变为零,因为它试图修复错误但它不能

于 2017-01-18T14:44:29.803 回答
0

我认为你的表述是错误的。您正在使用 NN 为下一个状态提供的最大值更新状态的值。

expectedValue[i] = replay.getReward() + gamma *targetNetwork.forwardPropagate(replay.getNextState()).max();

这适用于单人游戏设置。但由于井字游戏是 2 人游戏,“下一个状态”(对手)的更高价值不利于当前状态的价值。

您可以将最大值 2 个状态向前(使用 NN 预测 2 个状态向前),但这也不能很好地发挥作用,因为您假设您所做的第二步是最佳的并且会导致许多错误的更新。

我建议您在传播值不是很清楚的设置中使用策略梯度。在这种方法中,您玩随机游戏(两个玩家都进行随机移动),并说如果玩家“O”获胜,您会积极奖励所有“O”移动(减少折扣因子,即最终移动获得更多奖励,然后奖励减少因子)和奖励“X”以相同的方式负向移动。如果游戏结果为平局,您可以用较小的积极奖励奖励两名玩家。

您最终可能会积极奖励次优动作,反之亦然,但在大量游戏中,事情对您有利。

于 2017-01-17T14:58:32.083 回答