DeepLearningによる将棋の学習12~7ブロック化~

 前回はResidualBlockを6個に増やしたら性能が上がることを確認しました。

 ならばと今回は7個にして実験してみました。結果は次の通りです。

Epoch Total Loss Policy Loss Value Loss Policy Accuracy Value Accuracy
1 3.6059 3.4564 0.5978 0.2957 0.6376
2 3.1807 3.0401 0.5622 0.3370 0.6677
3 3.0033 2.8649 0.5535 0.3581 0.6759
4 2.8979 2.7613 0.5465 0.3694 0.6809
5 2.8407 2.7050 0.5426 0.3766 0.6856
6 2.8037 2.6686 0.5403 0.3814 0.6893
7 2.7849 2.6495 0.5417 0.3831 0.6886
8 2.7692 2.6336 0.5426 0.3866 0.6889
9 2.7701 2.6347 0.5416 0.3868 0.6898
10 2.7635 2.6285 0.5400 0.3873 0.6925
11 2.7778 2.6427 0.5405 0.3889 0.6914
12 2.7783 2.6424 0.5439 0.3892 0.6895
13 2.7879 2.6518 0.5444 0.3898 0.6908

f:id:tokumini:20180502102246p:plain

 Policyの性能は下がってしまいました。これまでの結果を表にまとめるとこうなります。

ブロック数 Total Loss Policy Loss Value Loss Policy Accuracy Value Accuracy
5 2.4231 2.2876 0.5421 0.3957 0.6874
6 2.3999 2.2634 0.5458 0.4013 0.6883
7 2.7635 2.6285 0.5400 0.3873 0.6925

 Valueは良くなっているようにも見え、またPolicyの一致率はまだ上がりそうであることを考えると、損失比をいじることでまだ改善はできるかもしれません。ブロック数を変えると最適な損失比も変わるとなると実験が大変ですが……。そこまでこだわる精度の差でもない気はするので、選手権後はもっと大きな改善に取り組みたいと思います。

 NN版はリモートで動かせない環境だと思っていたのですが、試行錯誤していると動くようになったので選手権にも合議として参加させる可能性が高くなってきました。ルールの確認等をして問題がなさそうならば線形評価関数版の海底とNN版との楽観合議で参加したいと思います。

DeepLearningによる将棋の学習11~6ブロック化と対局結果~

 前回は現状で最も良いと考えられるモデルで学習させてみました。

 今回はResidualBlockを一つ増やして6個として実験してみました。

f:id:tokumini:20180501110203p:plain

Epoch Total Loss Policy Loss Value Loss Policy Accuracy Value Accuracy
1 3.1680 3.0230 0.5797 0.3130 0.6512
2 2.7987 2.6588 0.5595 0.3539 0.6681
3 2.6395 2.5019 0.5506 0.3677 0.6759
4 2.5260 2.3894 0.5464 0.3832 0.6814
5 2.4690 2.3340 0.5400 0.3911 0.6868
6 2.4389 2.3043 0.5384 0.3939 0.6881
7 2.4099 2.2750 0.5397 0.3983 0.6903
8 2.4086 2.2732 0.5418 0.3995 0.6887
9 2.3999 2.2634 0.5458 0.4013 0.6883
10 2.4045 2.2693 0.5407 0.4032 0.6883
11 2.4163 2.2765 0.5590 0.4033 0.6850
12 2.4187 2.2826 0.5441 0.4025 0.6902

 結果は指し手一致率が40%を超え、良い性能を持つと考えられます。

 ここで海底の最新版(WCSC28へ出すもの:レート1100ほど?)と100局対局させてみました。海底側は1手5秒、NN側は8スレッドで10000回のプレイアウト(という言い方が適切なのかわかりませんが)となっています。この条件だとおおむねNN側も5秒から多くとも7秒ほどで着手するため、それなりに平等な条件となっていると考えられます。

 結果はNN側から見て34勝 2引き分け 64敗でした。引き分けを0.5勝0.5敗と考えてELOレート差を計算すると107.5となりました。思ったより強いという印象を持っています。

 しかし実は純粋にNNだけを利用しているのではなく、Valueを計算している時間を利用して海底が持っている評価関数で静止探索を行いそれらの平均値をValueとしているので、これが多少強くなっている一因なのではないかと感じます。そもそもモンテカルロ木探索自体を線形評価関数に適用してもそれほど悪くないのではと思っており、実験してみたいところです。

DeepLearningによる将棋の学習10~現状の最高性能~

 前回は損失の比を調整することでPolicyの損失曲線とValueの損失曲線がだいたい同じタイミングで底を打つようにできるのではないかということを実験しました。

 今回はそれを踏まえて現状での最高性能を出す条件で実験してみました。

 ResidualBlock5つ、フィルタ数192、フィルタサイズ3、バッチサイズ128で、損失比はPolicy:Value = 1: 0.25、optimizerはNesterovとしました。結果は以下の様になります。

