TadaoYamaokaの開発日記

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

リバーシ(オセロ)で深層強化学習

先日作成した高速なリバーシライブラリを使って、深層強化学習アルゴリズムをいろいろ試してみたいと思っている。

DQNの実装

将棋でDQNによる強化学習を試したときはまったく学習しなかったので、まずは教師ありでDQNのネットワークが学習できるか試すことにした。
DQNのネットワークは、状態(局面)が入力となり、行動(着手)ごとに行動価値を出力する。
AlphaGoのバリューネットワークのような状態価値ではなく、行動ごとの行動価値を出力するため、価値の学習の方法がAlphaGoとは少し異なる。
f:id:TadaoYamaoka:20191130150316p:plain

エピソードには、状態で取りうるどれか一つの行動しか記録されていないため、損失を計算する行動価値はどれか一つになる。
Pytorchのチュートリアルでは、gatherを使って出力をどれか一つのノードにして損失を計算している。これと同じ方法で実装することにする。

リバーシの場合、行動価値は盤の座標対応する64ノードに対応させる(中央の4マスは実際には着手できないが64とした方が処理の都合がよい)。

入力は、黒と白に対応する2値画像2枚で表す。

ネットワーク構成

3×3フィルタ128の5層のCNNとした。
AlphaGoと同様にパディングを行い、各層で画像サイズが変わらないようにする。
出力層はAlphaGoの方策ネットワークと同様に1×1の畳み込みに位置ごとに異なるバイアスとした。
(ソースはこちら

教師あり学習

DQN強化学習でエピソードを作成するが、ここでは強化学習を行わず棋譜データをエピソードとして学習できるか確認を行った。
DQNではQ学習を使用するが、ここではQ学習は行わず、エピソードの終端の報酬を使用して学習を行う。

リバーシ棋譜

GGSから大量の棋譜がダウンロードできる。
棋譜を処理するため、creversiにGGSの棋譜を読み込む機能を実装した。

GGSからダウンロードした棋譜をレーティング2000以上、手数45以上でフィルタリングして、9,831,855局面の学習データを作成した。
(処理に使用したコードはこちら

学習結果

学習データをすべてリプレイバッファに格納し、ミニバッチ256をランダムにサンプリングして、10万イテレーションの学習を行った。
サンプリング時に1/2の確率で局面を180度回転する処理も行っている。
f:id:TadaoYamaoka:20191130154808p:plain

20,000イテレーション(グラフのx軸200)あたりからlossが横ばいで、学習しているように見えない。
しかし、将棋AIでも価値の学習は、lossが横ばいになる傾向があるので、学習できているかもしれない。

ランダムプレイヤーと対局

lossだけでは学習できているか分からないので、ランダムプレイヤーと対局させてみた。
ランダムプレイヤーは、合法手から一様ランダムに手を選択して、着手する。

学習したモデルを使用するプレイヤーは、局面から行動価値を予測し、最大の行動価値の行動を選択する(グリーディー戦略)。
モデルの出力には、盤の座標に対応する64のノードがあるため、合法手に絞る必要がある。
そのため、gatherを使用して、合法手に対応するインデックスのみ出力するようにした。

ランダムプレイヤーと1000局対局した結果、680勝280敗40分となった。
信頼区間95%の勝率は73.6%~67.9%で、有意にランダムプレイヤーに勝ち越している。

ランダムに対する勝率としては低いように思うが、リバーシでもDQNのネットワークが学習できることが確かめられた。
これで、DQN強化学習した場合にネットワーク構成が原因で学習できないということはないだろう。

なお、ソフトマックス戦略にした場合、温度0.1でも532勝424敗44分となり、勝率がかなり落ちた。

学習時間

10万イテレーションの学習には、GeForce2080Tiを使用して12時間かかった。

ネットワークサイズを変えて実験

リバーシでは、着手による駒の反転は盤の端から端まで影響するので、直感的には層数が多い方がよさそうなので、層数を10層、フィルタを192にして、1万イテレーション学習してみた。
(ソースはこちら

ランダムプレイヤーとの1000局対局した結果、766勝196敗38分となった。
少ないイテレーションで、5層CNNよりも良い結果になった。
リバーシを学習するには、ある程度のネットワークサイズが必要そうだ。


次は、教師ありでTD学習(Q学習)を試してみたい。