TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

第28回世界コンピュータ将棋選手権 出場結果

第28回世界コンピュータ将棋選手権に参加してきました。

dlshogiは、一次予選に7位で通過しましたが、二次予選では1勝8敗で24チーム中最下位という結果でした。

dlshogiは、今回注目されていたCrazy Shogiと同じくモンテカルロ木探索とディープラーニングを組み合わせたソフトです。
今回ディープラーニングを使用したチームは複数チームありましたが、一次予選通過できたのはdlshogiだけでした。
dlshogiの学習方法、探索の実装がある程度通用することが示せてよかったと思います。

大会では、参加者の方と情報交換できて、新たに試したいこともでてきました。
YSSの山下さんとPonanza Chainerの大渡さんに技術的な話を聞くことができて参加した甲斐があった思います。
ねね将棋とbroadenもモンテカルロ木探索とディープラーニングを試されており、有益な情報交換をすることができました。

来年は、Crazy Shogiも優勝を目指してくるということなので、こちらも負けないように頑張るつもりです。

dlshogi(wcsc28版)のビルド済みファイル公開

dlshogiの第28回世界コンピュータ将棋選手権バージョンのビルド済みファイルを公開しました。

第5回将棋電王トーナメントバージョンは、Chainerの環境構築が必要でしたが、USIエンジンの実行のみであれば不要になっています。
CUDA、cuDNNはライセンス上の問題が起きないように同梱していませんので、別途インストールが必要です。下記のページの説明を参照してください。

Release 第28回世界コンピュータ将棋選手権バージョン · TadaoYamaoka/DeepLearningShogi · GitHub

USIエンジンをAWSのWindowsインスタンスで実行する

以前にAWSWindowsサーバで、GPUを増やしても探索速度を上げられなかったということを書きましたが、後からバグがあって1個のGPUしか使っていなかったがわかりました。
バグを修正したバージョンで、p3.8xlargeで4GPUを使うと自宅のGPU2枚のPCより少し探索速度を上げることができました。
p3.16xlargeだと、なぜか探索速度が落ちてしまいました。
ということで世界コンピュータ選手権はp3.8xlargeを使うことにします。

探索速度の比較
ハードスペック スレッド数 シミュレーション/秒
Corei9 10コア+GPU2枚(TitanV+1080Ti) 255+255 10779
Xeon 32コア+GPU4枚(Tesla V100) 168+168+144+96 12224

スペックは2倍以上ですが、探索速度の向上は13%です。
スレッド数は探索速度が最大になるように調整した結果です。

AWSでUSIエンジンを実行する方法

dlshogiはLinuxでも実行できるようにしていますが、探索速度はWindowsの方が高いので、AWSのOSはWindowsにする予定です。

USIエンジンをAWSで実行するには、SSHでリモートで実行して標準入出力でやり取りすれば可能です。
将棋所は、実行ファイルに引数を渡すことができませんが、バッチファイルにSSHコマンド記述して、バッチファイルを登録すれば問題ありません。

WindowsのAMIは、デフォルトではSSHで接続できないため、自分でSSHサーバを構築する必要があります。
WidnowsでのSSHサーバの構築方法は、別の記事にしました。
AWSのWindows AMIにsshで接続する - TadaoYamaokaの開発日記

上記の記事を参考に、AWSWindowsサーバにSSHサーバを構築して、公開鍵で認証する設定を行います。
将棋所を実行するクライアントからsshコマンドで接続できることが確認できたら、以下のようなバッチファイルを作成します。

@echo off
C:\OpenSSH-Win64\ssh xxxx@xxxx.us-west-2.compute.amazonaws.com C:\Users\xxxx\Documents\dlshogi\usi

※ユーザ名とホスト名とUSIエンジンのパスは書き換えてください。

これを将棋所に登録します。
将棋所のエンジン選択は、デフォルトで拡張子が「.exe」のファイルしか表示されませんが、ファイル名に「*」を入力してEnterキーを押せば、バッチファイルも表示されるので、登録できます。

これで、ローカルで動くUSIエンジンと同様にエンジン設定と実行が可能です。
当然ですが、エンジン設定に設定するファイルパスはサーバ上でのパスです。