Epoch Total Loss Policy Loss Value Loss Policy Accuracy Value Accuracy
1 3.2068 3.0597 0.5885 0.3082 0.6442
2 2.8337 2.6939 0.5595 0.3465 0.6683
3 2.6670 2.5285 0.5538 0.3637 0.6728
4 2.5773 2.4384 0.5555 0.3755 0.6759
5 2.5006 2.3640 0.5463 0.3846 0.6810
6 2.4791 2.3428 0.5451 0.3869 0.6830
7 2.4457 2.3097 0.5443 0.3912 0.6827
8 2.4357 2.2999 0.5434 0.3948 0.6849
9 2.4231 2.2876 0.5421 0.3957 0.6874
10 2.4307 2.2953 0.5418 0.3977 0.6872
11 2.4323 2.2964 0.5436 0.3984 0.6856
12 2.4357 2.2991 0.5466 0.3971 0.6862

f:id:tokumini:20180429100859p:plain

 Policyの損失が最小になったタイミングとValueの損失が最小になったタイミングに1エポックしかズレがなく、そこそこ良い学習になっているのではないでしょうか。性能としてもPolicyの一致率39.57%はこれまでにない高い確率となっています。SGDからNesterovへ変更した恩恵も大きそうです。

 ちなみに本家dlshogiはWCSC28のアピール文書にあるデータと比較すると(使用データがfloodgateではなくelmoで生成した自己対局データのようですが)

Model Policy Accuracy Value Accuracy
dlshogi 45.6% 78.1%
今回の実験結果 39.6% 68.7%

 とのことで、やはり精度は段違いのように思えます。

 今回の実験で得たモデルを既存の海底最新版と対局させてみたところ、中盤まではかなり良い勝負をする、優位を築くことさえあるとわかりました。しかし、やはり最終盤での詰みが関わってくる局面で弱さを見せ、なかなか勝ち切るには至りませんでした。理想的にはニューラルネットワークの質を高めて終盤にも対応できるようにするのが良いのでしょうが、現実的にはWCSC28のアピール文書でいくらかのチームが提示していたように、終盤では使うエンジンを切り替えるなどの工夫をしていくのが良いのかもしれません。まぁ僕は今回のWCSC28でDeepLearningを使用したエンジンを使う気はないのですが……。

WCSC28・各チームアピール文書一言メモ

elmo

 文字化けしていて読めなかった(・ω・)

 ダウンロードしたら読めた。定跡を「自己対局→勝敗+評価値を利用して評価」によってうまく作るというのは面白そうな考えですね。ライブラリを複数組み合わせいくのはやはり公開されていることの良さを上手く活かしていると思うので、elmoには強くあって欲しいなぁ~とか勝手に思っているんですが、今年はどうなるでしょう。

大合神クジラちゃん2

 あまりよくわかってないけど、末端ノードだけではなく全てのノードで探索というのは面白そう。計算パワーを上手く活かすのも技術が必要なことで、これはまぁすごいことだなぁと思う。

the end of genesis T.N.K.evolution turbo type D

 ニューラルネットワークの評価関数を差分計算できるようにしてCPUで1局面ごと評価するらしい。いやしかしそれ以上の詳細がさっぱり理解できないぞ。メモリレイアウトをものすごく気にしているようで、それが大きく効いてくるのか。整数SIMD演算もゴリゴリ使ってとんでもない実装になっていそう。

 しかしNN自体の大きさはそれほどでもないほか。入力特徴の時点でKPを使っているので深い、大きい必要はそれほどないのか。

 実際どの程度強いんでしょうね。これは楽しみだ。

読み太

 ついにノートパソコン脱却ということでこれはかなり期待できるのでは。KPPT型の評価関数、depth8で200億局面䛾教師局面を作成(!)、現時点でWCSC27のelmoに勝率75%程度っていうのやはり強い。

 技巧の並列化を参考に疎結合並列化をしているとのこと。この辺さっぱり知識がなくてわからない。

 Byteboardは指し手生成には使わない?

 塚本さん卒業したのか。おめでとうございます(?)

 Linuxでの開発、僕もちょっと移行したいかなーとか思っているのでできれば聞いてみたいな。

HoneyWaffle

 いつ見ても美味しそうなワッフル。うちで焼いたのっていうの、すごいですね。

 「本題に入る前にポエム」という部分が非常に良い考察だと思う。単に飛車を6筋に置く将棋というところにとどまらず、振り飛車党らしい将棋がソフトによって指されたら面白いなぁ。やはり注目のソフトです。

NineDayFever

 今更ですがC言語での開発なんですか。ひゃーって感じですね。使用ライブラリもBonanzaということで、古参としての風格たっぷりですね。

大将軍

 4駒関係は見送っている模様。やはり難しいんですかね。「学習作業の効率を考慮して」とのことなので単純な強さだけの問題でもなさろうなのかな?

 探索部はやねうら王ということで、まぁやはりそうだよなぁ。優秀だよなぁとは思う。

妖怪惑星Qhapaq

 教師データについて量より質を重視しているというイメージ。数理強い人と高速化強い人となんか強そうな人が融合したらそりゃ強いのでは。

 再放送の方が結構攻めた内容になっている。elmo絞りのここがダメで「ニューラルネット系の学習だと超強力」っていうのはなんだろう。AlphaZeroのことかな。

nozomi

 ビッグウェーブに乗る! → 乗りませんでしたー というお約束。1回のパラメータ更新に2000万局面ですか。なるほど。

 指し手の選択確率を利用してオーダリング。これは結構ありな方針だと思うんですよね。35%の確率で、ってなかなかなんじゃないかとか思ってしまうんですが、そんなになんですかね。

