翻譯Deep Learning and the Game of Go(10)第八章:部署你的AI

本章包括:

  • 構建一個端到端的應用程序來訓練和運行一個圍棋機器人
  • 在前端運行來對抗你的機器人
  • 讓你的機器人在本地與其他機器人對抗。
  • 部署到在線圍棋服務器

到目前爲止,你已經知道如何爲圍棋落子預測去構建和訓練一個強大的深度學習模型,但是你如何將它集成到一個與對手玩遊戲的應用程序中?訓練神經網絡工作只是構建端到端應用程序的一部分,不管你是自我對弈,還是讓你的機器人與其他機器人競爭,這個模型必須集成成一個可以使用的引擎。

在本章中,您將構建一個簡單的圍棋模型服務器和兩個前端。首先,我們爲您提供一個HTTP前端,您可以用來對抗您的機器人。然後,我們介紹圍棋文本協議(GTP),這是一種廣泛使用的協議,圍棋AI可以互相進行對抗,比如你可以挑戰GNUGo或Pachi,這是兩個免費提供的基於GTP的圍棋程序。最後,我們將向您展示如何在AmazonWebServices(AWS)上部署圍棋機器人並將其與在線圍棋服務器(OGS)連接。這樣做可以讓你的機器人在真正的遊戲中與世界各地的其他機器人和人類玩家競爭,獲得相應的排名。爲了做到這一切,你需要完成以下任務:

  • 構建一個圍棋落子預測-你在第6章和第7章中訓練的神經網絡需要集成到一個框架中,允許你在遊戲中使用它們。在第8.1節中,我們將按照第3章中得到的隨機落子AI的概念創建深度學習機器人
  • 提供一個圖形界面---作爲人類,我們需要這個界面可以方便地對抗圍棋機器人。在8.2節中,我們將爲您配備一個有趣的屆滿讓你可以與AI進行對抗。
  • 把AI部署到雲上----如果你的計算機中沒有強大的GPU,你就不會得到訓練強大的圍棋機器人。幸運的是,大多數的雲都提供GPU實例,但即使你有足夠強大的GPU進行訓練,你仍然可能希望把你以前訓練過的模型託管在服務器上。在第8.3節中,我們將向您展示如何託管,要了解更多的細節可以去看附錄D。
  • 與其他AI對弈----人類喜歡使用圖形和其他界面,但對於機器人來說,習慣上通過標準化的協議進行通信。在第8.4節中,我們將向您介紹通用圍棋文本協議(GTP)。下面兩點是重要的組成部分:

                      1.與其他機器人對弈-----後你將爲你的機器人建立一個GTP前端,讓它與8.5節中的其他程序進行對抗。我們將教你                         如何讓你的機器人在本地與另外兩個圍棋程序進行比賽,去看看你的AI有多好。

                      2.在聯機圍棋服務器上部署機器人-----在第8.6節中,我們將向您展示如何在聯機圍棋平臺上部署機器人,以便讓其                        他機器人可以和你的機器人競爭。這樣,您的機器人甚至可以得到排名,所有這些我們將在最後一節展示給您。因                       爲大部分材料都是技術性的,你可以附錄E中找到大量細節。 

8.1 創建一個深度學習的落子預測AI 

現在,您已經有了所有的構建塊來爲圍棋數據構建一個強大的神經網絡,讓我們將這些網絡集成到一個爲它們服務的代理中。回顧第三章的概念,我們將其定義實現select_move方法爲當前遊戲狀態選擇下一個落子點的類。讓我們使用Keras模型和圍棋盤Encoder去編寫DeepLearningAgent(將此代碼放入dlgo中的agent模塊中的predict.py中)

from dlgo.agent.base import Agent
from dlgo.agent.helpers import is_point_true_eye
from dlgo import goboard
from dlgo import Encoder


class DeepLearningAgent(Agent):

    def __init__(self, model, encoder):
        super().__init__()
        self.model = model
        self.encoder = encoder

接着,您將使用編碼器將棋盤撞他轉換爲特徵,然後使用該模型去預測下一步落子。實際上,您將使用該模型去計算所有可能的概率分佈。

# 返回整個棋盤預測概率分佈
    def predict(self, game_state):
        encoded_state = self.encoder.encode(game_state)
        input_tensor = np.array([encoded_state])
        return self.model.predict(input_tensor)[0]

    def select_move(self,game_state):
        num_moves = self.encoder.board_width*self.encoder*board_height
        # 獲得預測概率分佈
        move_probs = predict(game_state)

