知己知彼,百战不殆。我们要打造一个能胜过人类的机器人,就必须要让机器人掌握人类的围棋思维模式,因此我们就需要使用人类棋手留下的棋盘数据训练机器人,让它从数据中掌握人类围棋思维存在的模式和套路。
幸运的是,我们能够通过围棋服务器拿到很多由人落子后产生的棋盘数据。很多围棋服务器公开了这些数据,这些围棋数据以一种叫Smart Game Format的方式存储,我们可以将其下载下来进行预处理后用于训练我们的神经网络,如此得到的网络,它的落子能力将远远超过上一节我们训练的网络机器人。
我们从当下最流行的围棋服务器下载棋盘数据,这个服务器叫KGS(Kiseido Go Server).在下载数据前,我们先了解具体的数据格式。它是一种文本格式数据,它通常用两个大写字母来表示棋盘属性,例如表示棋盘规格时使用的字母是SZ,然后在后面用大括号来容纳属性对应的数值,对于一个9*9的棋盘而言,对应的描述属性为SZ[9]。
它用W来表示白子,如果白子落在第三行第三列,对应的记录就是W[cc],也就是它使用字符次序来表示数字,因此c就表示数字3,同时B表示黑子,如果描述黑子落在第7行,第3列,对应的属性描述就是B[gc],字母g表示7。如果在某一步白棋或黑子pass,对应的描述就是B[],W[],也就是中括号内没有内容。
由此我们看下面一段数据对棋盘的描述:
(;FF[4] GM[1] SZ[9] HA[0] KM[6.5] RU[Japanese] RE[W+9.5] ;B[gc];W[cc];B[cg];W[gg];B[hf];W[gf];B[hg];W[hh];B[ge];W[df];B[dg] ;W[eh];B[cf];W[be];B[eg];W[fh];B[de];W[ec];B[fb];W[eb];B[ea];W[da] ;B[fa];W[cb];B[bf];W[fc];B[gb];W[fe];B[gd];W[ig];B[bd];W[he];B[ff] ;W[fg];B[ef];W[hd];B[fd];W[bi];B[bh];W[bc];B[cd];W[dc];B[ac];W[ab] ;B[ad];W[hc];B[ci];W[ed];B[ee];W[dh];B[ch];W[di];B[hb];W[ib];B[ha] ;W[ic];B[dd];W[ia];B[];
TW[aa][ba][bb][ca][db][ei][fi][gh][gi][hf][hg][hi][id][ie][if] [ih][ii]
TB[ae][af][ag][ah][ai][be][bg][bi][ce][df][fe][ga] W[])
其中FF[4]表示数据格式的版本号,有点类似于操作系统版本。GM[1]表示比赛第一盘,HA表示让子,HA[0]表示没有让子。RU[Japanese]表示围棋遵循日本规则,RE[W+9.5]表示白子以9.5分优势获胜,KM[6.5]表示第二落子的人获得6.5分补偿。接下来 以分好分割的就是双方落子方式。最后TW表示的是白子地盘,TB表示黑子占据的地盘。
理解了数据格式后,我们可以通过网址 https://www.u-go.net/gamerecords/ 下载棋盘数据:
这上面都存储了六段以上高手对弈的棋盘数据。我们接下来将会创建一个爬虫机器人,爬去网页,分析里面链接后自动将数据下载到本地并解压,在后面我们会具体给出爬虫的实现代码,当爬虫运行后,它会解析页面,找出下载链接,依次把文件下载到指定文件夹中,其运行信息如下:
>>>Downloading content/gdrive/My Drive/GO_RECORD/KGS-2006-19-10388-.tar.gz
worker is running
>>>Downloading content/gdrive/My Drive/GO_RECORD/KGS-2005-19-13941-.tar.gz
worker is running
>>>Downloading content/gdrive/My Drive/GO_RECORD/KGS-2004-19-12106-.tar.gz
worker is running
>>>Downloading content/gdrive/My Drive/GO_RECORD/KGS-2003-19-7582-.tar.gz
worker is running
>>>Downloading content/gdrive/My Drive/GO_RECORD/KGS-2002-19-3646-.tar.gz
worker is running
>>>Downloading content/gdrive/My Drive/GO_RECORD/KGS-2001-19-2298-.tar.gz
下载完数据后,我们会用代码解读棋盘数据,并将数据所表示的棋盘落子过程重放一遍,棋盘数据的解读烦琐耗时,为了将精力集中到网络训练上,我们将直接使用一个已经完成的数据解读类来帮我们解读棋盘数据。
首先我们先构造一段虚拟棋盘数据:
"(;GM[1] FF[4] SZ[9];B[ee];W[ef];B[ff])" + \
";W[df];B[fe];W[fc];B[ef];W[gd];B[fb]"
然后使用棋盘数据读取工具类Sgf_game读取上面信息,将其转换成白棋和黑棋的落子信息,然后启动一个虚拟棋盘,将上面的落子步骤显示出来,当我们正确读取上面棋盘信息后,我们可以输出以下模拟棋盘:
19 . . . . . . . . . . . . . . . . . . .
18 . . . . . . . . . . . . . . . . . . .
17 . . . . . . . . . . . . . . . . . . .
16 . . . . . . . . . . . . . . . . . . .
15 . . . . . . . . . . . . . . . . . . .
14 . . . . . . . . . . . . . . . . . . .
13 . . . . . . . . . . . . . . . . . . .
12 . . . . . . . . . . . . . . . . . . .
11 . . . . . . . . . . . . . . . . . . .
10 . . . . . . . . . . . . . . . . . . .
9 . . . . . . . . . . . . . . . . . . .
8 . . . . . . . . . . . . . . . . . . .
7 . . . . . . . . . . . . . . . . . . .
6 . . . . . . . . . . . . . . . . . . .
5 . . . . x . . . . . . . . . . . . . .
4 . . . . . . . . . . . . . . . . . . .
3 . . . . . . . . . . . . . . . . . . .
2 . . . . . . . . . . . . . . . . . . .
1 . . . . . . . . . . . . . . . . . . .
A B C D E F G H J K L M N O P Q R S T
19 . . . . . . . . . . . . . . . . . . .
18 . . . . . . . . . . . . . . . . . . .
17 . . . . . . . . . . . . . . . . . . .
16 . . . . . . . . . . . . . . . . . . .
15 . . . . . . . . . . . . . . . . . . .
14 . . . . . . . . . . . . . . . . . . .
13 . . . . . . . . . . . . . . . . . . .
12 . . . . . . . . . . . . . . . . . . .
11 . . . . . . . . . . . . . . . . . . .
10 . . . . . . . . . . . . . . . . . . .
9 . . . . . . . . . . . . . . . . . . .
8 . . . . . . . . . . . . . . . . . . .
7 . . . . . . . . . . . . . . . . . . .
6 . . . . . . . . . . . . . . . . . . .
5 . . . . x . . . . . . . . . . . . . .
4 . . . . o . . . . . . . . . . . . . .
3 . . . . . . . . . . . . . . . . . . .
2 . . . . . . . . . . . . . . . . . . .
1 . . . . . . . . . . . . . . . . . . .
A B C D E F G H J K L M N O P Q R S T
19 . . . . . . . . . . . . . . . . . . .
18 . . . . . . . . . . . . . . . . . . .
17 . . . . . . . . . . . . . . . . . . .
16 . . . . . . . . . . . . . . . . . . .
15 . . . . . . . . . . . . . . . . . . .
14 . . . . . . . . . . . . . . . . . . .
13 . . . . . . . . . . . . . . . . . . .
12 . . . . . . . . . . . . . . . . . . .
11 . . . . . . . . . . . . . . . . . . .
10 . . . . . . . . . . . . . . . . . . .
9 . . . . . . . . . . . . . . . . . . .
8 . . . . . . . . . . . . . . . . . . .
7 . . . . . . . . . . . . . . . . . . .
6 . . . . . . . . . . . . . . . . . . .
5 . . . . x . . . . . . . . . . . . . .
4 . . . . ox . . . . . . . . . . . . .
3 . . . . . . . . . . . . . . . . . . .
2 . . . . . . . . . . . . . . . . . . .
1 . . . . . . . . . . . . . . . . . . .
A B C D E F G H J K L M N O P Q R S T
完成了数据的解析后,我们就得创建数据处理器,将下载的棋盘数据转换成网络可以识别的向量格式,然后喂给网络,滋养网络的发育。它首先从下载的棋盘描述文件中选取出一部分进行解压,然后读取解压后的数据文件,将它描述的棋盘转换为上一节对应的棋盘编码,同时将当前棋盘与下一步落子对应起来。
我们要把数据分割成两部分,其中时间在2014年前的数据作为测试数据,之后的数据作为训练数据。我们把数据读入内存,按照上面描描述解析数据后,将解析后的数据存储起来以便以后使用,因为数据解析是非常耗时耗力的”脏活累活“,我们尽量做一次即可。