Apery

 探索深さ10での生成、学習をやっているとのこと。単純に計算量を増やすことでどうにかなるかもしれないという仮説はまぁそういうこともありえるのかなという気はする。探索はどうなんだろう?

なのは

 リリカルなのは、全然知らないんですよね。

 Bitboard不使用でも実際そんなに性能差はないのかな? どこにでもあるような平凡な構成とか謙遜しているけど詰み探索があるのは面白い点だと思う。ただやっぱり棋力に繋げるとすると単なる詰みかどうかだけでなく詰めろ等々を含まないとダメなんだろうなぁとは。

おから饅頭

 そういえば毎年変化点を作る必要はないのかな。

GPS将棋

 利きを管理する高速な将棋盤、実現確率を用いた探索辺りがちょっと気になりますね。詰め探索もしっかり入っているということで、隙がなさそう。

スーパーうさぴょん2

 AMD勢での争い。なのはminiを改善していくということだけど、やっぱりStockFish探索から改善するのは難しいですよね……。定跡部もなんか作り込んでいるっぽい?Aperyの評価関数を使うということでやっぱり強そう。

習甦

 tanuki-のアピール文書内でも触れられていたけど、非線形な評価関数を用いている。駒の働きを入玉度合いで判断するの面白い。評価パラメータの学習方法がちょっとよくわからないけどどうなんだろう。

たこっと

 評価バイナリとしてAperyがやっぱり人気ですね。オンラインの強化学習をやっているのかな? 気になるところ。

CGP

 フルスクラッチ勢。非ビットボードで高NPSを目指しつつ、定跡データとか局面と評価値のセットなどは使用していないというこだわり。利きを保持したり演算途中のデータを保持することで高速化。なるほど。KPPT型だけど学習は不十分。オーダリングでSIMD使うの良さそう。

柿木将棋

 1985年ごろから開発ってすごいなぁ。「今年は昨年と殆ど変わりません」で前年のアピール文書が続くの笑ってしまった。

 Bitboardと利きデータは排反なものなんだろうか。まぁ冗長っちゃ冗長ではあるなぁ。

ひまわり

 方策勾配を用いた教師あり学習+強化学習。方策勾配法気になるけどどんな感じなんだろうなー。

芝浦将棋Softmax

 プレイアウトをしないモンテカルロ木探索との違いがいまいちよくわかっていない。まぁかなり似たものではあるのかな。アピール文書中でもMCSoftmaxとか言われてるしなぁ。いやしかし普通の評価関数でも有効ならこれは結構すごいことだと思う。

まったりゆうちゃん

 古参勢。去年は最終局で僕が負けて予選抜けしたんでしたよね。リベンジする機会が得られるかどうか。フルスクラッチなのはやっぱりすごいことだとは思う。

名人コブラ

 徹底的にキメラ化に拘るというコンセプトはなかなか良さそう。いろいろな条件で学習させて評価関数作ったりそれを上手く混ぜ合わせたりすると既存のものより強くなるっていうのは結構奇妙な現象にも思えるので何か解明されるといいな。

カツ丼将棋

 将棋連盟のページを真似た自己紹介ページ良いですね。簡易的な4駒と多少の手調整ということで結構面白いソフトに仕上がっている感じ。24での自動対局システムなど貢献は大きいです。僕のソフトもお世話になりありがたい限り……。

Novice

 横型RotatedBitboardか。StockFishを改善できた(?)なら強いなぁ。Aperyをそのまま使うということで評価関数の差が出ないと良いけど、まぁ強化に成功しているチームもそんなになさそうだから結構強いのでは。

 人生の悩みを描くアピール文書。

きのあ将棋

 1手ごとに思考エンジンの実行するっていうのは相当珍しいですね。汎用的なプログラムに仕上がっていると良いなぁ。

 加算連結とか乗算連結はよくわからない。評価パラメータにノイズを加えるのとかも? ちょっとこれは聞いてみたいな。

Claire

 Rustでの開発、利きのみを利用した評価関数って辺りが面白い。利きのみの評価ってどこまで情報を復元できるんだろうか。なかなか興味深い。

SilverBullet

 対局途中で使用する思考エンジンを変更していくのも面白い考え方だなぁ。特にDeepを使った評価関数は序盤は強いけど……という感じになりがちという印象があるのでそこで終盤に強いエンジンに切り替えられたら良さそう。そのエンジンも終盤に特化させたりはできるんだろうか。

こまあそび

 手製でチューニングした評価関数。まぁなんだかんだでそれでもそこそこ強くなるとは思う。

臥龍

 第3回から参加しているってとんでもないですね。すごい。使用言語がJavaで、評価パラメータはちょっと少ない感じですか。「前回からの改良 全く変更なし。」が潔い。

dainomaruDNNc

 dlshogiをRMSPropで強化学習。

山田将棋

 手調整の評価関数。8近傍をいろいろやるっていうのあまりやってないんだけどやった方がいいのかなぁ。簡易必至判定とかも面白そう。

隠岐

 将棋ソフトを作るプログラムを作っているということですか。昔のソフトとは大きく作りが違うんだろうなぁとは思う。

オッズの魔法使い

 線形の評価関数を用いてモンテカルロ木探索。プレイアウトではなくある程度で打ち切りと。これ案外強くなったりしないのかな。探索は不思議なことが多い。

