翻译Deep Learning and the Game of Go(10)第七章:从数据中学习:一个深度学习AI

本文介绍了如何使用SGF文件格式处理围棋游戏数据,从下载KGS围棋服务器的游戏记录开始,通过编码和处理SGF数据来训练深度学习模型。通过构建GoDataProcessor和围棋数据编码器,如SevenPlaneEncoder和ElevenPlaneEncoder,以增强模型的落子预测能力。此外,探讨了Adagrad和Adadelta优化器在训练过程中的应用,以提升模型性能。最终目标是构建一个能够通过学习人类游戏数据来提高预测准确性的围棋AI。
摘要由CSDN通过智能技术生成

本章包括

  • 下载和处理实际的围棋游戏记录
  • 了解存储围棋游戏的标准格式
  • 训练一个使用这样的数据进行落子预测的深度学习模型
  • 运行自己的实验并评估它们

在前一章中,您看到了构建深度学习应用程序的许多基本要素,并构建了一些神经网络来测试您所学到的工具。而关键的是你仍然缺少好的数据来学习。一个监督式的深度神经网络需要你提高好的数据——但目前为止,你只拥有自己生成的数据。

在这一章中,您将了解围棋数据最常见的数据格式-----SGF。您可以从几乎每个流行的围棋服务器中获得SGF游戏记录。为了加强深度神经网络的落子预测能力,在本章中,您将从围棋服务器中下载许多SGF文件,用智能的方式对它们进行编码,并使用这些数据训练神经网络。由此产生的经过训练的神经网络,将比以前的任何模型都要强得多。

图7.1说明了到本章结尾时可以构建的内容。

在本章的末尾,您可以使用复杂的神经网络运行自己的试验,完全独立地构建一个强大的AI。要开始,您需要访问真实的围棋数据。

7.1. 引入围棋数据

到目前为止,您使用的所有围棋数据都是由你自己生成的。在上一章中,你训练了一个深度神经网络来预测生成的数据的落子。你所希望实你的网络可以完美地预测这些落子,在这种情况下,网络将像生成数据的树搜索算法一样发挥作用。在某种程度上,你输入的数据奥克提供了一个深度学习机器人训练的上限。机器人不能超过产生的数据。如果利用强大的人类棋手游戏记录作为深层神经网络的输入,就可以大大提高您的机器人的水平。现在您将使用KGS围棋服务器(以前称为Kiseido GoServer)的游戏数据,这是世界上最流行的围棋游戏平台。在介绍如何从KGS下载和处理数据之前,我们将首先向你介绍围棋数据的数据格式。

7.1.1 SGF文件格式 

 SGF,80年代后期就开始开发。它目前的第四个主要版本(表示FF[4])是在90年代后期发布的。SGF是基于文本的一种格式,可以用来表达围棋游戏及围棋游戏的变体(例如,围棋高手的游戏评论)以及其他棋盘游戏。章节的剩下部分,你将假设你正在处理的SGF文件是由围棋游戏组成,没有其他任何别的东西。在本节中,我们会教你一些关于这个丰富游戏格式的基本知识,但如果你想学习更多关于它的知识的话,请去https://senseis.xmp.net/?SmartGameFormat

SGF主要包括游戏情况和落子数据,是通过两个指定的大写字母包在两个大括号里面。例如,在SGF中,一个大小为9×9的围棋盘将被编码为SZ[9]。围棋落子将会如下编码,在第三行和第三列上的一个交叉点上落白棋将是W[cc],而在第七行和第三列上的一个交叉点上落黑棋将被表示成B[gc];字母B和W代表棋子的颜色,行和列的坐标按字母顺序索引。若要表示pass,请使用空步骤B[]和W[]。

下面的SGF文件示例取自第二章9*9棋盘上的完整对局。它显示了一个围棋游戏(GM[1]代表是围棋),HA[0]表示让子数为0,KM[6.5]表示贴目6.5,R U[Japanese]表示规则是日本规则,RE[W9.5]表示白赢了6.5目

 一个SGF文件被组织成一个节点列表,节点由分号分隔。第一个节点包含有关游戏的信息:棋盘大小、使用的规则、游戏结果和其他背景信息。后面的每个节点表示游戏中的一个落子。最后,你也可以看到属于白棋地盘的点,列在TW之下,以及属于黑棋地盘的点,列在TB之下。