以上です。

アンサンブル対応

使えるGPU枚数が増えたので、GPUごとに異なるモデルをロードできるようにしました。
アンサンブルにより精度が向上することを狙っていますが、まだ十分に検証できていません。
試しに自己対局した強化学習のモデルを1GPUに割り当ててみましたが、弱くなりました。
今回は自己対局した強化学習のモデルは使用しないで、教師ありで学習した3種類のモデルを使用する予定です。

AWSのWindows AMIにsshで接続する

AWSWindows AMIで作成したインスタンスsshで接続する方法についてです。

使用したAMIは、「Windows_Server-2016-English-Deep-Learning-2018.03.24 (ami-4f168837)」です。

WindowsSSHサーバを構築する方法はいくつかありますが、マイクロソフトオープンソースで公開している「Win32 port of OpenSSH」を使用しました。
GitHub - PowerShell/Win32-OpenSSH: Win32 port of OpenSSH

手順は、以下の記事を参考にしました。
ASCII.jp:マイクロソフト版OpenSSHをサーバーとして動作させる
※記事にはsshdのパスに誤りがあるので要注意です。パスの誤りに気づかず数時間無駄にしてしまいました・・・

OpenSSHのダウンロード

Releases · PowerShell/Win32-OpenSSH · GitHub
から、releaseの最新版のOpenSSH-Win64.zipをダウンロードして、「C:\」に解凍します。
※現時点で最新のv0.0.24.0を使用しました。
以下、「C:\OpenSSH-Win64」に解凍した前提とします。

sshdサーバーをサービスとしてインストール

PowerShellを管理者モードで起動し、

cd C:\OpenSSH-Win64
powershell -ExecutionPolicy Bypass -File install-sshd.ps1

sshd用にファイアウオール通過のルールを設定

New-NetFirewallRule -Protocol TCP -LocalPort 22 -Direction Inbound -Action Allow -DisplayName OpenSSH -Program C:\OpenSSH-Win64\sshd.exe

参考にした記事では、「sshed.exe」になっていましたが誤りです。

ホストの認証キーを作る

.\ssh-keygen.exe -A

sshdサービスをPCの起動時に自動的に実行

Set-Service sshd -StartupType Automatic

sshd_configファイルを編集

notepad sshd_config

sshd_configをメモ帳で開いて、

#PubkeyAuthentication yes

の行頭の「#」を削除して、保存します。

ユーザーのホームフォルダ以下に.sshフォルダを作って公開鍵ファイルを置く

接続するクライアントでキーペアを作成

接続するクライアント側にもOpenSSHをダウンロードして解凍し、PowerShellを管理者モードで起動して、以下のコマンドを実行します。

cd C:\OpenSSH-Win64
.\ssh-keygen -t rsa

ユーザフォルダ(C:\Users\xxxx\.ssh\)に、「id_rsa」と「id_rsa.pub」が作成されます。

サーバ側に公開鍵を置く

クライアントで作成した「id_rsa.pub」をサーバ側の「C:\Users\xxxx\.ssh\」にコピーします。
「.ssh」はエクスプローラでは作成できないので、コマンドプロンプトで「mkdir」で事前に作成します。

「id_rsa.pub」を「authorized_keys」にリネームします。
別のクライアントの公開鍵をする場合は、「authorized_keys」に「id_rsa.pub」の内容を追記します。

authorized_keysファイルのアクセス権で変更

C:\OpenSSH-Win64\FixHostFilePermissions.ps1 -Confirm:$false

sshdサービスを再起動

restart-service sshd

接続テスト

クライアントから接続できるかテストします。

cd C:\OpenSSH-Win64
ssh <サーバのユーザ名>@<サーバのIPアドレスまたはFQDN>

以上です。

将棋AIの進捗 その20(自己対局による強化学習)

自己対局による強化学習を続けています。
現在、1サイクルあたり500万局を自己対局で生成するサイクルを17サイクル実行したところです。
教師ありでelmoで深さ8で生成した4.9億局面を事前学習したモデルを初期モデルとしています。
初期モデルは、収束前のLesserkaiには勝つがGPSfishには1度も勝てない程度のモデルです。