Anicca

 RustからGoへ変更。今年も参加してくれるのは良いですね。あれ、評価関数は手調整になるんですか。

なり金将棋

 強化学習と遺伝的アルゴリズムの融合? 面白そう。遺伝的アルゴリズムなんか可能性ないのかなーとは結構思っているんだけど。

手抜き

 おーD言語。以前には確かD言語で参加していた人もいたような気がするけど、まぁ今は少なくなっているのかな。いろいろな実験結果が載っていて面白い。置換表めっちゃ効いてるなー。

きふわらべ

 なんもわからん。天才。

十六式いろは改

 フルスクラッチ勢。Luaという謎の言語での開発。評価値を探索に活かせていないという天才性。すごい。

762alpha

 ん、なんだか面白いそうなことをやっている気がするのだけど理解できない。しかしこういう工夫を重ねていかないとダメだよなぁとは思うのであとでしっかり読もう。

YSS Zero

 DeepLearning使用。ばっちりAlphaZeroを真似した感じで期待大ですね。

TMOQ

 特大もっきゅという名前可愛くていいですよね。CUDAを使って書いているのは何か良い点があるのだろうか。Deepやっているのかな?

悲劇的 with Zero

 Bonanzaをベースとして改造をした感じか。利きを使っているらしく、飛・角・香を別に保持しているのは面白そう。利きを上手く更新できるならやっぱり利きを持ちたいとは思う。

人生送りバント失敗

 オンライン学習やりたいよなー。俺もなー。

 昔話が面白い。

 「うまるちゃんになりたい人がいればお貸しすることは可能です」誰か。

broaden

 DeepLearning使用。なぜかCaffeが人気っぽい?(速いらしいというのはちょっと聞いたことあるかも)。Conv3層で全結合5層。floodgateの3年分を指し手と勝ち負けのみ使用。これでも一致率とかは結構行くのかな。ぜひ聞いてみたい。

GA将!!!!!!!!!

 自己対局のみからの学習。歴史があって信用できそう。GAとかTDleafとかいろいろ試しているとのころ。PDLeafがまだよくわかってないんだけど、まぁできれば聞いてみよう。

ツツカナ

 指し手を読む深さを機械学習によって決定しているという部分が

 Kindergarten Bitboardsってなんだろう。

ichibinichi

 フルスクラッチ勢。Javaを使っているチームがそこそこある気がする。

W@ndre

 角頭歩戦法ガチ勢。この戦法全くよくわかってないんですけどプロでも指されていたんでネタではないっぽいんですよね。阪田流向飛車もやるということでできればそっちも見てみたい。

 指させたいものを定跡としてそこから学習させるとうまく指してくれる。序盤はdlshogiでそのあとはやねうら王。これはSilverBulletと同じアイデアかな。強そう。

Crazy Shogi

 フルスクラッチ勢。AlphaZeroを実装したとのこと。これはCuDNNを直書きしたということ? 話しかけることは多分僕には不可能なので話を聞くのはできないだろうけど……。

S.S.E.

 フルスクラッチ勢。評価関数はelmoを利用。上手くいけばDeepを利用する。

ねね将棋

 DeepLearning使用。やねうら王を使って教師データを生成し、それを教師あり学習。pythonを実践でも用いるということかな。ちょっと速度が心配な気もするけど、どう実装しているんだろう。

ArgoCorse_IcSyo

 モンテカルロ木探索は上手くやれば将棋でもなんとかなるのでは? とか思ってしまうんですがならないもんなのか。

 なぜかりゅうおうのおしごと! の感想があり笑った。

SMS将棋

 れさぴょんを使っているチームは珍しい気がする。序盤は広く、終盤は深い探索をしているとのことだけれど、それはどうなんだろうか 評価関数は手調整。

Girigiri

 C++からRustに変更とのこと。3駒関係を機械学習させたなら結構強いのでは。1勝どころではなさそう。

dlshogi

 DeepLearning使用。自己対局による強化学習をしているとのことで。まぁだいたいブログを見ていると進捗のほどはわかるけど、結構強そう。

 ドメイン知識を入力に入れた方がいいというのはそんなんだろうな。

 ドメイン知識を利用するということでAlphaZeroよりもAlphaGoの方に近いということなのかな? REINFORCEアルゴリズム使っていたとは知らなかった。

 Policy Network の一致率:45.6%  Value Network の一致率:78.1%

 はすごいなぁ。floodgate2016年のものだけだと全然そんなにいかない。

 自己対局の強化学習ではまだ有意に強くなってはいないということで、大変ですね。

PAL

 DeepLearning不使用(!)。0ベースから強化学習と敵対的学習のハイブリッド。なんだかよくわからないけどすごそうだぞ。

Windfall

 DeepLearning使用。努力がとんでもない方向に向かっていませんか? しかしすごい。

Hefeweizen

 48さんなどが参加されているクソ強そうなチーム。結局何をやるんだかさっぱりわからんけどまぁ強いんだろう。

Yorkies

 通信部がすごそう。

こい将棋

 フルスクラッチ勢。標準的な構成っぽいけど強そうだぞ。

