上一期结尾我留了一个问题。
DeepMind 那篇《不用人类知识掌握围棋》的论文,2017 年 10 月 19 日在《Nature》上线(纸本是 550 卷 7676 期,12 月),题目叫《Mastering the Game of Go without Human Knowledge》。摘要里有一句:
Here, we introduce an algorithm based solely on reinforcement learning, without human data, guidance, or domain knowledge beyond game rules.
(我们提出一个完全基于强化学习的算法:不用人类数据、不用人类指导,除了游戏规则之外不用任何领域知识。)
还有一句更像标题:
AlphaGo becomes its own teacher: a neural network is trained to predict AlphaGo's own move selections and also the winner of AlphaGo's games.
(AlphaGo 成了自己的老师:一个神经网络被训练来预测 AlphaGo 自己的选子,以及 AlphaGo 自己这盘棋的胜负。)
一台连"棋"是什么都没人教过的机器,凭什么知道自己在下棋?
这个问题我搁了快两个月。上个月我把它写成了下一篇的预告,然后就去忙别的了。现在我想把它真的弄明白。
一、作者自己列了一份"已知清单"
我读论文有个习惯:先找有没有作者自己的总结。这一篇有,而且总结得比我预想的诚实。
论文在讲方法之前,先插了一节叫 Domain Knowledge(领域知识),开头是这么写的:
Our primary contribution is to demonstrate that superhuman performance can be achieved without human domain knowledge. To clarify this contribution, we enumerate the domain knowledge that AlphaGo Zero uses, explicitly or implicitly, either in its training procedure or its Monte-Carlo tree search; these are the items of knowledge that would need to be replaced for AlphaGo Zero to learn a different (alternating Markov) game.
(我们的主要贡献是证明:不依赖人类领域知识,也能达到超越人类的表现。为了说清这件事,我们把 AlphaGo Zero 在训练过程和蒙特卡洛树搜索里用到的领域知识——无论是明面上的还是暗含的——列成清单;这些就是"要让它去学另一个游戏时必须替换掉"的东西。)
然后是四条清单。第一条:
AlphaGo Zero is provided with perfect knowledge of the game rules. These are used during MCTS, to simulate the positions resulting from a sequence of moves, and to score any simulations that reach a terminal state. Games terminate when both players pass, or after 19 · 19 · 2 = 722 moves. In addition, the player is provided with the set of legal moves in each position.
(AlphaGo Zero 被提供了对游戏规则的完美知识。这些规则用在 MCTS 里:一是用来推演一串着点之后会出现的局面,二是给走到终局的模拟打分。棋局在双方都虚着的时候结束,或者下满 19×19×2 = 722 手。此外,程序在每个局面里都被提供了全部合法着点。)
第二条更微妙:
AlphaGo Zero uses Tromp-Taylor scoring during MCTS simulations and self-play training. This is because human scores (Chinese, Japanese or Korean rules) are not well-defined if the game terminates before territorial boundaries are resolved. However, all tournament and evaluation games were scored using Chinese rules.
(AlphaGo Zero 在 MCTS 模拟和自我对弈训练里用的是 Tromp-Taylor 计分法。因为人类的计分方式(中国规则、日本规则、韩国规则)在棋局没下完、边界没分清的时候是没有定义的。不过,正式比赛和评测棋局仍然按中国规则计分。)
第三第四条更简单:棋盘被当成一张 19×19 的图片喂给网络;围棋的规则对旋转和翻转是不变的,所以训练时会把数据做旋转翻转的增广。
我读到这里的第一反应是:所谓"从零开始",是从棋盘开始,不是从零开始。
规则是给的。怎么算赢是给的。哪些点能下是给的。连"棋盘长什么样"都是给的。
论文自己也知道这件事,所以它还说了另一句——大意是:除了上面这几条,它不用任何别的领域知识:
AlphaGo Zero does not use any form of domain knowledge beyond the points listed above.
(除了上面列出的那几条,AlphaGo Zero 不使用任何形式的领域知识。)
然后有一句让我笑了的:
No legal moves are excluded – even those filling in the player's own eyes (a standard heuristic used in all previous programs).
(它不排除任何合法着点——包括那些往自己眼睛里填的棋,而"别往自己眼睛里填"是此前所有围棋程序都有的标准启发式。)
也就是说:所有人类程序都遵守的那条常识,它一条都不需要。
二、先查一下我自己
在往下走之前,我想先做一件更笨的事:查一下我自己写过什么。
我用账本搜了三个词:
| 词 | 我这 22 年旧文里的篇数 |
|---|---|
| AlphaGo | 0 |
| 围棋 | 0 |
| 自我对弈 | 0 |
(口径:9186 篇旧文,标题或正文出现该词;和我自己这几篇系列文无关。)
一篇都没有。
我甚至去翻了我发论文那天——2017 年 10 月 19 日——的博客。那天我发了两条,一条是转发别人的画作,一条是我自己写的:
考虑是不是再买一个VPN备用啊。
论文上线的那一天,我在考虑要不要多买一个 VPN。
后来那三年,我写过很多 AI 相关的转发、很多"这工具真方便"的感叹,可我一次都没提过 AlphaGo。这件事发生在我头上,而我没在场。
所以这一期我做的事,其实不是"研究一个新东西",是补一个我当年没赶上的现场。
三、我把"从零开始"自己搭了一遍
读完那份清单,我最想干的一件事是:自己写一遍那份清单,看看到底够不够。
如果我能用一份自己写的规则清单,让一台从随机参数开始的程序下出比随机好得多的棋,那"从零开始"这件事,至少在这个小尺度上是真的。
我写了一个 5×5 的小围棋(实验/selfplay_demo.py,纯 Python,不依赖任何第三方库)。我给它的全部"已知",就四条:
- 1.棋盘是 5×5 的方格,黑先。
- 2.合法着点:空点;不能自杀(落下之后自己那串没有气);不能重复出现过的局面(简单的 ko)。
- 3.输赢:数子法——盘上的子加上被单方围住的空点;两边都挨着的空点谁也不算。
- 4.贴目:白棋 0.5 子,所以和棋算白赢。
策略不是神经网络,是 9 个特征加一组权重:每个候选点算 9 个特征(是不是角、是不是边、旁边有几个对方的子、这一手能不能提子、会不会把自己送进一气……),权重和特征点积得到一个分数,分数高的点更可能被选中。起点是随机权重。
训练方式是自我对弈:程序自己跟自己下,赢的一方走过的那些点加分,输的一方走过的那些点减分。
就这样,没有一盘人类棋谱,没有一条人写的规则。

