LoginSignup
19
18

More than 5 years have passed since last update.

書籍「将棋AIで学ぶディープラーニング」のプログラムコードをGoogle Colaboratoryで動かす + GPUで学習と対局も

Last updated at Posted at 2018-09-19

書籍「将棋AIで学ぶディープラーニング」のプログラムコードをGoogle Colabで動かす、学習と対局も

一番伝えたい事

やること

  1. ローカル端末で資材を集める
  2. Googleドライブと同期する
  3. Google ColabでGoogleドライブをマウント
  4. 環境つくり
  5. 動作確認
  6. 学習
  7. 対局

ローカル端末で資材を集める

  • python-dlshogi on Githubをクローンする。
    • git clone https://github.com/TadaoYamaoka/python-dlshogi.git

Googleドライブと同期する

章題のとおり。

Google ColabでGoogleドライブをマウント

Go to this URL in a browser:が一度だけでてきます。これまでのイディオムだと二度必要だったので楽になりました。

Colab_cel_1
from google.colab import drive
drive.mount('/content/drive')

ここでは、My Driveが空白含みで扱いづらいのでリンクはってみました。

Colab_cel_2
%cd /content
!ln -snf '/content/drive/My Drive/' MyDrive

やってて気づきましたが、一つのセルに一行で書くだけなら、cd hogelsなどが%cd!lsとしなくて良くなりました。楽ちんです。

環境つくり

  • chainerとpython-shogiをいれます。
Colab_cel_3
!curl https://colab.chainer.org/install | sh -
!pip install python-shogi==1.0.8

GPUが有効なことも確認しましょう。

Colab_cel_4
import chainer
print('GPU availability:', chainer.cuda.available)
print('cuDNN availablility:', chainer.cuda.cudnn_enabled)

お目当てのpython-dlshogiをありがたくインストールします。

Colab_cel_5
%cd /content/MyDrive/python-dlshogi
!mkdir log
!pip install --no-cache-dir -e .

動作確認

  • ためしにpolicyプレイヤを動かします。
Colab_cel_6
# !python -m pydlshogi.usi.usi_policy_player
from pydlshogi.usi.usi import *
from pydlshogi.player.policy_player import *

player = PolicyPlayer()
usi(player)
  • つぎのテキスト入力を順次して動作することを確認します。
    • Colabっていつから対話できるようになりましたか?楽ちん。
  1. usi
    1. 戻りの最終行はusiok
  2. setoption name modelfile value /content/MyDrive/python-dlshogi/model/model_policy_value_resnet
    1. 戻りはない
  3. isready
    1. 戻りはreadyok
  4. position startpos
    1. 戻りはlnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1
  5. go
    1. 戻りの最終行はbestmove ....
  6. quit

学習

ローカル端末で資材を集める

powershellで準備

  • wdoor2016.7zをダウンロードする
  • kifulist_test_100.txtkifulist_train_1000.txtを編集する
get-kifu.ps1
# Googleドライブのとこで作業
pushd $googledrive

# 棋譜
$homepage="http://wdoor.c.u-tokyo.ac.jp/shogi/"
$filehost=(wget $homepage|%{$_.Links}|?{$_.href -match "downloads"}|?{$_.href -match "2016"}).href
$filename=$filehost.split("/")[-2]
$fileref=(wget $filehost|%{$_.Links}|?{$_.href -match $filename+"$"}).href
$uri = New-Object System.Uri $filehost;
$downloadUrl = New-Object System.Uri ($uri,  ($fileref[0]).Replace('&','&'))
wget -uri $downloadUrl -OutFile $filename
$kifuarchive = $filename

# 7zip
$homepage="https://sevenzip.osdn.jp/"
$downloadpage=(wget $homepage|%{$_.Links}|?{$_.innerText -eq "ダウンロード"}|?{$_.href -match "download"}).href
$filehost=(wget $downloadpage|%{$_.Links}|?{$_.innerText -eq "ダウンロード"}|?{$_.href -match "7za"}).href
$filename=$filehost.split("/")[-2]
$fileref=(wget $filehost|%{$_.Links}|?{$_.href -match $filename+"$"}).href
$uri = New-Object System.Uri $filehost;
$downloadUrl = New-Object System.Uri ($uri,  ($fileref[0]).Replace('&','&'))
wget -uri $downloadUrl -OutFile $filename
$7zaarchive = $filename