数サイクル回した時点では、初期モデルに対して弱くなっていましたが、17サイクル回したところで、やっと初期モデルに対して1手3秒の50回の対局で有意水準5%で強くなったことが確かめられました。
f:id:TadaoYamaoka:20180424235457p:plain:w350

しかし、GPSFishには1度も勝てていません。
1サイクルの実行にGPU3枚使って、3日かかっているので、レーティングを上げるのは気の長い作業になりそうです。

AlphaZeroの論文では、elmoのレーティングに達するのに110k stepsとなっています。
f:id:TadaoYamaoka:20180424234831p:plain

私のリソースでは、1 stepの実行に3日かかるので、1k stepsには333日、110k stepsには100年かかるため、AlphaZeroと同じレーティングの上昇傾向だと実現性がありません。
AlphaZeroと比較すると、

  • 特徴量に利き数と王手を使っていること
  • モデルサイズが小さいこと
  • 初期局面集を使っていること
  • 方策ネットワークの学習にREINFORCE Algorithmを使っていること
  • 価値ネットワークの学習にブートストラップ法を使っていること

という違いがあるので、収束が速くなっていればよいのですが、まだわかりません。

もう少し自分で検証して、間違いなくレーティングが上昇することが確かめられたらleela zeroのようにコミュニティの力を借りることを検討したいと思っています。

世界コンピュータ選手権は、今のままでは弱すぎるので、教師ありで学習したモデルを主に使うことになりそうです。
マルチGPUの1枚を強化学習したモデルにしてアンサンブルにすることも考えています。

Chainer4系がAnaconda3 4.2.0で動かない件

4/17にChainer 4.0.0がリリースされましたが、Anaconda3 4.2.0では以下のエラーがでて動かなくなっていました。

>>> import chainer
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Anaconda3\lib\site-packages\chainer\__init__.py", line 28, in <module>
    from chainer import training  # NOQA
  File "C:\Anaconda3\lib\site-packages\chainer\training\__init__.py", line 2, in <module>
    from chainer.training import extensions  # NOQA
  File "C:\Anaconda3\lib\site-packages\chainer\training\extensions\__init__.py", line 30, in <module>
    from chainer.training.extensions.variable_statistics_plot import VariableStatisticsPlot  # NOQA
  File "C:\Anaconda3\lib\site-packages\chainer\training\extensions\variable_statistics_plot.py", line 16, in <module>
    _plot_color = matplotlib.colors.to_rgba('#1f77b4')  # C0 color
AttributeError: module 'matplotlib.colors' has no attribute 'to_rgba'

原因は、chainerがmatplotlibのバージョン2系を前提にしているためです。

Anaconda3 4.2.0のmatplotlibのバージョンは、「pip freeze」で調べると、

matplotlib==1.5.3

となっていました。

回避策

とりあえずは、バージョンを指定してcupyとchainerをインストールすることで回避できます。

インストール済みのcupyとchainerをアンインストール
>pip uninstall cupy
>pip uninstall chainer 
バージョンを指定してインストール
>pip install cupy==2.4.0 --no-cache-dir
>pip install chainer==3.4.0 --no-cache-dir 

本格対処

Anacondaの最新版である5.1はmatplotが2系になっているので、Anaconda 5.1にすることが対処になります。
以前は、WindowsでPython3.6系のAnadondaを使用すると問題が起きましたが、現在は問題が解決されていました。

Anaconda3 4.2.0をアンインストール

プログラムの追加と削除から「Python 3.5.2 (Anaconda3 4.2.0 64-bit)」をアンインストールします。

Anadonda 5.1のダウンロード

Anaconda | Individual Edition
からAnadonda 5.1をダウンロードします。

Anadonda 5.1のインストール

インストールオプションのInstall for:で、「Just Me」か「All Users」を選択するところで、「Just Me」が推奨になっていますが、ディレクトリ階層が深くなるので「All Users」を選択しました(要Admin権限)。

