简介:AlphaGo作为深度学习与强化学习在棋类AI领域的标志性成果,这份源码包面向想深入理解蒙特卡洛树搜索、策略网络与价值网络原理的AI学习者和研究者。压缩包共55个文件,以37个Python脚本为主,另有7个SGF棋谱、2个HDF5模型权重文件以及Markdown说明和配置文件,覆盖模型训练、MCTS决策、棋盘解析与GTP交互等核心模块。RocAlphaGo目录展示了清晰的工程结构,包含测试用例和基准测试,便于二次开发。资源仅208KB,轻量易部署。目前已有3005人学习下载。研读源码可掌握从数据预处理、策略与价值网络训练到蒙特卡洛树搜索的完整链路,并借鉴Python实现神经网络、JavaScript展示棋局交互的设计思路,为自主实现棋类AI或强化学习项目提供扎实参考。
1. 关于AlphaGo源码,先厘清一个关键事实
网上搜索"AlphaGo源码"能翻出一大堆结果,但不少人对第一件最重要的事有误会:DeepMind当年击败李世石的那个AlphaGo Master,完整源码至今没有公开。我们拿到的、能在GitHub上看到的,是DeepMind在2017年底开源的AlphaGo Zero——也就是从零开始、不依赖任何人类棋谱、纯靠自我对弈练出来的版本。那个版本在围棋上超越了所有前辈,而它的完整训练代码、网络结构和自对弈系统,是真正放到了公众面前。
这个区别很重要,因为它决定了你搜索、下载和学习的方向。如果你奔着"复现2016年那一战"去下载代码,大概率会失望;如果你抱着"搞懂AlphaGo的核心机制并亲手把它跑起来"的目的,那AlphaGo Zero的开源项目反而是个比初代更清晰、更优雅的学习样本。
另一个常见误区是:搜索出来的一堆"AlphaGo源码下载"里,很多其实是个人学习项目、简化版复现,甚至是标题党。真正值得花时间的路径其实很明确:先读DeepMind官方的AlphaGo Zero开源仓库,再配合两篇Nature论文(2016年的初代AlphaGo论文和2017年的AlphaGo Zero论文),最后找一个能在自己机器上跑通的简化实现做实验。三步下来,你对这套系统的理解会远超那些只看过新闻报道的人。
这篇文章我想带你做三件事:一是拆解AlphaGo源码里真正值钱的核心模块,让你知道每个文件在干什么、为什么这么设计;二是给你一条从零开始的实际学习路径,从下载代码到跑通实验;三是把我自己折腾这套代码时踩过的坑和顿悟时刻分享出来,这些在论文里可不会写。
2. 源码里真正值钱的东西:三个模块的配合逻辑
打开AlphaGo Zero的源码,你会发现它的代码量并没有想象中那么大——核心结构非常紧凑。这是整个系统最反直觉的地方:一个击败了全世界最强棋手的程序,底层逻辑居然如此简洁。真正复杂的是训练流程的工程实现,以及让系统稳定运行的无数细节。
2.1 策略网络:把"该往哪下"变成概率分布
策略网络是整个系统的"直觉"模块。它接收当前棋盘局面作为输入,输出的是一个覆盖棋盘所有合法落子点的概率分布。简单说,面对一个局面,它会告诉系统:下在A点的胜率倾向是30%,B点是15%,C点是3%……这样一来,搜索就不用在361个点上一视同仁地碰运气,而是把注意力集中在最有希望的区域。
这个网络在AlphaGo Zero里是一个深度残差卷积网络。它的输入不是简单的黑白棋位置,而是把最近8步棋、当前玩家是谁、合法落子点等先验信息编码成很多个特征平面,有点像给每步棋拍了"多角度快照"。网络在这些特征之上做卷积、残差连接,最后通过一个softmax层输出概率。源码里网络结构定义得很清楚,你甚至可以直接数出来它有多少层卷积、多少通道——这些参数都是经过反复实验调出来的,改大了训练慢,改小了强度不够。
策略网络在源码里承担两个职责:一是给蒙特卡洛树搜索提供先验概率,让搜索的起点更聪明;二是自我对弈时用来实际选点落子。这样你就理解了为什么它必须是"概率分布"而不是"唯一最佳点"——围棋是个需要随机性的游戏,训练时需要探索不同变化,而不是每次都走最确定的那个点。
2.2 价值网络:判断"这盘棋到底谁赢了"
价值网络回答的是一个完全不同的问题:给定当前局面,黑棋最终获胜的概率有多大。注意,棋局还没下完,它就要给出一个全局胜负的预判。这个网络在AlphaGo Zero里和策略网络共享大部分底层结构,只是最后输出的是一个标量值,取值范围在-1(白棋胜)到1(黑棋胜)之间。
这个模块的意义怎么强调都不为过。在AlphaGo之前,围棋程序主要靠蒙特卡洛模拟——随机把棋下完,看谁赢得多,重复很多次来评估局面。但围棋的搜索空间太大,靠纯随机模拟很容易被盘面"欺骗",比如局部战斗虽然赢了,但全局已经不行了。价值网络相当于给系统装了一个"大局观":看到当前局面,直接给出全局判断,而不用真的把棋下完。这大大提升了搜索效率,也是AlphaGo Zero能大幅超越初代AlphaGo的关键技术之一。
源码里你还会发现一个细节:价值网络的训练标签,不是人工标注的"这个局面好还是坏",而是来自自我对弈的最终结果。下完整盘棋后,直接拿胜负结果当作训练信号,赢的局面对应1,输的局面对应-1,完全没有人类知识介入。这就是"从零开始"的含义——连价值判断的标准都是系统自己建立起来的。
2.3 蒙特卡洛树搜索:把直觉和判断组织成决策
策略网络给直觉,价值网络给判断,但真正把这两者整合成最终落子决策的,是蒙特卡洛树搜索(MCTS)。可以把它理解成一个"思维推演器":在棋盘的当前局面下,虚拟地往前推演很多步,反复问"如果我下这里,对方最可能下哪里?接下来局面会怎样?",然后综合所有推演结果,选出最终落点。
具体流程大致是四步反复循环:
- 选择:从根节点出发,根据"先验概率+目前搜索胜率"的综合分数,反复挑选最有价值的子节点往下走,直到走到一个尚未展开的叶子节点。
- 扩展:给这个叶子节点创建子节点,对应所有合法落子点,并把策略网络给出的先验概率赋给每个子节点。
- 评估:用价值网络给这个叶子节点打分,得到局面好坏的判断。
- 回溯:把这个分数一层层传回根节点,更新路径上每个节点的访问次数和累计胜率。
这个循环会重复几千次甚至更多,每一次都更精细地刻画不同落子方案的优劣。最终,根节点下访问次数最多的那个分支,就是系统的最终选择。
源码里MCTS的实现有不少工程上的讲究。比如搜索时用的是虚拟损失(virtual loss)机制,让同一时刻的多个并行搜索线程不会在同一个节点上扎堆;又比如被选中概率的计算里有一个温度参数,训练初期温度高、落子更随机,便于探索新变化,后期温度低、更倾向利用已知优势。这些细节单独看都是小技巧,合在一起就是拉开程序强弱差距的关键。
2.4 三者的循环关系:自我对弈如何驱动进化
把这三个模块连起来看,AlphaGo Zero的训练就像一台永动机:当前版本的策略网络和价值网络一起参与自我对弈,每盘棋的每一步都是"用MCTS搜索后的结果来落子"。这些棋局积累下来,每一步都带着"当时的局面+最终的胜负"信息,被当作训练数据来更新网络的参数。新网络稍微变强一点,就去跟旧版本比一比,如果胜率超过阈值,就替换掉旧版本继续下一轮自我对弈。
这个过程每循环一次,系统对围棋的理解就更深一层。源码里你会看到这个循环被实现成了三个独立程序之间的配合:一个程序负责批量生成自我对弈棋谱,一个程序负责用棋谱训练更新网络,还有一个程序负责定期让新旧版本对战、评估是否替换。这三个程序各司其职、互不阻塞,整个训练流程能够并行滚动地推进。
我个人觉得,这才是AlphaGo源码里最值得学习的设计思想——它不是一个写死的规则围棋程序,而是一个能够自我进化的闭环系统。理解了这条循环链,你就理解了AlphaGo的全部精髓。
3. 从哪里下载、如何跑起来:可操作的学习路径
说完了原理,来讲实际操作。前面提到,DeepMind开源的AlphaGo Zero项目在GitHub上,仓库名字就叫alpha-go。你直接搜索就能找到。但我要提前打个预防针:这份代码不是一个"双击运行"的项目,它包含TensorFlow网络定义、自对弈棋谱生成器、并行训练脚本、评估工具等一整套工程体系。要在你的个人电脑上完整复现它的训练过程,基本不现实——那需要TPU集群和海量算力。所以我的建议是把这套代码当作"参考实现"来读,而把实际跑起来的任务交给一些更轻量的复现项目。
3.1 官方仓库怎么读:按模块而不是按文件顺序
下载完官方源码后,别急着打开一个文件从头读。我的阅读顺序是这样的:
第一,先读README和项目结构说明,搞清楚每个目录分别负责什么。第二,找到网络定义文件,把策略网络和价值网络的结构搞清楚——这是全系统最核心的数据结构,理解了输入输出,后面所有代码都好懂了。第三,读MCTS的搜索逻辑,重点看选择、扩展、评估、回溯四个步骤分别在哪里实现。第四,看自我对弈的数据流,搞清楚一盘棋是怎么下完的、每一步怎么保存下来的。最后再看训练脚本和评估脚本。
这个顺序本质上是"先数据流、后控制流"——先知道数据长什么样,再看逻辑怎么处理这些数据,会顺很多。反过来从main函数硬啃的话,很容易迷路。
3.2 简化复现项目:在个人电脑上体验AlphaGo的核心
如果你不想只停留在"读代码"阶段,想实际训练一个能玩简单棋类的小模型,我推荐找一些针对教学场景简化的AlphaGo Zero复现项目。这类项目大多把网络结构大幅缩小、把棋盘改成9路甚至更小、把训练轮次降到个人电脑能承受的范围,让整个流程能在单机上跑通。
我自己跑过的是一个基于Python和PyTorch的简化版,核心流程是:用当前模型自我对弈生成棋谱,每步落子调用MCTS(搜索次数可以调小,比如100次左右),然后喂给一个小卷积网络训练,多轮迭代后观察棋力提升。整个过程在一张普通显卡上就能跑。虽然训出来的"棋手"水平远远比不上AlphaGo,但那种"看着程序从乱走一气到逐渐有章法"的体验,比任何论文里的描述都更能让你理解强化学习的魔力。
3.3 从代码到运行的三个坑,先帮你排掉
这类代码在本地跑起来有几个高频问题,我自己都踩过。先说第一个:环境依赖冲突。AlphaGo Zero的官方代码是基于TensorFlow 1.x的,现在的新版本TensorFlow完全跑不了,你需要用conda单独建一个Python 3.6配TensorFlow 1.15的环境才行。这个坑几乎人人都会遇到,别在这上面浪费半天时间。
第二个坑是搜索参数设置不合理。如果你把MCTS的搜索次数设得太少,比如只有十来次,网络根本来不及形成有效的推演,训练出来的模型会非常弱,让人误以为代码有问题。把搜索次数适当提高(比如100到200次),虽然单局时间变长,但棋力提升是肉眼可见的。
第三个坑和评估阈值有关。AlphaGo Zero用新旧版本对战来决定是否更新主模型,胜率阈值通常设得比较高。在简化版里,如果你照搬这个阈值,会发现模型很难被替换,训练陷入停滞。把阈值调低一些,更适合快速迭代的教学场景。这三个坑都不难解决,提前知道能帮你省很多时间。
4. 源码里的工程细节:从棋盘表示到并行搜索
如果只看论文,你会觉得AlphaGo Zero的核心就是"网络+MCTS+自我对弈",但真正打开源码,你会发现工程实现里的门道多得多。这些细节恰恰是"能跑"和"能高效跑"之间的差距。
4.1 棋盘状态怎么编码:特征平面的设计思路
AlphaGo Zero的网络输入并不是简单地把棋盘画成黑白两色。源码里把当前局面编码成了若干层特征平面,每一层都是17×17(对应19路棋盘+一个全零边框)的矩阵。具体来说,最近8步棋的黑白分布各占一层(共16层),再加上当前轮到谁下的一层(全1表示黑棋回合,全0表示白棋回合)。这样设计的理由是:让网络有足够的信息判断劫争、打吃、连环劫等需要回溯历史棋形的复杂局面。
还有一个容易被忽略的细节:合法落子点。围棋有"劫"的规则,某些点当前不能落子,或者盘面上某些位置不能下(比如已经有子的位置)。源码里有一个统一的合法落子判断逻辑,MCTS扩展节点、网络输出概率时都要先用这个逻辑过滤掉非法位置。这看起来是个基础功能,但漏掉它会导致生成的局面数据全是废的,训练出来的模型完全无法对弈。
4.2 自对弈数据怎么存:训练数据格式的统一化
自我对弈产生的棋谱,要成为训练网络的素材,必须按固定格式存下来。源码里每步数据包含三样东西:局面特征(网络的输入)、MCTS搜索后得到的访问次数分布(作为策略训练的标签)、以及最终棋局的胜负结果(作为价值训练的标签)。
这里有个精妙的设计:训练时网络预测的目标,不是"最终被选中的那个落子点",而是MCTS搜索得到的一整份访问次数分布。这一步棋的多种候选落点它都评估过,访问次数多的说明系统认为它更好。所以策略网络的训练目标,本质是"模仿MCTS搜索后的决策偏好",而不只是"模仿最终落子"。从这个角度看,自我对弈生成的数据,质量远高于单纯用最终落子做标签的数据——它包含了搜索过程中的软性倾向信息。
4.3 并行搜索的效率手段:虚拟损失与批量推理
MCTS单次搜索只能评估一个叶子节点,效率很低。AlphaGo在实际运行时会同时开很多个搜索进程,并且对它们进行批量推理——一次把多个局面的评估请求堆在一起送给GPU处理。但多进程同时搜索一个树,会遇到资源竞争问题:大家都往同一个节点跑,那这个节点就会被反复评估,浪费算力。
源码里的解决方案是虚拟损失:当一个搜索线程正在评估某个节点时,先在这个节点的统计值里加一个临时的大额惩罚,其他线程看到这个节点"暂时很不利",就会绕道去搜索别的分支。等评估完成后再把惩罚去掉。这个机制简单有效,保证了多个搜索线程能够均匀地分布到树的不同区域。
另外一个调度细节是:同一批次推理的局面尽量来自不同的搜索树分支,避免某个时刻网络只看到高度相似的输入。这些调度逻辑虽然不改变搜索引擎的数学原理,但对于真实训练效率的提升是决定性的。
4.4 从源码反推论文:代码比公式更容易理解的地方
很多人在读论文的时候会被各种数学公式劝退,但读源码反而能获得更直观的理解。比如论文里的MCTS置信上界公式,看起来是一长串变量,但源码里就是几行算术赋值。我曾经反复读公式不懂它为什么要对访问次数取平方根、为什么要乘一个探索常数,直到看到代码里把这个公式拆成"先验概率除以(1+访问次数),再乘一个系数"的中间变量时,才真正理解了它是在平衡"探索新路"和"利用熟路"。
所以我的建议是:论文和源码对照着读。每当论文里出现一个公式,就试着在源码里找到对应的实现位置。反过来,源码里看不懂一个算法在做什么,就去论文里找到它的理论解释。两者互为字典,这是研究任何前沿项目代码都通用的方法。
5. 从复现到进阶:跑通源码后还要补什么课
当你把AlphaGo Zero的核心代码啃完、在简化版项目上完整跑通一遍训练流程之后,你可能会有一个强烈的感受:代码本身其实没那么难理解,难的是把它改造到自己的场景里。这时候你才算真正站到了复现学习的分水岭上。
5.1 怎么判断你"真正看懂了"这份代码
一个很有效的自测标准:你能不能在别人的代码基础上,独立把它从19路围棋改成9路围棋,再把训练过程跑通。这个改动听起来简单,实际上要动很多地方:棋盘尺寸影响所有特征平面的形状、网络输入输出的维度、MCTS的节点展开逻辑、合法落子判断、棋谱存储格式……任何一个地方漏改,都会导致训练蹦出莫名的报错。
如果再往前一步,你自己动手把策略网络从卷积网络换成别的结构,或者把强化学习从AlphaGo Zero的自博弈改成Policy Gradient去训练一个简单游戏人工智能,那你对这套体系的理解就真的到应用层了。到这一步,你简历上写"熟悉强化学习和蒙特卡洛树搜索,有从零复现AlphaGo Zero核心算法的经验",是完全站得住脚的。
5.2 历史版本的价值:看懂初代AlphaGo和Zero的差别
还有一个很值得做的对比学习:把初代AlphaGo的方案和AlphaGo Zero的方案放在一起看。初代有"人类棋谱监督学习预训练"这一步,先用人类高手的棋局训练策略网络,再进入强化学习;Zero则完全跳过人类棋谱,从随机初始化开始,全靠自博弈。初代的价值网络和策略网络是分开的两个网络,Zero则设计成了共享底层模块的双头网络。
这个差异背后是一个深刻的认识:人类棋谱虽然有价值,但也把系统的探索空间限制在了人类经验范围内。Zero去掉这个限制后,探索到的围棋招法甚至超出了人类千年经验的范畴,比如它独立发现了某些人类从未用过的新定式。源码里初代和Zero的网络结构差异一目了然,而理解了这种差异,你就会明白"从零开始"这四个字的分量。
5.3 学习资源搭配:论文、开源代码和复现教程怎么组合
给想深入的朋友整理一套我自己的搭配方案。第一,精读论文《Mastering the Game of Go without Human Knowledge》,重点看A节、B节、C节这三个部分,分别对应整体方法、网络结构和强化学习训练流程。第二,看官方AlphaGo Zero代码,重点读网络定义、MCTS和训练循环这三个模块,不用管分布式训练和部署相关的工程文件。第三,找一个适合教学简化版的开源项目,边读边改,把核心流程真正跑一遍。第四,如果有余力,追一下后续的一些改进方法论文,看看高手们如何把AlphaGo的思路用到围棋之外的领域。
这个组合里,论文给你理论框架,官方代码给你工业级参考实现,教学项目给你动手实验环境,后续论文给你视野。四者缺一,你大概率会卡在"看了很多、但总觉得没真正掌握"的尴尬位置。
5.4 从AlphaGo到通用决策:这套代码还能用到哪里
AlphaGo Zero的源码价值远不止围棋。它代表了一种通用思路:在一个存在大量决策问题的领域里,让系统通过自我对弈式的闭环机制去不断改良自身的决策质量。凡是你能定义清楚"状态是什么、动作是什么、胜负怎么判断"的问题,这套框架原则上都可以尝试迁移。
我见过有人拿类似的思路去简化版的物流调度问题,让系统通过大量模拟来学习分发策略;也有人用这种框架做游戏AI和机器人控制策略的教学实验。当然,实际落地时你会发现,围棋之所以适合这套方法,是因为它有明确的规则、确定性的状态转换和清晰的胜负判定。换到其他问题域时,这些前提往往被削弱,你需要做大量适配。但从学习意义上讲,掌握AlphaGo Zero这套系统帮你在面对复杂决策问题时多了一个极具威力的工具视角。
我自己第一次在本地机器上真正跑完整套AlphaGo Zero流程时,前后花了大概一周,中间无数次想放弃。但当我看到那个小模型逐步学会吃掉简单死活题的时候,那种震撼感是整个看论文过程完全无法比拟的。如果你也打算入这个坑,我的建议是:先把每一块代码的输入输出搞清楚,再动手调试,然后试着做一下我前面说的"改成9路围棋"这个练习。等你独立完成这一步,你就不再是"看过AlphaGo源码"的人,而是"做过AlphaGo源码"的人了。
本文还有配套的精品资源,点击获取