AlphaZero — 把一次树搜索完整走一遍
这一章讲三件事: 下棋的到底是谁(不是神经网络); 一次树搜索的三个步骤,在一棵真树上逐轮走一遍,每一步的数都写出来; 以及树搜索和网络训练是靠哪一个量接在一起的。
它在全书链条里的位置:全书唯一一个「成功案例」的完整解剖。 它的前置是第 14 章第 6 到 8 节那棵通用的搜索树 —— 这一章只讲「砍掉模拟那一步之后有什么不同」,不重讲四步。 而第 02 章第 5 节那个置信上界的式子,跨了十七章在这里原样回来。
顶层全景:三轮树搜索,一棵树长出来
这一章从头到尾用书里那棵树:一个 3×3 的棋盘(也就是井字棋大小),轮到白方走1。
★ 树上每个节点存五样东西,全部是书里给的2:
| 存什么 | 意思 |
|---|---|
| A | 到达这个节点走的是哪一步 |
| N | ★ 这个节点被访问过几次 ★(初值 0) |
| W | 累计的奖励和(初值 0) |
| Q | W 除以 N —— 平均下来这个节点值多少(初值 0) |
| P | ★ 网络给这一步打的先验概率 ★ —— 由父节点的局面喂进网络得到 |
★ 三轮树搜索,每一轮做完之后树长什么样(全部是书里的真数):★
── 第 1 轮 ────────────────────────────────────────────
树里只有一个节点。它在顶上所以是根,它没有孩子所以也是叶。
→ 选择这一步:★ 已经在叶子上了,不用选 ★
→ 扩展与评估:把它所有可行的下一步都摊开,网络给每一步一个先验概率
→ 回溯:★ 根节点不更新 W 和 Q,只把 N 从 0 改成 1 ★ §5
结果:根 N=1
── 第 2 轮 ────────────────────────────────────────────
从根开始。这次根有孩子了,所以要选。
→ 按「Q 加一项探索加成」选出白方走 (w,2),到一个新叶子 §4
→ 扩展与评估:摊开它 的孩子,价值网络给这个局面打 **−0.1**
→ ★ 回溯:这个 −0.1 是从黑方视角说的,而这个节点属于白方 ★ §6
取反之后:N=1、W=**0.1**、Q=**0.1**
→ 再回到根:★ 只把 N 从 1 改成 2 ★
结果:根 N=2,(w,2) 那个节点 N=1、W=0.1、Q=0.1
── 第 3 轮 ────────────────────────────────────────────
从根开始,选出 (w,2),再往下选出黑方走 (b,9)。
→ ★ 撞上终局了。★ 于是:不扩展、价值网络不用、策略网络也不用 ——
结果直接从游戏规则拿。 §5
→ 白方输了,所以从白方视角看是 **−1**;
而这一步是黑方走出来的,所以记在这个节点上是 **+1** §6
→ N=1、W=1、Q=1
→ 沿路往上,★ 每回退一级就取一次反 ★
结果:根 N=3
★ 三轮之后,根节点被访问了 3 次,路上每个节点的信息都更新过了。★
★ 而真正的棋盘上,到现在为止一个子都还没落。★ §7
图说:这就是本章的主走查。§4 到 §6 把这三轮逐步推出来,
§7 讲搜完之后怎么在真棋盘上落子。
(三轮的每一步与 −0.1、+1 这两个数全部是书里的。)
1. 这套办法只对一类很窄的游戏成立
这一节先划边界,免得读完以为它什么都能干。
书里在开头列了这类游戏(它管这叫组合博弈)的五个特征3:
| 特征 | 书里的说法 |
|---|---|
| ① 两个玩家 | 单人游戏(数独、纸牌)可以看成「设计者和玩家」之间的博弈 |
| ★ ② 三人以上不算 ★ | 书里的理由很关键:「因为游戏中会出现合作等更加复杂的博弈问题」 |
| ③ 没有随机因素 | 「不包含任何影响游戏结果的随机性因素,如骰子等」 |
| ④ 完美信息 | 「每个玩家都完全了解之前发生的所有事件」 |
| ⑤ 回合制、有限、会结束 | 动作与状态空间都有限,而且「游戏会在有限步内结束」 |
★ 第 ② 条正好接上第 16 章:三个人以上会出现合作,而合作要用均衡去描述 —— 那就不是「一棵树搜到底」能解决的了。★
★ 第 ③ 条也很硬:有骰子的游戏,同一步走出来的结果不唯一,树就不能这么建。★
书里给的谱系:自从深蓝赢了国际象棋大师之后,围棋成为下一个桥头堡4。
2. 下棋的是树搜索,网络只做两件事
这一节纠正这一章最常被搞反的一件事。
先看现象
「AlphaZero 下棋」这句话,直觉上会理解成:把棋盘喂给一个网络,它吐出该走哪一步。
★ 不是。真正决定走哪一步的是那棵树,而神经网络只在树里被叫两次。★
★ 每一次真正落子之前,树搜索要重复几百次(书里这个实现是 400 次)。★[^5]
★ 而每一次树搜索里,神经网络只被用来做两件事:★
① 策略网络:给一个局面 → 吐出「每一步被选中的先验概率」 → 存进新扩展出来的子节点(那个 P)
② 价值网络:给一个局面 → 吐出「这个局面值多少分」 → 拿去回溯
★ 落子那一步,网络一个字都不参与 —— 靠的是访问次数(§7)。★
(这句归纳是我们的;两个网络各自干什么是书里的。)
和第 14 章那棵树的关系
第 14 章第 7 节讲的通用树搜索有四步:选择 → 扩展 → 模拟 → 回溯5。 「模拟」那一步是:从当前节点用某种策略(比如随机策略)一路下到游戏结束,拿到胜负5。
★ 而书里说:AlphaZero「舍弃了模拟步骤,直接用深度神经网络预测结果」——于是只剩三步。★6
第 14 章的四步: 选择 → 扩展 → ★ 模拟(随机下到底) ★ → 回溯
这一章的三步: 选择 → ★ 扩展与评估(网络直接给分) ★ → 回溯
★ 被砍掉的那一步是最贵的:随机下到底,一局可能要几十步。★
★ 换成让数据从网络的输入一路算到输出走一遍(这个动作叫前向传播),几毫秒就出一个估分。★
(这个代价对比是我们补的;砍掉模拟这件事是书里的。)
★ 但注意一处例外,它在主走查第 3 轮出现:如果叶子已经是终局,那么结果直接从游戏拿 —— 书里明说:这时「价值网络不会用来估计状态价值,策略网络也不会输出动作概率」。★7
3. 一棵树里有两个视角
这一节讲这一章最容易踩的坑,而书里专门为它写了一段警告。
那个坑
书里的原话:由于游戏中存在两个玩家,所以建搜索树时「一棵树里存在两个玩家的视角」; 节点上的信息要么从黑方视角更新,要么从白方视角更新8。
★ 而关键的一句是:一个节点上的信息,是从它的父节点那个玩家的视角存的。★8
★ 书里给的理由很干净:这个节点是父节点在扩展孩子时新产生的。★[^9]
举个书里的例子:某个节点的棋盘上只有一个黑子。
→ 直觉上「现在该白方走了」,所以你会以为这是白方的节点
→ ★ 错。这个节点是黑方走了一步 A=5 才到达的,
所以它的 A、N、W、Q、P 全部是黑方初始化的,也是给黑方后续使用的。★[^9]
书里的原话:「对每个节点的视角有一个清晰的理解是非常重要的,
否则在随后树搜索的过程中执行回溯步骤时,不易理解整个更新过程。」[^9]
★ 一句话记住:节点属于「走到它的那个人」,不属于「接下来该走的那个人」。★ 主走查第 2 轮和第 3 轮那两次取反,全部来自这一条。
4. 选择:那个式子是第 02 章那个的第三代
这一节走主走查第 2 轮的第一步,并兑现第 02 章埋了十七章的那个伏笔。
三代写法,一脉相承
书里把这个式子的谱系完整地摆了出来9:
★ 第一代(第 02 章第 5 节那个):置信上界 ★
挑分最高 的: 这根杆的估值 + c × √( ln(总次数) ÷ 这根杆被拉过几次 )
└─ 利用 ─┘ └────── 探索:拉得越少这一项越大 ──────┘
★ 第二代:把它搬进树里 ★[^11]
同一个形状,只是「总次数」变成当前节点被访问几次、
「这根杆被拉过几次」变成这个子节点被访问几次。
★ 第三代(这一章):再乘上网络给的先验概率 ★[^12]
挑分最高的: Q(这个子节点的均值) + c × P × √(兄弟们总共被访问几次) ÷ (1 + 自己被访问几次)
└── 利用 ──┘ └────────── 探索 ──────────┘
★ 三代之间只有两处变化:分母从「开根号里」挪到了「根号外」,
以及多乘了一个 P —— 也就是网络的意 见。★
(这个三代对照是我们排的;三个式子都是书里给的。)
那个 P 起什么作用
★ 它让网络的意见成为「往哪儿搜」的引导,而不是「走哪一步」的决定。★
一个网络认为很有希望的动作(P 大) → 探索项大 → 优先被搜到 → 很快积累访问次数
一个网络不看好的动作(P 小) → 探索项小 → 搜得少
★ 但注意:P 只影响「先搜谁」。★
★ 如果搜下去发现那一支实际很差(Q 变负),它照样会被冷落。★
★ 也就是说:网络负责提名,树搜索负责否决。★
(这段解释是我们的;那个式子是书里的。)
书里给了那个平衡系数的值:在 AlphaZero 里设为 510。
主走查第 2 轮的这一步
按这个式子,白方选了动作 2,到达一个新叶子。此时轮到黑方走11。
5. 扩展与评估:两种情况,以及第一轮那个特例
这一节走主走查第 1 轮和第 3 轮。
一般情况
书里的做法:在叶节点后面添加子节点,同时「每个动作的选取概率和状态值的估计 直接通过策略网络和价值网络预测得到」6。
书里还提到一个可选的 优化:通常会设一个阈值来判断这个节点要不要扩展; 而它自己的实现省掉了这个阈值,每次到叶子都扩展6。
第 1 轮那个特例
★ 第 1 轮时,树里只有一个节点。它既是根又是叶。★[^14]
→ 选择那一步:★ 已经在叶子上了,什么都不用选 ★
→ 扩展与评估:照常做 —— 摊开所有可行动作,网络给每一步一个先验概率
→ 回溯:★ 这里有一处很反直觉的做法 ★
书里的原话:由于当前节点是根节点,
「我 们不需要回溯 W 和 Q,只需更新访问次数 N。将 N = 0 更新为 N = 1」。[^14]
★ 为什么根节点的 W 和 Q 不用更新:因为 W 和 Q 是「用来判断树搜索该不该到达这个节点」的。★[^14]
★ 而根节点是每一轮的起点,你必须从它开始 —— 它不需要被「判断值不值得去」。★
(这句解释是我们补的;那句「不需要回溯 W 和 Q」是书里的原话。)
★ 顺带解释了一个细节:书里说 400 次搜索之后,
子节点的访问次数之和是 400,而根节点是 401 ——
因为第一次搜索是从扩展开始的,并没有选任何子节点。★[^15]
第 3 轮那个特例
主走查第 3 轮走到了终局。这时的处理完全不同7:
★ 节点不扩展。★
★ 价值网络不用 —— 结果直接从游戏规则拿。★
★ 策略网络也不用 —— 都终局了,不需要「下一步的概率」。★
★ 这是这一章唯一一处「网络完全不参与」的地方,而它恰恰是信息最准的一次:★
★ 前两轮拿到的都是网络的猜测,这一次拿到的是事实。★
(这句对比是我们补的;三条处理都是书里的。)
6. 回溯:每回退一级,取一次反
这一节走主走查两次回溯的完整算术,是本章最要紧的一节。
更新的规则
书里给的三条,每个节点都一样12:
N ← N + 1 (访问次数加一)
W ← W + v (把这次拿到的值累加进去)
Q ← W ÷ N (重算平均)
★ 而书里紧接着给了那句警告:「我们需要注意更新的视角,并且总是以当前玩家的视角更新值。」★12
第 2 轮的回溯:一次取反
价值网络给这个新叶子打了 **−0.1**,而★这是从黑方视角看的★。[^16]
可这个节点属于白方(§3 那一条:节点属于走到它的那个人 —— 白方走了 A=2 才到这儿)。
★ 所以要取反:−(−0.1) = **+0.1** ★
→ N = 0 + 1 = **1**
→ W = 0 + 0.1 = **0.1**
→ Q = 0.1 ÷ 1 = **0.1**
书里给的正是这三个数。[^16]
然后回到根节点:★ 只更新 N,从 1 变成 2 ★(根节点的 W 和 Q 不更新,理由见 §5)。[^17]
判断(我们的,不是书里的): 转码出来的文本在这一处有一个符号错 —— 它写的是「当更新属于白方玩家的信息时需要取反,即 v(s) = −0.1」, 可紧接着 的结论是 W = 0.1、Q = 0.1(正数)。 ★ 所以那个「即 v(s) = −0.1」里的负号应该是取反之后的 +0.1,清洗时把加号丢了。★ 我们按结论(0.1)来讲。 如果错,会错在: 也可能是书里原本就写错了,而不是转码丢的。 判据是:三个数必须自洽 —— W = 0 + v,而书里给的 W 是 0.1,所以 v 只能是 +0.1。
第 3 轮的回溯:逐级取反
★ 书里的规则一句话:「还应该切换每个节点的视角,这意味着 v(白) = −v(黑)。」★[^18]
这一局的事实:黑方走了 A=9 之后,游戏结束,★ 白方输了 ★。
① 从白方视角看这个结果:**−1**[^18]
② 可这个节点是黑方走 A=9 到达的(§3 那一条)
→ ★ 记在这个节点上的值要取反:v(黑) = −(−1) = **+1** ★[^18]
→ N = **1**、W = **1**、Q = **1**
③ 再往上退一级(到 (w,2) 那个节点,属于白方)→ ★ 再取一次反 ★
④ 再往上退到根 → 只更新 N,从 2 变成 **3**
★ 这就是「每回退一级取一次反」的全部内容。★
★ 而书里为这件事专门写了一整段警告 —— 因为一处符号错,整棵树的估值全反了,
而且它不会报错,只会让智能体一直下臭棋。★
(最后那句后果是我们补的;逐级取反是书里的。)
7. 落子看的是访问次数,不是估分
这一节讲搜完之后怎么真的下一步棋,而它是这一章第二个反直觉的地方。
先看现象
搜了 400 次,每个子节点都有一个 Q(平均值)和一个 N(访问次数)。
★ 按哪个落子?直觉会说按 Q —— 分最高的那一步。而书里用的是 N。★
书里的原话:动作的选取「通过计算每个动作的访问次数并归一化为概率进行选择, 而不是直接通过策略网络输出动作概率」13。
判断(我们的,不是书里的): 为什么访问次数比估分更可信 —— ★ 因为 N 大本身就意味着「这一支被反复验证过」。★ 一个只被访问过 2 次的节点,它的 Q 是两次估计的平均,噪声很大; 而一个被访问了 200 次的节点,它的 Q 已经被 200 条不同的后续路线检验过。 而且 §4 那个式子保证了:Q 高的支路会被反复选中 —— 所以 N 已经把 Q 的信息吸收进去了, 同时还多了一层「稳不稳」的信息。 如果错,会错在: 访问次数也会被先验概率 P 抬高 —— 网络看好但实际不好的一支,前期也会积累访问次数。 判据是:搜索次数够多时,Q 的负反馈会把这种支路压下去;搜索次数很少时,这条就不成立。
温度参数怎么用
书里给了一个参数来控制这一步的随机程 度14:
| 温度 | 效果 | ★ 用在哪 ★ |
|---|---|---|
| 等于 1 | 选中的概率和访问次数成正比 —— 探索度高 | ★ 自博弈收集数据时的前若干步 ★ |
| 趋近 0 | 只挑访问次数最多的那一步 | 之后的所有步,以及和真人下棋时全程 |
书里给的具体步数:AlphaZero 与 AlphaGo Zero 用前 30 步,而这本书的实现用前 12 步14。
★ 为什么自博弈时要故意随机:书里说这是为了「确保数据收集的多样性」。★14 如果每一局都下得一模一样,训练数据就全是重复的。
落子之后:换根
先说一个动作:把树上用不着的枝杈整片砍掉、连同它下面存的所有信息一起扔,这叫剪枝。
书里说:落子之后树的根节点就换成了刚才走的那个子节点,搜索从新的根继续; 而「其他兄弟节点及其父节点将被剪枝丢弃以节省内存」15。
★ 也就是说:上一步搜出来的那一大片树,只有走到的那一支被留下来接着用。★
8. 训练数据从自己跟自己下棋来
这一节讲这两样东西(树搜索与网络)是靠哪一个量接在一起的。
两个标签
★ 一局自博弈下完,每一个走过的局面都变成一条训练数据:★
输入: 这个局面
标签一:★ π(a|s) = 各个动作的访问次数归一化 ★ → 训练策略网络[^22]
标签二:★ v(s) = 这一局最终的胜负 ★ → 训练价值网络[^23]
赢是 1、输是 −1、平局是 0
★ 书里对第一个标签给了一句非常关键的话:★
「这里的概率通过访问次数计算,这是蒙特卡罗树搜索自博弈过程和神经网络训练相结合的关键点。」[^22]
★ 把这一句掰开:★
网络的先验 P → 引导树往哪儿搜(§4)
↓
树搜了 400 次,得到访问次数 N
↓
★ N 归一化之后,反过来当策略网络的训练目标 ★
↓
网络的先验 P 变得更像「搜了 400 次之后的结论」
↓
下一次搜索,起点就更好
★ 这就是这套办法自我提升的整个环路。★
★ 而它的接口只有一个量:访问次数。★
(这张环路图是我们画的;那句「关键点」和两个标签都是书里的。)
输入怎么摆
书里说数据要先转成堆叠的特征层:每一层只有 0 和 1,表示哪些位置有子; 一组表示当前玩家的落子、另一组表示对手的落子,而这些层按历史动作的顺序堆叠16。
一处很值钱的对照:数据增强
★ 这是全章最能说明「通用算法要为具体游戏让步」的一处。★
★ 这本书的实现用了数据增强:把棋盘旋转和镜像翻转,一条数据变成好几条。★[^25]
书里给的理由:「围棋和五子棋的规则都不受旋转和镜像翻转的影响」;
而在搜索过程中随机旋转或翻转再喂给网络,还能「在一定程度上减小方差」。[^25]
★ 而 AlphaZero 没有用这个技巧。★
书里给的理由:「由于某些游戏规则不具有旋转和镜像翻转不变性」。[^25]
★ 一句话:一个白捡的技巧,因为要覆盖国际象棋这类游戏而被放弃了。★
(国际象棋的兵只能往一个方向走,棋盘一转规则就变了 —— 这个例子是我们补的。)