Advanced Optionsで、「Add Anaconda to the system PATH environment variable」がデフォルトでオフになっていましたが、コマンドラインpythonコマンドを利用したいのでオンにしました。

pipをアップグレード
python -m pip install --upgrade pip
cupyインストール

以前はWindowsのPython3.6環境でcupyをインストールすると、UnicodeDecodeErrorが発生したが、pipの最新版では問題が改修されておりエラーがでなくなっていました。

>pip install cupy --no-cache-dir

インストール中に以下のエラーが出力されますが、無視しても問題ありません。

notebook 5.4.0 requires ipykernel, which is not installed.
jupyter 1.0.0 requires ipykernel, which is not installed.
jupyter-console 5.2.0 requires ipykernel, which is not installed.
ipywidgets 7.1.1 requires ipykernel>=4.5.1, which is not installed.
chainerインストール
>pip install chainer --no-cache-dir
MNISTサンプル実行

動作確認のためにMNISTサンプルを実行しました。

>git clone https://github.com/chainer/chainer.git
>cd chainer
>cd examples
>cd mnist
>python train_mnist.py -g 0

問題なく実行できました。

C:\Anaconda3\lib\site-packages\h5py\__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  from ._conv import register_converters as _register_converters
GPU: 0
# unit: 1000
# Minibatch-size: 100
# epoch: 20

epoch       main/loss   validation/main/loss  main/accuracy  validation/main/accuracy  elapsed_time
1           0.191216    0.0942012             0.941517       0.9687                    11.5416
2           0.0722713   0.0799588             0.976866       0.9756                    14.6657
3           0.0487604   0.0722168             0.984582       0.9789                    17.4512
4           0.0362529   0.0650514             0.988115       0.9813                    20.3503
5           0.0274124   0.077619              0.990649       0.9808                    23.1016
6           0.0228435   0.0733697             0.992465       0.9821                    25.9697
7           0.0226351   0.0899091             0.992865       0.9786                    28.7722
8           0.0155136   0.0836356             0.994665       0.9809                    31.6092
9           0.0160265   0.106787              0.994949       0.9754                    34.4846
10          0.0164888   0.0899379             0.994832       0.979                     37.3887
11          0.0104961   0.122631              0.996966       0.9771                    40.3375
12          0.013743    0.0798696             0.995699       0.9823                    43.1569
13          0.0114804   0.121284              0.996465       0.9773                    46.0298
14          0.0146573   0.0919883             0.995599       0.9831                    48.8832
15          0.0115368   0.100213              0.996949       0.9808                    51.6212
16          0.00518552  0.105182              0.998316       0.9822                    54.3656
17          0.0141003   0.0964787             0.995815       0.9831                    57.1719
18          0.00718431  0.101884              0.998049       0.982                     59.9831
19          0.00747319  0.103948              0.997882       0.9816                    62.7022
20          0.00940562  0.126561              0.997032       0.9809                    65.5354

1行目に警告がでますが、h5pyがNumpyの廃止予定の型を使用しているためですが、特に問題ありません。

2018/8/27追記

以下の警告は、h5pyをアップグレードすることで抑止できます。

C:\Anaconda3\lib\site-packages\h5py\__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  from ._conv import register_converters as _register_converters

h5pyは現在2.8.0がリリースされており、Anaconda 5.1のNumpyのバージョンに対応しています。

バージョン確認
>pip search h5py
h5py (2.8.0)          - Read and write HDF5 files from Python
  INSTALLED: 2.7.1
  LATEST:    2.8.0
アップグレード
>pip install -U h5py

【告知】技術書典4

4/22(日)に秋葉原で開催される技術書典4で、「ディープラーニングを使った将棋AIの作り方2~大規模学習、高速化編~」という本を出します。
場所は「き15」になります。

書籍「将棋AIで学ぶディープラーニング」の第13章の補足的な内容です。
頒布は紙の本のみです。

f:id:TadaoYamaoka:20180420000640p:plain
f:id:TadaoYamaoka:20180420000711p:plain

マイナビ出版様(い08)のところで書籍の割引販売もされるようですので、よろしければそちらもお願いいたします。