あとがき

 これで全部見たかな。一番の注目株はやっぱりthe end of genesis T.N.K.evolution turbo type Dですかね。内容をちゃんと理解はできてないけど今後流行るのかなぁ。

 あとはDeepLearning勢がどうなるか。dlshogiが一番強いのかな?

 ライブラリを上手く使っているチームは工夫次第で一気に強くなる可能性があると思うのでそれらにも注目ですね。

 あまり開発に時間割けてないけど楽しみだー。

DeepLearningによる将棋の学習9~損失比の再検討~

 前回の実験ではResidualBlockの実装にミスがあったことがわかりました。Valueの出力を3つ目のブロックから取る実験をしてそのままにしていて、前回の実験は無意味でした。

 今回はそれを修正して一番基本的な実装に戻し、一番気になるのが損失の比をいじる部分だったのでそれを変更して実験しなおしました。

 結果はPolicy:Valueの比が

 1:1の場合 f:id:tokumini:20180427101946p:plain

 1:0.5の場合 f:id:tokumini:20180427101959p:plain

 1:0.1の場合 f:id:tokumini:20180427102008p:plain

 やはり多少Valueの損失を小さく扱ったほうが曲線のピークが一致するようで良く見えます。損失が最小になった瞬間を比較してもValueの性能をそこまで落とさずにPolicyの性能を上げられているようでうs。

損失比 Policy Loss Value Loss Move Accuracy Value Accuracy
1:1 2.4987 0.6193 0.3673 0.6774
1:0.5 2.4348 0.5650 0.3773 0.6831
1:0.1 2.4149 0.5591 0.3811 0.6717

 詳細なデータ

 1:1

Epoch Total Loss Policy Loss Value Loss Move Accuracy Value Accuracy
1 4.0093 3.4192 0.5901 0.2738 0.6449
2 3.5516 2.9888 0.5629 0.3127 0.6689
3 3.3704 2.7949 0.5755 0.3321 0.6655
4 3.2515 2.6918 0.5597 0.3428 0.6779
5 3.1720 2.6084 0.5636 0.3538 0.6798
6 3.1440 2.5726 0.5714 0.3576 0.6824
7 3.1315 2.5363 0.5953 0.3633 0.6774
8 3.1277 2.5212 0.6065 0.3654 0.6779
9 3.1180 2.4987 0.6193 0.3673 0.6774
10 3.1503 2.4924 0.6578 0.3698 0.6736
11 3.1420 2.4766 0.6654 0.3720 0.6765
12 3.1590 2.4686 0.6904 0.3721 0.6746

 1:0.5

Epoch Total Loss Policy Loss Value Loss Move Accuracy Value Accuracy
1 3.6982 3.3983 0.5999 0.2741 0.6397
2 3.2568 2.9709 0.5716 0.3142 0.6596
3 3.0546 2.7779 0.5535 0.3350 0.6728
4 2.9499 2.6735 0.5528 0.3451 0.6742
5 2.8712 2.5978 0.5468 0.3536 0.6807
6 2.8096 2.5365 0.5462 0.3635 0.6818
7 2.7826 2.5069 0.5515 0.3644 0.6833
8 2.7552 2.4790 0.5526 0.3698 0.6844
9 2.7467 2.4604 0.5725 0.3718 0.6782
10 2.7294 2.4454 0.5681 0.3757 0.6813
11 2.7264 2.4425 0.5678 0.3746 0.6838
12 2.7173 2.4348 0.5650 0.3773 0.6831
13 2.7304 2.4404 0.5801 0.3780 0.6829
14 2.7273 2.4328 0.5888 0.3778 0.6795
15 2.7317 2.4332 0.5970 0.3782 0.6814

 1:0.1

Epoch Total Loss Policy Loss Value Loss Move Accuracy Value Accuracy
1 3.4702 3.4077 0.6256 0.2763 0.6181
2 3.0286 2.9682 0.6044 0.3159 0.6357
3 2.8417 2.7829 0.5886 0.3331 0.6467
4 2.7277 2.6681 0.5958 0.3476 0.6436
5 2.6520 2.5945 0.5749 0.3558 0.6590
6 2.5996 2.5420 0.5767 0.3632 0.6575
7 2.5550 2.4981 0.5683 0.3667 0.6630
8 2.5143 2.4573 0.5703 0.3718 0.6633
9 2.5021 2.4458 0.5627 0.3735 0.6682
10 2.4859 2.4295 0.5639 0.3763 0.6677
11 2.4771 2.4208 0.5628 0.3771 0.6706
12 2.4744 2.4187 0.5572 0.3778 0.6726
13 2.4726 2.4167 0.5589 0.3793 0.6717
14 2.4708 2.4149 0.5591 0.3811 0.6717
15 2.4758 2.4202 0.5559 0.3804 0.6743
16 2.4726 2.4171 0.5554 0.3828 0.6748
17 2.4789 2.4233 0.5563 0.3819 0.6732

DeepLearningによる将棋の学習8~元のモデル~

 前回はフィルタ数を変更して実験をしてみました。

 今回はいろんな実験をしすぎて情報が取っ散らかってきたように思えるのでここらで一度標準的なものを再実験してみることにしました。

 ResidualBlock5つ、フィルタ数192、optimizerはSGD、patienceは10、損失の比は1:0.1、バッチサイズは256での実験です。