接下來,您可以稍微改變存儲在move_probs中的概率分佈。首先,計算所有值的三次方,以大幅增加可能和不可能落子點之間的距離。你希望最好的落子點能儘可能挑選頻繁,然後使用一種叫做裁剪的技巧,它可以防止落子概率太接近0或1。這是通過定義一個極小的正值,ε=0.000001,設置值小於ε到ε,值大於1-ε到1-ε。然後,對得到的值進行規範化,再次得到概率分佈

 

  # 大幅拉開可能點與非可能點之間的距離
        move_probs = move_probs ** 3
        small_data = 1e-6
        # 防止落子概率卡在0或1
        move_probs = np.clip(move_probs,small_data,1-small_data)
        # 重新得到另一個概率分佈
        move_probs = move_probs/sum(small_data)

您進行此轉換是因爲您希望根據它們的概率從這個分佈採樣落子點。(另一個可行的策略不是抽樣調查,而是始終採取分佈的最大值)。你不採取第二種做法的好處是有時會選擇其他可能有用的落子

     # 把概率轉成一個排序列表
        candidates = np.arange(num_moves)
        # 按照落子概率進行採樣,不允許取相同的落子
        ranked_moves = np.random.choice(
            candidates, num_moves, replace=False, p=move_probs)
        # 從最高層開始,找到一個有效的落子,不會減少視野空間
        for point_index in ranked_moves:
            point = self.encoder.decode_point_index(point_index)
            if game_state.is_valid(goboard.Move.play(point)) and \
                    not is_point_an_eye(game_state.board, point, game_state.current_player):
                return goboard.Move.play(point)
        return goboard.Move.pass_turn()

你訓練了一個深度學習模型,並創建了一個代理,然後你堅持下去。稍後,這個代理將被反序列化成了服務,這樣人類玩家或其他機器人就可以對抗它。要執行序列化步驟,就需要序列化Keras的格式。當您持久化Keras模型時,它將以HDF5進行存儲,這是一種有效的序列化格式。HDF5文件包含靈活的組,用於存儲元信息和數據。對於任何一個Keras模型,您可以調用model.save(“model_path.h5”)將完整模型(即神經網絡體系結構和所有權重)持久化爲本地文件model_path.h5。你唯一需要的就是在保持像這樣的Keras模型之前,先安裝Python庫h5py

要存儲完整的代理,您可以添加一個額外的組以獲取有關你的圍棋棋盤編碼器。

 # 序列化模型
    def serialize(self, h5file):
        # 先創建一個編碼器組
        h5file.create_group('encoder')
        h5file['encoder'].attrs['name'] = self.encoder.name()
        h5file['encoder'].attrs['board_width'] = self.encoder.board_width
        h5file['encoder'].attrs['board_height'] = self.encoder.board_height
        # 再創建一個模型組
        h5file.create_group('model')
        kerasutil.save_model_to_hdf5_group(self.model, h5file['model'])

最後,在序列化模型之後,您還需要知道如何從HDF5文件去加載它。


    # 從序列化的文件中加載模型
    def load_prediction_agent(h5file):
        # 加載模型
        model = kerasutil.load_model_from_hdf5_group(h5file['model'])
        # 加載編碼器
        encoder_name = h5file['encoder'].attrs['name']
        if not isinstance(encoder_name, str):
            encoder_name = encoder_name.decode('ascii')
        board_width = h5file['encoder'].attrs['board_width']
        board_height = h5file['encoder'].attrs['board_height']
        encoder = encoders.get_encoder_by_name(
            encoder_name, (board_width, board_height))
        return DeepLearningAgent(model, encoder)
這就完成了我們深度學習代理的定義。作爲下一步,您必須確保此代理與環境能與人進行交互。通過將DeepLearningAgent嵌入到人類玩家可以在瀏覽器中使用的Web應用程序中
 

8.2.將你的機器人放到一個網絡前端

在第6章和第7章中,你設計並訓練了一個神經網絡,它預測一個人在圍棋遊戲中會下哪裏。在第8.1節中,你將落子預測模型轉換爲DeepLearningAgent,下一步是與你的機器人對弈!回到第三章,你建立了一個光禿禿的界面,讓你可以在控制檯輸入落子座標,而你的RandomBot則將其迴應打印到控制檯。現在你已經建立了一個更復雜的機器人,它應該有一個更好的前端來與人類玩家交流對弈。

