書籍「将棋AIで学ぶディープラーニング」のプログラムコードをGoogle Colabで動かす、学習と対局も
- 以前は
- 「書籍「将棋AIで学ぶディープラーニング」のプログラムコードを動かす」にて、写経部分をコピペできるようにしました。
- 「書籍「将棋AIで学ぶディープラーニング」のプログラムコードをCPUで動かす」にて、CPUで動くように書きかえました。
- 今回は
- Google Colabで動かします。
一番伝えたい事
- 「ColaboratoryでのGoogle Driveへのマウントが簡単になっていたお話 - Qiita」が凄く嬉しかった。
- ですが、いいねが伸びてない、検索上位に上がって来てないので、活用記事を書いて支援したい。
やること
- ローカル端末で資材を集める
- Googleドライブと同期する
- Google ColabでGoogleドライブをマウント
- 環境つくり
- 動作確認
- 学習
- 対局
ローカル端末で資材を集める
- 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 hoge
やls
などが%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っていつから対話できるようになりましたか?楽ちん。
usi
- 戻りの最終行は
usiok
setoption name modelfile value /content/MyDrive/python-dlshogi/model/model_policy_value_resnet
- 戻りはない
isready
- 戻りは
readyok
position startpos
- 戻りは
lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1
go
- 戻りの最終行は
bestmove ....
quit
学習
ローカル端末で資材を集める
powershellで準備
- wdoor2016.7zをダウンロードする
- kifulist_test_100.txtとkifulist_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
- 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をパクります
```python: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
- いざ実行、
usi
→setposition startpos
→go
とかするとbestmove
が返ってきます - さらに
setposition ~
とgo
で対局が進みます - または
go
だけ連続で渡せばランダムなbestmoveが返ってくることが確認できます - 適当に
quit
して終わりましょう
Colab_cel_ex5
usi(player)
- これで分かる通り、3ファイルあれば取り合えず対局できそうです
-
BasePlayer
をパクる -
自前Player
をつくる -
usi
クライアントをつくる
-
- ロジックを挟むポイントは、
- 自前Playerの
go
の中身を良い感じにboard
から情報をとって、bestmove
を決定するだけです - ランダムの例ならこの部分を変更します
- 自前Playerの
Colab_cel_ex3抜粋
moves = [move for move in self.board.legal_moves]
bestmove = random.choice(moves)
- この基本を押さえて
python-dlshogi
のコードを見ると、ディープラーニングの成果をどのように呼び出しているか理解しやすいと思います
書籍紹介を再掲載
おしまい