Epoch Total Loss Policy Loss Value Loss Move Accuracy Value Accuracy
1 3.6851 3.6216 0.6356 0.2560 0.6093
2 3.1959 3.1348 0.6113 0.2961 0.6300
3 2.9791 2.9188 0.6023 0.3167 0.6368
4 2.8631 2.8040 0.5909 0.3305 0.6466
5 2.7799 2.7218 0.5808 0.3386 0.6529
6 2.7272 2.6693 0.5789 0.3459 0.6553
7 2.6715 2.6144 0.5709 0.3515 0.6621
8 2.6428 2.5854 0.5744 0.3550 0.6591
9 2.6117 2.5546 0.5711 0.3588 0.6622
10 2.5974 2.5408 0.5668 0.3607 0.6651
11 2.5806 2.5243 0.5625 0.3628 0.6691
12 2.5684 2.5122 0.5620 0.3637 0.6688
13 2.5526 2.4967 0.5589 0.3675 0.6706
14 2.5516 2.4957 0.5589 0.3669 0.6712
15 2.5524 2.4965 0.5590 0.3689 0.6710
16 2.5471 2.4910 0.5612 0.3682 0.6693
17 2.5485 2.4926 0.5587 0.3691 0.6727
18 2.5504 2.4949 0.5548 0.3679 0.6752
19 2.5531 2.4974 0.5568 0.3681 0.6729
20 2.5573 2.5017 0.5550 0.3689 0.6741
21 2.5650 2.5095 0.5557 0.3697 0.6737
22 2.5775 2.5218 0.5566 0.3676 0.6734
23 2.5813 2.5259 0.5543 0.3694 0.6755
24 2.5850 2.5295 0.5548 0.3689 0.6762
25 2.5995 2.5441 0.5534 0.3671 0.6765
26 2.6024 2.5469 0.5556 0.3689 0.6748

f:id:tokumini:20180425131349p:plain

 思ったよりも精度が出ませんでした。指し手を検証してみても初期局面で▲1八香、▲9八香などが高い確率で示されていてあまり上手くいっているようには見えません。損失の比をいじると見た目の数字だけ改善されている可能性があります。

 損失の減少具合と指し手の自然さがあまり一致しない場合、学習の進行度合いを確認する指標がなくなり、苦しい事態となるのですが……。

 確認できることとして、patienceは相当小さくても良いのではないかということがあります。そもそもテストデータに対する損失で学習終了を決定して良いのかという疑問はありますが、これを正しいとすると、一度損失が増加し始めると改善されることはないような結果が今のところ得られています。

 収束まで16エポックかかっていることも気になります。特に変な実験条件ではないはずなので、こんなにかかる原因がよくわかりません。今回からバッチサイズを倍にしていることが効いているのでしょうか。時間がかかるわりに性能がよくなっているということがあればいいのですが、あまりその傾向はみられないようにも思えます。

 5ブロックではNesterovが良いということもあるのかもしれません。ブロック数によって最適なoptimizerが異なると膨大な実験が必要になってしまうようにも思えるのですが……。

 一度性能まとめ記事を作らないと自分でもなにをやっているのか少しわからなくなってきています。うまく実験をデザインしていきたいです。

DeepLearningによる将棋の学習7~フィルタ数の変更~

 フィルタ数を256にして実験してみました。

 損失の比が1:1の場合

Epoch Total Loss Policy Loss Value Loss Move Accuracy Value Accuracy
1 3.9012 3.3180 0.5833 0.2844 0.6544
2 3.4626 2.8997 0.5630 0.3194 0.6710
3 3.2766 2.7227 0.5539 0.3407 0.6819
4 3.1787 2.6200 0.5587 0.3514 0.6841
5 3.1518 2.5581 0.5938 0.3606 0.6776
6 3.1222 2.5166 0.6057 0.3661 0.6785
7 3.1237 2.4928 0.6309 0.3681 0.6770
8 3.1259 2.4712 0.6547 0.3718 0.6764
9 3.1711 2.4665 0.7046 0.3728 0.6740
10 3.1869 2.4692 0.7177 0.3742 0.6748
11 3.2392 2.4728 0.7664 0.3733 0.6735
12 3.2619 2.4747 0.7872 0.3741 0.6717
13 3.2887 2.4768 0.8119 0.3761 0.6696

 損失の比が1:0.01の場合

Epoch Total Loss Policy Loss Value Loss Move Accuracy Value Accuracy
1 3.3156 3.3090 0.6593 0.2834 0.5909
2 2.8898 2.8834 0.6388 0.3241 0.6097
3 2.7190 2.7127 0.6262 0.3418 0.6196
4 2.6072 2.6010 0.6199 0.3549 0.6245
5 2.5365 2.5303 0.6135 0.3603 0.6298
6 2.4879 2.4818 0.6082 0.3686 0.6344
7 2.4555 2.4495 0.6045 0.3722 0.6367
8 2.4368 2.4307 0.6018 0.3753 0.6388
9 2.4318 2.4259 0.5982 0.3756 0.6418
10 2.4138 2.4078 0.5952 0.3798 0.6441
11 2.4311 2.4251 0.5946 0.3785 0.6441
12 2.4338 2.4278 0.5929 0.3803 0.6452
13 2.4469 2.4410 0.5937 0.3783 0.6453
14 2.4570 2.4511 0.5925 0.3789 0.6469
15 2.4788 2.4729 0.5911 0.3769 0.6468
16 2.4921 2.4862 0.5890 0.3783 0.6484
17 2.5086 2.5027 0.5892 0.3781 0.6487

 グラフでは

 損失が1:1の場合 f:id:tokumini:20180423151142p:plain

 損失が1:0.01の場合 f:id:tokumini:20180423151205p:plain