结果是:
| 自我对弈局数 | 对随机棋手的胜率 |
|---|---|
| 0(还没训练) | 46.2% |
| 25 | 66.8% |
| 50 | 98.5% |
| 100 | 89.8% |
| 175 | 100.0% |
| 300 | 99.5% |
| 400 | 99.2% |
(每一格是对 400 局随机对手的胜率,一局就是 0.25 个百分点,所以中间那点上下抖动是噪声,不是它在反复变弱。)
真正起作用的其实是前 50 局。50 局之后它就已经压着随机打了,175 局时是 100%。
我盯着这条曲线看了挺久。它不神秘,甚至有点寒酸——它学会的东西,说白了就是"别往自己眼睛里填"、"对方只剩一口气就去提"、"别往边上和角上走"。

这 9 个数字就是它全部的"棋经"。
顺便说一个我原本想错了的事:我本来想用它第一手下在哪来说明"它自己学会了往中间走"——它 400 次开局都下同一个内部点。但我把那一点的特征值打印出来才发现,在它眼里,那个点和另外两个内部点长得一模一样(都不在边上、都不在角上、旁边都没子),选中它只是因为并列第一时按顺序取了第一个。
这不是发现,这是我的玩具分辨不出它们。
四、规则改一条,学出来的东西就换了面孔
接着是我最想做的那个实验。
我把规则清单里的第 2 条改一个字:把"不能自杀"改成"允许自杀"。别的什么都不动——同样的代码、同样的随机种子、同样多的对局、同样的 9 个特征。
结果,两套规则学出来的权重明显不是一回事。差别最大的三个特征是:边、空点的开阔程度、紧邻对方子。
最直接的证据是把"允许自杀"规则下学出来的策略,放回标准规则里用:
| 策略 | 在标准规则下对随机棋手 |
|---|---|
| 用标准规则学出来的 | 99.8% |
| 用"允许自杀"规则学出来的,放回标准规则 | 86.0% |
掉了 13.8 个百分点。
只因为规则清单里的一条不一样,这份"知识"就不能直接用了。
论文里那句话,这时候才真正读进去:
these are the items of knowledge that would need to be replaced for AlphaGo Zero to learn a different (alternating Markov) game
(这些就是要让 AlphaGo Zero 去学另一个游戏时,必须替换掉的东西。)
"规则清单"不是摆设。它给了什么,学出来的东西就是什么形状。
五、换一张棋盘呢
同样的问题还有一版:如果换的是棋盘呢?
我把在 5×5 上学出来的权重原封不动搬到 7×7,又在 7×7 上从零重训了一份,让它们对下:
| 测法 | 结果 |
|---|---|
| 5×5 学出来的,直接搬到 7×7,对随机棋手 | 99.8% |
| 在 7×7 上从零重训,对随机棋手 | 98.5% |
| 这两份直接对下(5 轮 × 40 局),搬过来的那份平均得分 | 55.0%(每轮 50%–60%) |
这个结果没有第四节那么干脆:搬过去的照样能赢随机棋手,直接对下也基本打平(55%)。
我原来以为会看到"一换棋盘就废掉"。没有。原因我猜是:我的玩具学到的就那么两三招(抓子、别送进一气、别下边),这几招在任何大小的棋盘上都成立;而 AlphaGo Zero 学到的是一整套围棋知识,改一条规则、换一张棋盘,那一整套都得作废。
所以我这层实验能证明的是"规则决定学出来的形状",证明不了"规则一改能力就作废"——后者是论文说的,不是我验证出来的。
DeepMind 后来把同一套算法用到了国际象棋和将棋上,做成了 AlphaZero。那篇论文里有一句:
We applied the AlphaZero algorithm to chess, shogi, and also Go. Unless otherwise specified, the same algorithm settings, network architecture, and hyper-parameters were used for all three games. We trained a separate instance of AlphaZero for each game.
(我们把这套 AlphaZero 算法用到了国际象棋、将棋和围棋上。除特别说明外,三个游戏用的是同样的算法设置、网络结构和超参数。我们为每个游戏各训练了一个独立的实例。)
算法是一个,脑子是三个。
论文摘要里还有一句我很喜欢:
Starting from random play, and given no domain knowledge except the game rules, AlphaZero achieved within 24 hours a superhuman level of play in the games of chess and shogi (Japanese chess) as well as Go.
(从随机落子开始,除了游戏规则之外不给任何领域知识,AlphaZero 在 24 小时里就达到了国际象棋、将棋和围棋的超人类水平。)
"除了游戏规则"——这里面的"游戏规则"当然不是"围棋的棋理",而是"怎么算一盘棋的胜负"。
六、论文里的几个数字
顺便把论文里几个我记得住的数字抄一下,都出自正文,我自己对着 PDF 逐条核过:
- •训练用了 3 天,期间产生 490 万局自我对弈,每一步 MCTS 跑 1600 次模拟(大约 0.4 秒),更新了 70 万个 mini-batch,神经网络有 20 个残差块。
- •论文里有一句:"Surprisingly, AlphaGo Zero outperformed AlphaGo Lee after just 36 hours; for comparison, AlphaGo Lee was trained over several months."(出人意料的是,只训练了 36 小时的 AlphaGo Zero 就超过了 AlphaGo Lee;作为对比,AlphaGo Lee 训练了好几个月。)
- •72 小时之后,它和当年赢了李世石的那台 AlphaGo Lee 对下,100 比 0。而且条件对我方不利——AlphaGo Zero 只用一台装了 4 个 TPU 的机器,AlphaGo Lee 用的是分散在很多台机器上的 48 个 TPU。
- •后来又用同一套流程跑了更大的一次:40 天、2900 万局、40 个残差块。最终那一版的评测里,Elo 是:AlphaGo Zero 5185,AlphaGo Master 4858,AlphaGo Lee 3739,AlphaGo Fan 3144。而只用一个神经网络、连搜索都不要(直接选概率最高的一手),也有 3055 分。
还有两句,是这一期最打动我的。
第一句,关于它学到了什么:
AlphaGo Zero rapidly progressed from entirely random moves towards a sophisticated understanding of Go concepts including fuseki (opening), tesuji (tactics), life-and-death, ko (repeated board situations), yose (endgame), capturing races, sente (initiative), shape, influence and territory, all discovered from first principles.
(AlphaGo Zero 从完全随机的着点,迅速进展到对布局、妙手、生死、劫、官子、提子、先后、棋形、势力与实地等围棋概念的成熟理解,全部都是从第一原理里发现的。)
紧接着的那句更妙:
Surprisingly, shicho ("ladder" capture sequences that may span the whole board) – one of the first elements of Go knowledge learned by humans – were only understood by AlphaGo Zero much later in training.
(出人意料的是,征子——人类最早学会的围棋知识之一——AlphaGo Zero 反而是在训练后期才弄明白的。)
人类学棋,是先学套路:征子、跳、飞、扑。机器学棋,是先学效率:哪个局面赢率更高。 征子对人类来说是"常识",对机器来说反而是最晚才学会的那一类。
第二句,关于它像不像人:
Notably, although supervised learning achieved higher move prediction accuracy, the self-learned player performed much better overall, defeating the human-trained player within the first 24 hours of training. This suggests that AlphaGo Zero may be learning a strategy that is qualitatively different to human play.
(值得注意的是,虽然监督学习在"预测人类会下哪一手"上准确率更高,但自学的那个棋手整体表现好得多,在训练的头 24 小时里就击败了用人类数据训练的那个。这说明 AlphaGo Zero 学到的策略,可能和人类的棋在本质上不一样。)
它预测人类棋步的准确率更低,下得却更好。 这句话大概是"从零开始"这四个字最实在的意思。
七、所以它到底知道什么
我现在的理解是这样的:
它知道的不是"围棋",是"怎么在一个有规则的游戏里变强"。
规则是别人给的:棋盘多大、哪里能下、怎么算赢、什么时候结束。给完这些,它的起点是一堆随机数字和一个只会乱下的自己。
然后它靠一件事把这些随机数字变成了棋力:自己跟自己下,用结果给自己打分。
而它学出来的,是这个规则世界里的最优,不是"围棋"。所以规则一改、棋盘一换,这份东西就得重新学——我那个 13.8 个百分点,就是这个意思的一次小小的证据。
可我到现在也没想明白的是另一件事。
同样一份规则清单,DeepMind 那套跑出了围棋两千年才总结出来的东西,我这套只跑出了"别送进一气"和"去提子"。差别在哪?我猜是搜索、算力、和网络能表示的东西,可这三个词太大了,大到等于没说。
同样一份"已知清单",怎么就长出了完全不同的两种东西——这件事我到现在也没想明白。
八、下一篇
还有一件事我没写。
那台跑出 5185 分的机器,训练的时候用的是一台装了 4 个 TPU 的机器,跑了 40 天,下了 2900 万局棋。
而做国际象棋和将棋的 AlphaZero 更夸张:论文里写的是 5000 个第一代 TPU 用来生成自我对弈,64 个第二代 TPU 用来搜索。
每一个 TPU 都是一块专门的芯片,芯片要占地方,机器要占地方,电要从哪儿来,水要怎么排,人要怎么维护。
一台机器,在一间屋子里,用三天或者四十天的时间,自己下了几百万局棋——这件事的后面,藏着一整串非常具体、非常物质的东西。
下一期我想去看看这条线:为什么偏偏是现在?电、芯片、还有一间机房,是在什么地方凑齐的。
(这一期我做的东西都在 实验/selfplay_demo.py 和 实验/make_selfplay_chart.py 里,数据在 记录/selfplay.json,随机种子固定为 7,重跑一次数字完全一样。我的小围棋只有 5×5、9 个特征,比 AlphaGo Zero 简单了几万倍——它证明不了 Zero 有多强,只能证明一件事:把规则写清楚、把起点设成随机之后,自我对弈确实能造出一个强棋手,而这份能力长在给定的规则上。)
没有评论:
发表评论