将棋を「ディープラーニング」してみた

注)ディープラーニングを何も知らない人が適当に書いています。

2018年5月に行われた「第28回世界コンピュータ将棋選手権」にて発表された
新学習モデルである「NNUE型」を学習してみた感想です。

NNUE型開発者の詳しいモデル説明はコチラ

ディープラーニングとは


人間の「脳」を模倣したニューラルネットワーク(略称NN)の層を、
何階層でも深くできることからディープラーニング(深層学習)と言われるようです。

※狭義的に入力層、中間層、出力層が4層以上の多層のニューラルネットワーク

新学習モデルである「NNUE型」は
入力層(教師局面)
中間層が2層
出力層(評価値)
といった(たぶん)4層構造なので分類的にディープラーニングとなります。

ハイパーパラメータとは


人間が機械学習時、人為的に設定する数値であり、学習効率や正解率に影響するため
googleのような企業は「ハイパーパラメータ職人」みたいな社員が高給で雇われているようです。

NNUE型の学習


まずは本家である「tanuki-」チームが実際に学習した
ハイパーパラメータの個人的感想。
( 「tanuki-」チーム代表者のツイッターから引用)
教師データは
やねうら王+Apery SDT5評価関数ファイル+Apery教師データ生成ルーチンを独自実装したものを用い、depth 8で50億生成
targetdir (教師局面フォルダパス)
loop 100
batchsize 1000000
lambda 1.0
eta 1.0
newbob_decay 0.5
eval_save_interval 500000000
loss_output_interval 1000000
mirror_percentage 50
validation_set_file_name (検証データファイルパス)
nn_batch_size 1000
eval_limit 32000

上記のあと
lambda 0.5
eta 0.1
eval_save_interval 100000000
として、同じ学習データを用いて追加学習

           
1)入力層の「nn_batch_size 1000」が少ない

「将棋の学習としては」という意味で、
例えば1局100手数を学習するのに「1000」だと10局相当です。
レーティング評価で10局で強かった。なんて言えば総ツッコミ不回避でしょう。
そういった統計的にマズイ量を勾配計算に使うことは良くないと考えます。


2)「nn_batch_size 1000」に対して「eta」が大きすぎる

たぶん追加学習の
lambda 0.5
eta 0.1
だと「eval_save_interval」回数が少なく、
「newbob_decay」の適用回数が少ない場合は、
勾配が満足に下れずにすさまじい評価値になる。


正直なところ、よくこんなハイパーパラメータで収束出来たなって感想でした。
これは悪い意味ではなく、
機械学習は未知の所から(ゼロから)学習出来る学習モデルであることが良いので、
そういった意味で「大成功」だと考えている。
(機械学習モデルとして正しく実装出来ている)

NNUE型の学習案


NNUE型のハイパーパラメータを模索する
と言ってもこれは簡単です。

なぜなら将棋ソフトは「USIプロトコル」によって
歩1枚の価値を100とした評価値を出力しましょうって、
明確に基準が決まっているから。

※歩1枚の価値を100とした評価値基準で高い勝率というゴールを目指せば良いだけ

「nn_batch_size」は
KPPT型をゼロから学習した人は当たり前の感覚でしょうけど、
60万以上です。

「tttak」さんが追加学習に成功していますが、
「nn_batch_sizeが100万」ですね。

ただし、nn_batch_sizeを100万とかで学習してみると
パソコンの物理メモリがとんでもない大きさで学習出来ないと思います。
(個人で学習出来る人はすごすぎる。AWSとかじゃないと無理っぽい)


では本家「tanuki-」チームが「1000」で学習出来た理由を考えてみます。

NNは鞍点にバカみたいにハマるそうです。
なので「nn_batch_size」を大きくしようが、
たいして上手に勾配が出せない仕様らしい。
だから統計の力で良勾配を出そうとしたのだと思う。

batchsize / nn_batch_size として、
1000000 / 1000 = 1000
というN個数の統計の力を利用したのだと考えます。

であれば、
「nn_batch_size」=1000
これを1000倍した
「batchsize」=100万
これを1000倍した
「教師局面数」=10億
といった学習式となります。

そして、機械学習の基本構造である
学習進度による学習率の降下を
「eval_save_interval」毎に
「newbob_decay」を乗算するかどうか見ている実装だと思います。


従来学習モデルである
KPPT型「やねうら王学習部」の場合では、
「batchsize」=100万からスタートして
これを1000倍した
「eval_save_interval」=10億
といったN個数の統計の力を利用しています。

そして、AdaGradを使って
学習がサチったときには過去勾配の二乗和の平方根で、
学習をさらに進めて収束しようといった実装だと思います。



上記よりNNUE型のハイパーパラメータ案は、

1)USIプロトコル基準により、そのものズバリを当てれるので、
 不安定要素である「validation_set_file_name」は使わない。
(教師局面のレートが上がったり、定跡等を使用することで問題は無くなってくると思われる)

2)「validation_set_file_name」(検証データ)を使わないので、
 「newbob_decay」も使わない。

3)「nn_batch_size」を100局相当になる「10000」で妥協する。

よって、
100局分である
「nn_batch_size」=1万
これを100倍した
「batchsize」=100万
これを100倍した
「教師局面数」=1億
といった学習式を提案します。

これにより
4)etaは0.1となります
 etaの目安 = 10 /(batchsize / nn_batch_size)

※loopさせる場合は教師局面の増加=更新頻度の増加
 となるため、適切にetaを割引する必要がある

追加学習してみた結果


提案したハイパーパラメータが適切かどうか確認する意味で、
本家T.N.K.wcsc28をtttak氏が追加学習した
超人的棋力を持つ「nn20180519」を使用。

evaldir nn20180519
nn_batch_size 10000
batchsize 1000000
eta 0.1
eval_save_interval 100000000


学習した印象では3,4周(loop)行けそうな感じでしたが、
今回は提案したハイパーパラメータが適切かどうかの確認が目的なので、
depth8教師局面を1億だけ追加学習としています。
(ハイパーパラメータがおかしい場合はすごく弱くなるはず)

最大のメリットは「教師局面が1億」で学習出来る点です。
loopさせるならdepth10や12の精度からで良いかな。


実際に学習してみた評価関数です。

 ▶NNUE型評価関数nn20180608


この記事へのコメント

スポンサーリンク