損失最小の時点での結果

比(Move:Value) Total Loss Policy Loss Value Loss Move Accuracy Value Accuracy
1:1 3.1222 2.5166 0.6057 0.3661 0.6785
1:0.01 2.4138 2.4078 0.5952 0.3798 0.6441

 損失が1:1のとき、PolicyとValueでピークがあってないように見えるのが気になるんですね。その点1:0.01にすると無理やりValueの変化を小さくできているような……。しかしValueがまだ学習できるような感じにも見えます。この中間くらいでしょうかね。

 澤田さんの本を読んでも思ったのですが、目的意識もないままによくわからない実験を繰り返しているのは良くないですね。何かしらの仮説があって、それを検証するような実験を行いたいです。

 まぁしかしいろいろなネットワークを試していた結果、結局5ブロックのCNNで良いんじゃないかとわかってきたのは成果なのかもしれません。

 そろそろ強化学習の方に手を付けていきたいと思っていますが……。

DeepLearningによる将棋の学習6~全結合型NN~

 前回は損失の配分を調整して学習をさせてみましたが思わしい結果は得られませんでした。しかし、これは指し手予測の精度だけを見た場合の話であり、損失について考えると実は良い結果になっているともいえるかもしれないことに記事を書いてから気づきました。

 というのも前回の結果をPolicyとValueそれぞれの損失まで描くと下のようになり

f:id:tokumini:20180421105706p:plain

 配分を1:1にしていたときのグラフは

f:id:tokumini:20180421105943p:plain

 のようになっていらからです。配分が1:1だとValueの損失がすぐ上がっていってしまう(精度はそれほど悪化しない)という問題があり、それが緩和されていた可能性があります。Valueは精度よりも損失の方が重視されるべき指標にも思えますし、配分を変更させるのは良かったのかもしれません。

 この辺りは対局させてみないとわからないということになるのかもしれません。また今後はPolicyとValueのそれぞれの損失も表示するようにします。

 今回はそもそもCNNではなく全結合にしてみたらどの程度の性能になるのかを実験してみました。基本的に畳み込み層をそのまま全結合層に置き換えただけの構成になっています。全結合層を使う場合でもResidual Blockを作るのはおそらく効果あるのだと思いますが正確なことはわかりません。以下はその実装となります。

unit_size = 2048

def ResidualBlock(inputs):
    dense1 = tf.layers.dense(inputs=inputs, units=unit_size)
    bn1 = tf.layers.batch_normalization(inputs=dense1, training=True)
    relu1 = tf.nn.relu(bn1)
    dense2 = tf.layers.dense(inputs=relu1, units=unit_size)
    bn2 = tf.layers.batch_normalization(inputs=dense2, training=True)
    return tf.nn.relu(inputs + bn2)

def policy_value_func(features):
    # featuresのshapeは9×9マスが104チャネル ([-1, 9, 9, 104])
    # ResidualBlock
    flat = tf.reshape(features, [-1, 9 * 9 * 104])
    layer1 = tf.layers.dense(inputs=flat, units=unit_size, activation=tf.nn.relu)
    res1 = ResidualBlock(layer1)
    res2 = ResidualBlock(res1)
    res3 = ResidualBlock(res2)
    res4 = ResidualBlock(res3)
    res5 = ResidualBlock(res4)

    # policy_network用
    dense_policy = tf.layers.dense(inputs=res5, units=9 * 9 * MOVE_DIRECTION_LABEL_NUM)
    policy = tf.reshape(dense_policy, shape=[-1, 9 * 9 * MOVE_DIRECTION_LABEL_NUM], name="policy")

    # value_network用
    dense_value = tf.layers.dense(inputs=res5, units=unit_size, activation=tf.nn.relu)
    # 出力値はスカラ1つ
    value = tf.layers.dense(inputs=dense_value, units=1, name="value")
    # サイズ1のベクトルになっているのでsqueezeで直す
    squeezed_value = tf.squeeze(value, axis=1, name="squeezed_value")

    # policyとvalueの二つを返す
    return policy, squeezed_value

 ユニット数は2048、損失の比は1:0.01、

loss_op = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=policy, labels=teacher_for_move)
                         + 0.01 * tf.nn.sigmoid_cross_entropy_with_logits(logits=value, labels=teacher_for_win))

optimizerはSGD、patienceは5で実験を行いました。以下が結果となります。

Epoch Total Loss Policy Loss Value Loss Move Accuracy Value Accuracy
1 4.5123 4.5054 0.6939 0.2024 0.5642
2 4.0329 4.0262 0.6781 0.2430 0.5753
3 3.7613 3.7545 0.6757 0.2654 0.5781
4 3.5761 3.5695 0.6654 0.2796 0.5897
5 3.4540 3.4474 0.6595 0.2906 0.5929
6 3.3782 3.3717 0.6588 0.2955 0.5938
7 3.3175 3.3109 0.6586 0.3035 0.5938
8 3.2783 3.2717 0.6581 0.3075 0.5960
9 3.2539 3.2473 0.6587 0.3105 0.5942
10 3.2397 3.2331 0.6556 0.3137 0.5960
11 3.2226 3.2160 0.6535 0.3152 0.5993
12 3.2501 3.2436 0.6512 0.3160 0.6003
13 3.2673 3.2608 0.6493 0.3148 0.6012
14 3.2725 3.2660 0.6483 0.3161 0.6008
15 3.3043 3.2977 0.6508 0.3160 0.6009
16 3.3179 3.3115 0.6473 0.3170 0.6024

