如果树搜索在完成游戏之前停止并重新开始,alpha zero 如何知道?

人工智能 深度学习 强化学习 蒙特卡罗树搜索 零字母
2021-11-12 00:43:56

我试图了解 alpha zero 的工作原理,但有一点我在理解上存在问题,即使在阅读了几种不同的解释之后也是如此。据我了解(参见例如https://applied-data.science/static/main/res/alpha_go_zero_cheat_sheet.png),alpha zero 不执行推出。因此,它不会结束游戏,而是在遇到未知状态时停止,使用神经网络计算不同动作的概率以及该状态的值(“获胜概率”),然后将新值向上传播树。

原因是这要便宜得多,因为实际完成游戏需要更多时间,而不是让神经网络猜测一个状态的值。

但是,这要求神经网络能够很好地预测状态的值。但是在开始训练的时候,显然会在这方面做得不好。此外,由于蒙特卡洛树搜索在遇到新状态时立即停止,并且不同游戏状态的数量非常多,因此在我看来,模拟很少能够完成游戏。并且可以肯定的是,除非真正完成大量游戏,否则神经网络无法改进,因为只有真正的反馈才能告诉智能体它的动作是好是坏。

我在这里想念什么?

我能想出的唯一合理的解释是:如果神经网络在开始时基本上是随机的,那么可以肯定的是,如果树搜索一碰到以前未知的游戏状态,所以不可能是这样。所以也许,也许即使神经网络一开始很糟糕,它也不会很“随机”,但仍然会相当偏向某些路径。这意味着搜索会偏向于大量不同游戏状态中的一些较小的状态集,因此它往往会不止一次地走同一条路径,并且能够完成一些游戏并获得反馈。这个“决议”正确吗?

我在上述“解决方案”中遇到的一个问题是,根据算法,一开始它应该有利于探索,所以一开始它似乎会偏向于选择以前没有采取的行动。这使得树搜索似乎永远无法完成游戏,因此神经网络无法学习。

2个回答

你是对的,AlphaGo Zero 没有在其 MCTS 中执行部署。不过,它确实完成了很多很多游戏。

意识到 AlphaGo Zero 在采取行动之前只迭代 MCTS 1,600 次。该动作产生的下一个状态成为未来搜索树的根。由于典型的围棋游戏仅持续几百步,棋盘将很快达到最终状态。

这些都不取决于神经网络的初始性能。神经网络可能非常糟糕。动作/动作仍将以相同的频率进行。当然,由于 AlphaGo Zero 训练自我对弈,因此它在游戏中的两个自我中的一个通常会成为赢家(有可能打成平手)。所以神经网络会随着时间的推移而改进。

我建议仔细阅读本文的“Self-Play Training Pipeline”部分

抱歉,这更像是评论而不是答案。我想知道您是否找到了问题的明确答案,因为我有一个非常相关的问题。

我也对 AlphaZero 算法感到困惑——我对我的困惑的解释在这里指定:AlphaZero 如何结合使用它的价值和策略头?.

问题是我认为 AlphaZero 算法也不同于 Alphago Zero 算法。我尝试过的许多来源确实将两者混合在一起。

特别是官方伪代码里有这个功能,真的让我很困惑:

def run_mcts(config: AlphaZeroConfig, game: Game, network: Network):
  root = Node(0)
  evaluate(root, game, network)
  add_exploration_noise(config, root)

  for _ in range(config.num_simulations):
    node = root
    scratch_game = game.clone()
    search_path = [node]

    while node.expanded():
      action, node = select_child(config, node)
      scratch_game.apply(action)
      search_path.append(node)

    value = evaluate(node, scratch_game, network)
    backpropagate(search_path, value, scratch_game.to_play())
  return select_action(config, game, root), root


def select_action(config: AlphaZeroConfig, game: Game, root: Node):
  visit_counts = [(child.visit_count, action)
                  for action, child in root.children.iteritems()]
  if len(game.history) < config.num_sampling_moves:
    _, action = softmax_sample(visit_counts)
  else:
    _, action = max(visit_counts)
  return action

主要是因为,如果你看一下expanded...的定义

  def expanded(self):
    return len(self.children) > 0

即当没有更多动作时,我们处于游戏结束时。我想知道我在这里缺少什么。