7.1.2.从KGS下载和回放Go游戏记录

如果你进入到https://u­go.net/gamerecords/,你会看到一张表格,上面有可供下载的各种格式游戏记录。这个游戏数据是从KGS 围棋服务器收集的,所有这些游戏都是在19×19的棋盘上进行的,而在第六章中,我们为了减少计算而只使用了个9×9的棋盘。

这是一个令人难以置信的强大数据集,可以用于围棋落子预测,您将在本章中使用该数据集来为强大的深度学习机器人提供动力。您需要可以自动通过获取单个文件的链接下载,然后解压文件,最后处理其中包含的SGF游戏记录。

作为使用这个数据作为深度学习模型的输入第一步,你可以在主dlgo模块中创建一个名为data的新子模块,并像往常一样提供一个空的_init_.py。这个子模块将包含所有这本书所需的数据处理。

接下来,要下载游戏数据,您可以在数据子模块中添加新文件index_processor.py中,并创建一个名为KGSIndex的类,然后实现其中的download_files方法

7.2 为深度学习准备数据

在第6章中,您看到了一个简单的围棋数据编码器,该编码器已经表示了在第3章中介绍的Board和GameState类。当使用SGF文件时,您首先需要对内容进行回放,产生对应的一个对局,得到必要的游戏信息。

7.2.1.根据SGF记录重放围棋对局

读取SGF文件的游戏信息意味着要理解和实现格式规范。虽然这并不是特别难做到(只是强加一个规则在一串文本上),这也不是构建围棋AI最令人兴奋的方面,需要大量的努力和时间才能做到完美无缺。出于这些原因,我们将引入另一个子模块gosgf到dlgo中,它负责处理SGF文件所需的所有逻辑。gosgf模块是从Gomill Python库改编而来的,地址是https://mjw.woodcraft.me.uk/gomill/

您将需要一个来自gosgf的实体,它足以处理您需要的所有内容:sgf_game。让我们看看如何使用SGF_Game加载一个SGF游戏,逐步读出游戏信息,并将落子应用于Game State对象。图7.2显示了围棋游戏的开始,用SGF命令表示。 

从SGF文件中重放游戏记录。原来的SGF文件编码游戏移动与字符串,如B[ee]。Sgf_game类解码这些字符串并将它们作为Python元组返回。你就可以将这些落子应用到GameState对象以重建游戏

# 先从新的gosgf模块导入Sgf_game类
from dlgo.gosgf import Sgf_game 
from dlgo.goboard_fast import GameState, Move 
from dlgo.gotypes import Point 
from dlgo.utils import print_board 


# 定义示例SGF字符串,此内容稍后会来自下载的数据
sgf_content = "(;GM[1]FF[4]SZ[9];B[ee];W[ef];B[ff]" + ";W[df];B[fe];W[fc];B[ec];W[gd];B[fb])" 

# 使用from_string方法,您可以创建一个SGF_game
sgf_game = Sgf_game.from_string(sgf_content)  
game_state = GameState.new_game(19)

# 重复游戏的主要顺序,你忽略了棋局变化和评论
for item in sgf_game.main_sequence_iter(): 
    # 这个主序列中的项是(颜色,落子)对,其中"落子"是一对坐标。
    color, move_tuple = item.get_move() 
    if color is not None and move_tuple is not None:
         row, col = move_tuple
         point = Point(row + 1, col + 1)
         move = Move.play(point) 
         # 将读出的落子应用到棋盘上
         game_state = game_state.apply_move(move) 
         print_board(game_state.board)