f:id:tokumini:20180421103818p:plain

 一番損失が小さいタイミングを抜き出すと

Epoch Total Loss Policy Loss Value Loss Move Accuracy Value Accuracy
11 3.2226 3.2160 0.6535 0.3152 0.5993

 であり、畳み込み層を使う場合より性能は低いことがわかりました。

 結果で気になる点は、損失が下がらなくなってからも精度は上がっていることでしょうか。この実験に限らず損失のピークと精度のピーク、あるいはPolicyのピークとValueのピークなどの間にズレがあり、どれを信じるものなのかよくわかりません。

 今回からグラフの作成をmatplotlibを用いて自動化しました。まだ使い方がよくわからず苦労するところも多いのですが……。

DeepLearningによる将棋の学習5~損失の配分を変更~

 前回はフィルタサイズを変更してもうまくいかないことを確認しました。

 個人的にはDeepLearningによる学習でValueの学習がなかなかうまくいかないという点が気になっています。マルチタスク学習をさせているので損失は指し手の一致具合とValueの一致具合の和を取っている

loss_op = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=policy, labels=teacher_for_move)
                         + tf.nn.sigmoid_cross_entropy_with_logits(logits=value, labels=teacher_for_win))

のですが、ここの配分を変えてみることで何か知見が得られないかと考えました。

 小さいデータ(訓練用1000局、テスト用100局)でいくらか試してみたところ、Value側の損失を大きくしても(定数100をかけても)そこまでValue予測の質は改善されない一方、指し手予測の方はひどい性能になりました。

 もともとValueだけを学習するネットワークでもそこまでの精度になっていないことを考えると、これは当たり前なのかもしれません。

 一方で逆にValueの損失を小さくするとValue予測の方は多少質が悪化した一方で指し手予測の精度は上がったため、これで全データを使って実験してみました。正確にはvalue側の損失に0.1をかけて学習させました。

loss_op = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=policy, labels=teacher_for_move)
                         + 0.1 * tf.nn.sigmoid_cross_entropy_with_logits(logits=value, labels=teacher_for_win))

 Residualブロック数は5、optimizerはSGD、early stoppingのpatienceは7で実験した結果が以下となります。

epoch Loss Move Accuracy Value Accuracy
1 3.5121 0.2691 0.6114
2 3.0486 0.3111 0.6389
3 2.8629 0.3315 0.6432
4 2.7399 0.3454 0.6505
5 2.6606 0.3545 0.6572
6 2.6133 0.3587 0.6618
7 2.5537 0.3667 0.6635
8 2.5361 0.3689 0.6647
9 2.5160 0.3707 0.6698
10 2.4973 0.3730 0.6707
11 2.4876 0.3743 0.6689
12 2.4843 0.3759 0.6745
13 2.4760 0.3783 0.6731
14 2.4844 0.3774 0.6744
15 2.4794 0.3795 0.6742
16 2.4832 0.3790 0.6717
17 2.4864 0.3799 0.6747
18 2.4926 0.3797 0.6761

f:id:tokumini:20180420095852p:plain

 学習に必要なエポック数は伸びていますが特に性能は上がっていません。損失の合計が小さくなっているので収束が遅いのは当然なのでしょうか。それならばValue側の損失の寄与も十分に意義あるものだった、ということになると思えます。

 学習自体が不安定なのではないかという説も自分の中で起こっています。同じ条件で何度も実験してみないと何も言えないのかもしれません。

 実験とは本質的に関係のないことかもしれませんが、ログファイルから表の作成、グラフの作成あたりは自動化しておいたほうが良さそうですね。山岡さんの本でもいくらか記述があったので、それを参考に頑張ってみたいと思います。

DeepLearningによる将棋の学習4~フィルタサイズの変更2~

 前回はフィルタサイズを5にして実験してみました。その結果性能は下がり、学習時間も多くなるということがわかりました。単純に考えれば増やしてもダメだということになるのですが、念のため今回はさらにフィルタサイズを7にして実験を行いました。結果は以下の通りです。

epoch Loss Move Accuracy Value Accuracy
1 3.5894 0.3014 0.6561
2 3.2799 0.3346 0.6786
3 3.2016 0.3457 0.6791
4 3.2024 0.3553 0.6773
5 3.2453 0.3565 0.6728
6 3.4741 0.3611 0.6501
7 3.3973 0.3579 0.6676
8 3.5083 0.3570 0.6656
9 3.5896 0.3581 0.6662
10 3.6940 0.3570 0.6682

f:id:tokumini:20180419105101p:plain

 今までの結果とまとめると次のようになります。

フィルタサイズ Loss Move Accuracy Value Accuracy 1エポックあたりの学習時間
3 2.9753 0.3879 0.6853 約40分
5 3.1447 0.3643 0.6744 約47分
7 3.2016 0.3457 0.6791 約49分

 やはりフィルタサイズは3が良いようです。