# Expand zip
Expand-Archive $7zaarchive
$7zaexe = (Get-Item $7zaarchive).BaseName+"/7za.exe"

# Expand 7z
& "$7zaexe" x "$kifuarchive"

# del zip 7z
rmdir -recurse (Get-Item $7zaarchive).BaseName
del $7zaarchive
del $kifuarchive

# kifulist_*.txt
$kifulists=Get-Childitem python-dlshogi|?{$_ -match "kifulist_.+\.txt"}|%{$_.fullname}
# "D:\2016\" to "/content/MyDrive/2016/"
foreach($kifulist in $kifulists) {
  (Get-Content $kifulist) | %{ $_ -replace "D:\\2016\\", "/content/MyDrive/2016/"} | Set-Content $kifulist
}
# crlf to lf
foreach($kifulist in $kifulists) {
  [string]::Join("`n",(Get-Content $kifulist))  | Set-Content $kifulist
}

Googleドライブと同期する その2

章題のとおり。

policy学習

Colab_cel_7
%run -i train_policy.py kifulist_train_1000.txt kifulist_test_100.txt --eval_interval 100 --log log

対局の準備

  • python-dlshogi/model/model_policyが更新されています。
  • これを使い対局しましょう。
  • とりあえずpolicy対policyです

将棋サーバ

  • shogi-serverを取得
Colab_cel_8
%cd /content/MyDrive/
!git clone git://git.sourceforge.jp/gitroot/shogi-server/shogi-server.git
%cd /content/MyDrive/shogi-server
%mkdir player-logs
!apt-get install --no-install-recommends ruby
  • shogi-serverをデーモン実行
Colab_cel_9
%cd /content/MyDrive/shogi-server
!ruby shogi-server --daemon . \
 --pid-file ./shogi-server.pid \
 --player-log-dir ./player-logs \
 test 4081

クライアント実行スクリプトをつくる

  • playerをpythonモジュール実行する、というスクリプト
Colab_cel_10
%%writefile /content/MyDrive/usi_policy_player
python3 -m pydlshogi.usi.usi_policy_player
Colab_cel_11
%%writefile /content/MyDrive/usi_search1_player
python3 -m pydlshogi.usi.usi_search1_player
Colab_cel_12
%%writefile /content/MyDrive/start_shogi_game
ruby /content/MyDrive/shogi-server/bin/usiToCsa.rb --host localhost --port 4081 --id pydlshogi1 --password pydlshogi1p --gamename=test1 --hash=12000 --keep-alive=60 --options="modelfile=/content/MyDrive/python-dlshogi/model/model_policy" /content/MyDrive/usi_policy_player &
ruby /content/MyDrive/shogi-server/bin/usiToCsa.rb --host localhost --port 4081 --id pydlshogi2 --password pydlshogi2p --gamename=test1 --hash=12000 --keep-alive=60 --options="modelfile=/content/MyDrive/python-dlshogi/model/model_value" /content/MyDrive/usi_search1_player &
echo start shogi game

対局する

Colab_cel_12
!chmod +x /content/MyDrive/usi_policy_player
!chmod +x /content/MyDrive/usi_search1_player
!chmod +x /content/MyDrive/start_shogi_game
!/content/MyDrive/start_shogi_game
  • 出力は次の通り
  • 対局は正常に終わっていますが
  • input()についてEOFErrorがあります、これは諦める
  • ディレクトリshogi-server/yyyy/mm/dd/にcsaファイルが出来ます
正常に対戦が終わった様子
start shogi game
Starting engine...  /content/MyDrive/usi_policy_player
Starting engine...  /content/MyDrive/usi_search1_player
Connecting to localhost:4081...
Login...  test1 pydlshogi1,xxxxxxxx
LOGIN:pydlshogi1 OK
Wait for a game start...
Connecting to localhost:4081...
Login...  test1 pydlshogi2,xxxxxxxx
LOGIN:pydlshogi2 OK
Wait for a game start...
game crated test+default-1500-0+pydlshogi2+pydlshogi1+20181009022757
game crated test+default-1500-0+pydlshogi2+pydlshogi1+20181009022757
#RESIGN
#LOSE
game finished.
#RESIGN
Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/content/drive/My Drive/python-dlshogi/pydlshogi/usi/usi_search1_player.py", line 5, in <module>
#WIN
game finished.
    usi(player)
  File "/content/drive/My Drive/python-dlshogi/pydlshogi/usi/usi.py", line 3, in usi
    cmd_line = input()