从本质上讲,在您有了一个有效的SGF字符串之后,您就可以根据它得到主要序列,而这些序列你可以通过迭代得到。上面代码是本章的核心,它给出了一个粗略的大纲,告诉你将如何继续处理深度学习所需的数据:

  1. 下载并解压缩围棋游戏文件。
  2. 遍历这些文件中包含的每个SGF文件,读取文件中的内容变成字符串,然后从这些字符串中创建一个Sgf_game。
  3. 读出每个SGF字符串的围棋游戏的主要顺序,确保处理重要的细节,如放置棋子,并将产生的落子数据输入到GameState对象中。
  4. 对于每一个落子,棋盘局面采用编码器进行编码成特征,并将落子本身存储为标签,然后将其放置在棋盘上。这样,您将创建落子预测数据,以便在后面训练中进行深入学习。
  5. 5.将生成的特征和标签以合适的格式存储起来,这样您就可以稍后将其添加到神经网络中。

在接下来的几节中,您将非常详细地处理这五个任务。处理完这些数据后,您可以回到您的落子预测应用程序,看看如何让数据影响落子预测精度。 

7.2.2.构建围棋数据处理器

在本节中,您将构建一个围棋数据处理器,该处理器可以将原始SGF数据转换为机器学习算法的特征和标签。这将是一个相对较长的实现,因此我把它分成几个部分。当你完成的时候,你就可以准备好在真实数据上运行一个深度学习模型。

要开始,先在data模块下新建一个名为processor.py的新文件,让我们导入几个核心Python库,除了用于数据出来的NumPy之外,您还需要相当多的包来处理文件。

import os.path
import tarfile
import gzip
import glob
import shutil

import numpy as np
from keras.utils import to_categorical

至于dlgo本身所需要的功能,您需要导入到目前为止构建的许多核心类。


from dlgo.gosgf.sgf import Sgf_game
from dlgo.agent.FastRandomAgent.goboard_fast import Board, GameState, Move
from dlgo.gotypes import Player, Point
from dlgo.Encoder.Base import get_encoder_by_name
from dlgo.data.index_processor import KGSIndex
from dlgo.data.sampling import Sampler # 从文件中采样训练和测试数据

我们还没有后面两个引入,但我们将在构建围棋数据处理器中引入它们。现在继续使用processor.py,GoDataProcessor初始化是通过提供一个Encoder作为字符串和一个存储围棋书记路径的data_directory

class GoDataProcessor:
    def __init__(self,encoder="OnePlaneEncoder",data_directory="data"):
        self.encoder = get_encoder_by_name(encoder,19)
        self.data_directory = data_directory

接下来,您将实现主要的数据处理方法,称为load_go_data。在此方法中,您可以指定要处理的游戏数量以及要加载的数据类型,即训练或测试数据。load_go_data将从KGS中下载在线游戏记录,对指定数量的游戏进行采样,通过创建功能和标签进行处理,然后将结果持久化到本地作为NumPy数组。

 

 

并行处理parallel.py

"""
   将sgf文件转成可被机器学习使用的格式
"""

# 文件相关类 begin
import os.path
import tarfile
import gzip
import glob
import shutil
# 文件相关类 end

import  os
from os import sys
import multiprocessing
import numpy as np
from keras.utils import to_categorical

from dlgo.gosgf.sgf import Sgf_game
from dlgo.agent.FastRandomAgent.goboard_fast import Board, GameState, Move
from dlgo.gotypes import Player, Point
from dlgo.Encoder.Base import get_encoder_by_name
from dlgo.data.index_processor import KGSIndex
from dlgo.data.Sample import Sampler
from dlgo.data.generator import DataGenerator


def worker(jobinfo):
    try:
        clazz, encoder, zip_file, data_file_name, game_list = jobinfo
        clazz(encoder=encoder).process_zip(zip_file, data_file_name, game_list)
    except (KeyboardInterrupt, SystemExit):
        raise Exception('>>> Exiting child process.')


class GoDataProcessor:
    def __init__(self,encoder="OnePlaneEncoder",data_directory="data"):
        self.encoder = get_encoder_by_name(encoder,19)
        self.data_directory = data_directory
        self.encoder_string = encoder

    # 加载
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值