在本節中,您將把DeepLearningAgent加入到PythonWeb應用程序,這樣您就可以在Web瀏覽器中與它對局了。您將使用Flask通過HTTP爲這樣的代理服務。在瀏覽器方面,您將使用JavaScript中一個名叫jgoboard的庫來渲染人類可以使用的圍棋棋盤。.8.1提供了將在本章中構建的應用程序的概述。

8.3.在雲上的訓練和部署你的AI

直到這一點,所有的開發都是在本地機器上進行的。如果你的電腦上有一個現代化的GPU,那就訓練我們開發的深層神經網絡第如果你沒有強大的GPU,或者不能在它上留出任何計算時間,那麼去租用雲使用GPU計算通常是一個很好的選擇。在第8.2節中,通過Web應用程序運行機器人由本地主機託管。如果你想和朋友分享你的機器人,或者公開它,這並不完全理想。你既不想確保你的電腦日夜運轉,也不想讓公衆知道去你的機器。通過在雲中託管您的機器人,讓你可以將開發與部署分開,並且可以簡單地與任何對與你的AI對弈感興趣的人共享URL。

因爲這個話題很重要我們把它完全放在了附錄D。在附錄D中,您將瞭解如何開始使用一個特定的雲提供商AmazonWeb服務(AWS)。您將在附錄中學習以下技能:

  • 使用AWS創建帳戶
  • 靈活設置、運行和終止虛擬服務器實例創建一個AWS實例
  • 在費用合理的情況下創建適合在雲GPU上進行深度學習的模型訓練
  • 在一個(幾乎)免費的服務器上放置你的AI

通過HTTP除了學習這些有用的技能外,附錄D也展示了部署一個完整的Go機器人的先決條件,該機器人可以連接到聯機Go服務器

8.4 與其他AI對弈:使用GTP

在8.2節中,您看到了如何將AI框架集成到Web前端。爲此,您使用HTTP(運行Web的核心協議之一)處理了機器人和人類棋手之間的通信。爲了避免分心,我們有目的地忽略了所有細節,但有一個標準化的協議是必要的,以實現這一點。人類和機器人不能使用一種通用語言來交換圍棋落子,但是協議可以充當橋樑。

GTP(圍棋文本協議)是世界各地圍棋服務器用來連接人類棋手和他們平臺上的機器人。許多離線Go程序也是基於GTP的。本節通過示例向您介紹GTP;您將在Python中實現協議的一部分並使用此實現來讓你的機器人與其他AI進行對弈。

在附錄C中,我們解釋瞭如何下載GNUGO和Pachi,這兩個通用的圍棋程序幾乎適用於所有的操作系統。我們建議兩者都安裝,所以請確保在您的系統上有兩個程序。你不需要任何前端,只需要簡單的命令行工具。如果安裝了GNU Go,您可以GTP模式啓動它:

gnugo ­­--mode gtp

使用此模式,您現在可以探索GTP是如何工作的。GTP是一種基於文本的協議,因此您可以在終端中鍵入命令並按回車鍵。例如,要設置9×9的棋盤,可以鍵入boardsize 9。這將觸發GNU Go返回響應並確認命令已正確執行。每一個成功的GTP命令都會觸發一個以=開頭的響應,而失敗的命令會導致一個?要檢查當前的棋盤狀態,您可以發出showboard命令,它將按預期打印出一個空的9×9棋盤。

在實際的遊戲中,兩個命令是最重要的:genmove和play..第一個命令genmove用於請求GTP bot去生成下一個落子。GTP機器人通常也會應用這個落子到它內部的遊戲狀態。所有這些命令都需要參數是玩家的棋子顏色,無論是黑色還是白色。例如,要生成一個白色落子並將其放置在GNU Go的棋盤上,請鍵入genmove white。這將導致響應,如=C4,這意味着GNUGo接受此命令(=),並將白石放置在C4。如您所見,GTP接受第2章和第2章所介紹的標準座標

另一個與遊戲相關的動作是play。此命令用於讓GTP機器人知道它必須在棋盤上落子。例如,你通過鍵入play black D4來讓它將黑棋下在D4上,它將返回一個=來確認此命令。當兩個機器人互相對抗時,他們會輪流要求對方落出下一步,然後將選擇的落子放在棋盤上。這一切都很直截了當----但我們遺漏了許多細節。一個完整的GTP客戶端有更多的命令要處理,從處理讓子棋到處理時間設置和計數規則。如果您對GTP的細節感興趣,請參閱http://mng.bz/MWNQ.。儘管如此,在一個基本的層次上,genmove和play將足以讓我們的深度學習機器人對抗GNUGo和Pachi。