EOFError: EOF when reading a line
Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/content/drive/My Drive/python-dlshogi/pydlshogi/usi/usi_policy_player.py", line 5, in <module>
    usi(player)
  File "/content/drive/My Drive/python-dlshogi/pydlshogi/usi/usi.py", line 3, in usi
    cmd_line = input()
EOFError: EOF when reading a line

活用する

  • 繰り返し対戦できるようにして云々
  • csaファイルを活用して追加の学習を云々
  • ビジュアルで対局内容を確認したいときは「JS将棋盤」 でcsaファイルを再生してはいかがでしょうか

オリジナルPlayer作成のとっかかり

  • python-shogiはCSAクライアントです
  • python-dlshogiはUSIクライアントです
  • python-dlshogiを参考にディープラーニングとか無しでランダムに合法手を返すプレーヤーは次のように簡単にできます
  • 新規にGoogle Colabを開いて次の4セルだけ実行しましょう。

  • まずpython-shogi取得

Colab_cel_ex1
!pip install python-shogi==1.0.8
  • BasePlayerをパクります
Colab_cel_ex2
import shogi

class BasePlayer:
    def __init__(self):
        self.board = shogi.Board()

    def usi(self):
        pass

    def usinewgame(self):
        pass

    def setoption(self, option):
        pass

    def isready(self):
        pass

    def position(self, moves):
        if moves[0] == 'startpos':
            self.board.reset()
            for move in moves[2:]:
                self.board.push_usi(move)
        elif moves[0] == 'sfen':
            self.board.set_sfen(' '.join(moves[1:]))
        # for debug
        print(self.board.sfen())

    def go(self):
        pass

    def quit(self):
        pass
  • ランダムプレーヤーを定義、各メソッドの中も最低限にしたつもり
Colab_cel_ex3
import random

class RandomPlayer(BasePlayer):
    def __init__(self):
        super().__init__()

    def usi(self):
        print('id name policy_player')
        print('usiok')

    def setoption(self, option):
        pass

    def isready(self):
        print('readyok')

    def go(self):
        if self.board.is_game_over():
            print('bestmove resign')
            return

        moves = [move for move in self.board.legal_moves]        
        bestmove = random.choice(moves)
        print('bestmove', bestmove.usi())
  • usiクライアントを定義、プレイヤーを呼んでる
Colab_cel_ex4
player = RandomPlayer()

def usi(player):
    while True:
        cmd_line = input()
        cmd = cmd_line.split(' ', 1)

        if cmd[0] == 'usi':
            player.usi()
        elif cmd[0] == 'setoption':
            option = cmd[1].split(' ')
            player.setoption(option)
        elif cmd[0] == 'isready':
            player.isready()
        elif cmd[0] == 'usinewgame':
            player.usinewgame()
        elif cmd[0] == 'position':
            moves = cmd[1].split(' ')
            player.position(moves)
        elif cmd[0] == 'go':
            player.go()
        elif cmd[0] == 'quit':
            player.quit()
            break
  • いざ実行、usisetposition startposgoとかするとbestmoveが返ってきます
  • さらにsetposition ~goで対局が進みます
  • またはgoだけ連続で渡せばランダムなbestmoveが返ってくることが確認できます
  • 適当にquitして終わりましょう
Colab_cel_ex5
usi(player)
  • これで分かる通り、3ファイルあれば取り合えず対局できそうです
    • BasePlayerをパクる
    • 自前Playerをつくる
    • usiクライアントをつくる
  • ロジックを挟むポイントは、
    • 自前Playerのgoの中身を良い感じにboardから情報をとって、bestmoveを決定するだけです
    • ランダムの例ならこの部分を変更します
Colab_cel_ex3抜粋
 moves = [move for move in self.board.legal_moves]
 bestmove = random.choice(moves)
  • この基本を押さえてpython-dlshogiのコードを見ると、ディープラーニングの成果をどのように呼び出しているか理解しやすいと思います

書籍紹介を再掲載

将棋AIで学ぶディープラーニング
- マイナビBooks:出版元(サポートサイト←ここに正誤表あります)
- Amazon

おしまい

19
18
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
18