要處理GTP幷包裝您的Agent概念,以便它可以通過使用此協議交換圍棋落子,您可以創建一個名爲GTP的新dlgo模塊,我們建議直接跟蹤我們在http://mng.bz/a4Wj的GitHub上的實現。

首先,讓我們形式化GTP命令。要做到這一點,我們必須注意,在許多圍棋服務器上,命令需要獲得序列號,以確保我們能夠匹配命令和響應。這些序號數字是可選的,可以是None的。對我們來說,GTP命令由序列號、命令和該命令的潛在多個參數組成,這個命令在gtp模塊下的command.py裏找到。 ,

class Command:
    # GTP命令由序列號、命令和該命令的潛在多個參數組成
    def __init__(self, sequence, name, args):
        self.sequence = sequence
        self.name = name
        self.args = tuple(args)

    # 判斷命令是否相同
    def __eq__(self, other):
        return self.sequence == other.sequence and \
            self.name == other.name and \
            self.args == other.args

    def __repr__(self):
        return 'Command(%r, %r, %r)' % (self.sequence, self.name, self.args)

    def __str__(self):
        return repr(self)

接下來,要將從命令行輸入的文本解析爲Command。例如,解析“999playwhiteD4”應該導致命令(999,‘play’,(‘white’,‘D4’)。parse就是實現了這種功能。

  # 根據命令字符串解析命令
    def parse(command_string):
        pieces = command_string.split()
        try:
            sequence = int(pieces[0])  # 序號
            pieces = pieces[1:]
        except ValueError:  # 如果第一個不是數字,就沒有序列號
            sequence = None
        name, args = pieces[0], pieces[1:]
        return Command(sequence, name, args)

我們剛纔認爲GTP座標是標準表示法,所以將GTP座標解析成棋盤位置,反之也是簡單的。定義兩個輔助函數使用gtp在座標和位置之間轉變

from dlgo.gotypes import Point
from dlgo.agent.FastRandomAgent.goboard_fast  import Move

COLS = 'ABCDEFGHJKLMNOPQRST'

# 將落子轉成gtp棋盤位置
def coords_to_gtp_position(move):
    point = move.point
    return COLS[point.col - 1] + str(point.row)

# 將gtp棋局位置轉成座標
def gtp_position_to_coords(gtp_position):
    col_str, row_str = gtp_position[0], gtp_position[1:]
    point = Point(int(row_str), COLS.find(col_str.upper()) + 1)
    return Move(point)

 8.5 和本地其他機器人進行對弈

 現在您瞭解了GTP的基本知識,讓我們深入到一個應用程序中,並構建一個程序來加載您的一個機器人,並讓它與GNUGo或Pachi競爭。在我們開始程序之前,我們只有一個技術問題要解決---什麼時候讓我們的機器人投降或pass

8.5.1 當一個機器人應該投降或pass

到目前爲止,你的深度學習機器人沒有辦法知道什麼時候停止下棋。你至今設計它們的方式是,你的機器人總是會選擇最好的落子來下。這個直到對局結束才停止是有害的,當情況看起來有點太糟糕的時候,選擇pass甚至投降可能會更好。出於這個原因,您將實施終止策略:您將告訴機器人什麼時候停下來。在第13章和第14章中,您將學習強大的技術,這將使這完全無用(您的機器人將學會判斷當前的棋局,從而判斷是否投降)。但目前,這個概念是有用的,並將幫助您試驗這種方式部署一個機器人對抗其他對手。

調用dlgo下的agent下的termination.py的TerminationStrategy 。它所做的只是決定你什麼時候應該pass投降----默認情況下,你永遠不會pass或投降。 

from dlgo import goboard
from dlgo.agent.base import Agent
from dlgo.ComputeWinner import compute_game_result


class TerminationStrategy:
     def __init__(self):
         pass
     
     def should_pass(self,game_state):
         return False
     
     def should_resign(self,game_state):
         return False

 停止遊戲的一個簡單的啓發是當你的對手pass時pass。你必須依靠這樣一個事實,即你的對手知道什麼時候要pass,但這是一個開始,而且它在對抗GNU Go和Pachi。

class PassWhenOpponentPasses(TerminationStrategy):

    def should_pass(self, game_state):
        if game_state.last_move is not None:
            return True if game_state.last_move.is_pass else False

def get(termination):
    if termination == 'opponent_passes':
        return PassWhenOpponentPasses()
    else:
        raise ValueError("Unsupported termination strategy: {}"
                         .format(termination))

 在termination.py中,你還發現了另一種叫做ResignLargeMargin的策略,它每當遊戲的估計分數對手過於有利時就會投降。你還能做許多別的策略,但要記住,最終你可以通過機器學習擺脫這種東西。

# 過於有利於對手就resign
class ResignLargeMargin(TerminationStrategy):

    def __init__(self, own_color, cut_off_move, margin):
        TerminationStrategy.__init__(self)
        self.own_color = own_color
        self.cut_off_move = cut_off_move
        self.margin = margin

        self.moves_played = 0

    def should_pass(self, game_state):
        return False

    def should_resign(self, game_state):
        self.moves_played += 1
        if self.moves_played:
            game_result = scoring.compute_game_result(self)
            if game_result.winner != self.own_color and game_result.winning_margin >= self.margin:
                return True
        return False

最後一件事,爲了讓機器人相互對抗,你最不需要的就是給代理配備一個終止策略,以便在適當的時候pass或投降。

class TerminationAgent(Agent):

    def __init__(self, agent, strategy=None):
        Agent.__init__(self)
        self.agent = agent
        self.strategy = strategy if strategy is not None \
            else TerminationStrategy()

    def select_move(self, game_state):
        if self.strategy.should_pass(game_state):
            return goboard.Move.pass_turn()
        elif self.strategy.should_resign(game_state):
            return goboard.Move.resign()
        else:
            return self.agent.select_move(game_state)

8.5.2 讓你的圍棋AI與其他圍棋程序對抗

在討論了終止策略之後,您現在可以讓圍棋機器人與其他程序對局。在gtp模塊中的play_local.py下,找到一個在你的某個機器人與無論是GNUGo還是Pachi之間設置遊戲的腳本。從必要的導入開始,一步一步地完成這個腳本 

from __future__ import print_function
import subprocess
import re
import h5py

from dlgo.agent.DeepLearningAgent.DeepLearningAgent import load_prediction_agent
from dlgo.agent.DeepLearningAgent.termination import PassWhenOpponentPasses, TerminationAgent
from dlgo.agent.FastRandomAgent.goboard_fast import GameState, Move
from dlgo.gotypes import Player
from dlgo.gtp.board import gtp_position_to_coords, coords_to_gtp_position
from dlgo.utils import print_board
from dlgo.ComputeWinner import compute_game_result

要初始化LocalGtpBot,您需要提供深度學習代理和可選的終止策略。此外,您還可以指定應該讓幾個子,以及要對弈的對手。對於後者,你可以在gnugo和pachi之間進行選擇..LocalGtpBot將這些程序中的任何一個初始化爲子進程,然後您的AI和它的對手將通過GTP進行通信。

# tag::play_local_init[]
class LocalGtpBot:

    def __init__(self, go_bot, termination=None, handicap=0,
                 opponent='gnugo',our_color='b'):
        self.bot = TerminationAgent(go_bot, termination)  # 用代理和終止策略初始化機器人
        self.handicap = handicap
        self._stopped = False
        self.game_state = GameState.new_game(19)

        self.our_color = Player.black if our_color == 'b' else Player.white
        self.their_color = self.our_color.other

        cmd = self.opponent_cmd(opponent)  #你的對手將是GNU Go或Pachi
        # 開闢子進程
        pipe = subprocess.PIPE
        self.gtp_stream = subprocess.Popen(
            cmd, stdin=pipe, stdout=pipe  #從命令行讀寫GTP命令
        )

    @staticmethod
    def opponent_cmd(opponent):
        if opponent == 'gnugo':
            return ["gnugo", "--mode", "gtp"]
        elif opponent == 'pachi':
            return ["pachi"]
        else:
            raise ValueError("Unknown bot name {}".format(opponent))

 我們在這裏演示的工具是command_and_response,它可以發出GTP命令並讀取該命令的響應

 # 發送命令
    def send_command(self, cmd):
        self.gtp_stream.stdin.write(cmd.encode('utf-8'))

    # 得到迴應
    def get_response(self):
        succeeded = False
        result = ''
        while not succeeded:
            line = self.gtp_stream.stdout.readline()
            if line[0] == '=':
                succeeded = True
                line = line.strip()
                result = re.sub('^= ?', '', line)
        return result

    def command_and_response(self, cmd):
        self.send_command(cmd)
        return self.get_response()

下棋的效果如下:

  1. 用GTP棋盤大小命令去設置棋盤。你在這裏只允許19×19圍棋棋盤,因爲你的深度學習機器人是爲此量身定做的。
  2. 在set_handicap方法中正確設置讓子。
  3. 對弈本身,你將在play方法中涵蓋它。
 # 運行
    def run(self):
        self.command_and_response("boardsize 19\n")
        self.set_handicap()
        self.play()

    # 設置讓子
    def set_handicap(self):
        if self.handicap == 0:
            self.command_and_response("komi 7.5\n")
        else:
            stones = self.command_and_response("fixed_handicap {}\n".format(self.handicap))
            for pos in stones.split(" "):
                move = gtp_position_to_coords(pos)
                self.game_state = self.game_state.apply_move(move)

你的機器人對弈的遊戲邏輯很簡單:沒有一個對手停下來,輪流並持續落子。機器人在名爲play_our_move和play_their_move的方法中做到了這一點。您還清除屏幕,並打印出當前的棋局和對結果的粗略估計。

    def play(self):
        while not self._stopped:
            if self.game_state.current_player == self.our_color:
                self.play_our_move()
            else:
                self.play_their_move()
            print(chr(27) + "[2J")
            print_board(self.game_state.board)
            print("Estimated result: ")
            print(compute_game_result(self.game_state))
    # 我方落子
    def play_our_move(self):
        move = self.bot.select_move(self.game_state)
        self.game_state = self.game_state.apply_move(move)

        our_name = self.our_color.name
        
        if move.is_pass:
            self.command_and_response("play {} pass\n".format(our_name))
        elif move.is_resign:
            self.command_and_response("play {} resign\n".format(our_name))
        else:
            pos = coords_to_gtp_position(move)
            self.command_and_response("play {} {}\n".format(our_name, pos))
       

    # 對方落子
    def play_their_move(self):
        their_name = self.their_color.name
        pos = self.command_and_response("genmove {}\n".format(their_name))
        if pos.lower() == 'resign':
            self.game_state = self.game_state.apply_move(Move.resign())
            self._stopped = True
        elif pos.lower() == 'pass':
            self.game_state = self.game_state.apply_move(Move.pass_turn())
                
            if self.game_state.last_move.is_pass:
                self._stopped = True
        else:
            move = gtp_position_to_coords(pos)
            self.game_state = self.game_state.apply_move(move)

然後就可以使用你之前訓練的AI進行對弈了

from dlgo.gtp.play_gtp_local import LocalGtpBot
from dlgo.agent.DeepLearningAgent.DeepLearningAgent import load_prediction_agent
from dlgo.agent.DeepLearningAgent.termination import PassWhenOpponentPasses

my_bot = load_prediction_agent("deep_go.h5")
gnu_go = LocalGtpBot(go_bot=my_bot, termination=PassWhenOpponentPasses(),
                         handicap=0, opponent='pachi', )
gnu_go.run()

在圖的頂部,你看到你打印的棋盤,然後是你目前的估計。在下半變,你可以在左邊看到Pacho的比賽狀態(與你的狀態相同),在右邊Pachi給你一個關於遊戲的評估,它用於判斷棋盤上的點屬於哪一方。

這是一個希望令人信服和激動人心的演示.,但這還不是故事的結尾。

GNU Go

GNU Go是在1989年開發的,是至今仍在使用的最古老的圍棋引擎之一。最近一次發佈是在2009年。儘管最近沒有什麼進展,但GNU Go仍然是一個受歡迎的AI 對手,在許多圍棋o服務器上爲初學者服務。此外,它是基於人工製作規則的最強的圍棋引擎之一;這與MCTS和深度學習機器人形成了很好的對比。你可以從www.gnu.org/software/gnugo/download.html下載安裝GNUGo。此頁面包括安裝GNUGo作爲命令行接口(CLI)工具的說明和各種圖形界面。爲了要安裝CLI工具,您需要從http://ftp.gnu.org/gnu/gnugo/下載最近版本的AI二進制文件,解壓縮各自的tarball,並遵循下載中包含的INSTALL和README文件中的平臺說明。對於圖形界面,我們建議從www.rene­grothmann.de/jago/下載Windows和Linux版本的JagoClient和從http://sente.ch/software/goban/freegoban.html.下載MacOS版本的FreeGoban

Pachi

你可以在http://pachi.or.cz/.上找到一個比GNU Go整體要強得多的程序Pachi,此外,Pachi的源代碼和詳細的安裝說明可以在https://github.com/pasky/pachi中找到.要測試Pachi,請在命令行上運行Pachi,並鍵入genmove Black,讓它在9×9棋盤上爲您生成一個黑色落子。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章