電竜戦を振り返って(みずうら王)

 第1回電竜戦,皆様大変お疲れさまでした!運営の皆様もこのような素晴らしい大会を開催していただき,感謝感謝です。

 

 電竜戦の感想のために,久しぶりに長い記事を書こうと思います。

 

 今回,私は,やねうら王本家とタッグを組んだ「みずうら王 with お多福ラボ」,及びPythonフルスクラッチで書いた「すいしょう」という2ソフトで出場させていただきました。

 

 結果は,みずうら王が6勝3敗でA級4位, すいしょうが2勝7敗でB級38位となりました。

 ご注目いただいた皆様には感謝申し上げます。ありがとうございました。

 

 

 

・みずうら王 with お多福ラボ

 こちらのソフトについては,やねうら王本家のやねさんに対し,「計算機として3990Xを貸しますから電竜戦に出てください!」という話を振ったことから始まり,最終的には,やねさんが探索部を改良し,私が評価関数及び定跡を作成するといった運びになりました。その辺りの経緯はやねさんのブログに詳しいので,そちらをご確認ください。

yaneuraou.yaneu.com

 

 

 

・評価関数強くならない。

 評価関数については,従来のKPPTからNNUEに変わったことによってブレイクスルーが起きて,コンピュータチェスの世界最強ソフトであるStockfishに採用されるまでになりました(素晴らしい成果で,今年のコンピュータ将棋関連のニュースでは今回の電竜戦と並ぶ2大ニュースだと思っています。)。

 

 しかし,NNUEも,標準NNUE(halfKP256x2-32-32)については,表現力の限界に来ており,ここ2年くらい強くできていないのではないか,と言われてきました。

 水匠については,その表現力を,コンピュータ将棋で発生しやすい局面で強くするために使い,相居飛車の特定の戦型では強いが,例えば対振り飛車ではあまり強くないという評価関数を作成した上で,WCSOC2020ではmブランチの力とThreadripper 3990Xの力を使って水匠2優勝という成果を出すことが出来ました。

 

 その水匠2の評価関数から,Threadripper 3990Xをフル活用し(WCSOC前は,3990Xを購入するのが遅く,あまり活用出来ていなかった。),電竜戦に向けて更に戦型特化して強くしようと考え,学習を進めていたのですが,floodgate上位陣の棋譜から作成した互角局面の24手目からの連続対局という計測方法で,水匠2からR+30くらい(勝率55%くらい)の評価関数しか作れませんでした。

 Stockfishにおける評価関数の成長具合(下記リンク)からして,標準NNUEについても,根気よく学習を進めればもう少し伸びるかと思っていましたが,手法が良くないのか,誰にとっても限界なのか,厳しい結果となりました。

https://www.comp.nus.edu.sg/~sergio-v/nnue/

 

 

 

・計測方法のバラつき

 評価関数の強化と関連して,今回,私はtanuki-チームのnodchipさんが開発したTanukiColiseumを使って,評価関数の学習具合を計測してきました。

github.com

 

 これはGUIで操作できるので私のような初心者でも扱いやすく,Twitter映えもするので,現在も愛用しています。

 しかし,評価関数の学習をして,TanukiColiseumを使って計測し,やねさんに対し「これだけ強くできたよ!これ本番で使うべきじゃないですか?」と画像を添付するとともに評価関数を提出すると,やねさんからは「こっちでも計測したけど全然強くなってないやん,はい,やり直し」(意訳)というようなことがありました。

 

 やねさんは,ご自身でPythonで書いた連続対局スクリプトを使用しているようで,その計測との差異があるようでした。

github.com

 

 このようなことが何故起こるのかはよくわかっていないのですが,仮に,同じソフトを対局させていても,連続対局プログラム毎に異なる結果を弾き出すとすれば,計測の根底から覆されてしまうこととなるので,本当に異なる結果となるのかという点から検証した上で,最終的には原因を究明したいです。

 

 

 

・定跡の作成

 評価関数が強くならないので,定跡を頑張るしかない,という気持ちで定跡の作成にはある程度時間を費やしました。

 定跡の作成方法として,近年話題となっているものとして,定跡局面をツリー化し,末端局面の評価値をミニマックス法で初期局面まで伝播させるというテラショック定跡手法があります。

テラショック定跡の生成手法 | やねうら王 公式サイト

 これは大変素晴らしい手法なのですが,

①計算資源が膨大に必要であること,②一つでもおかしな評価値があるとそれが伝播してしまうこと,③作られたテラショック定跡を使用した上で敗局を集め,それをまた掘り進め育てていくことが有用である(それができることがテラショック定跡のメリットのひとつ)ところ,おそらくそこまで到達できない(最初にある程度強いテラショック定跡を作るところで精一杯)という点で,難点も存在します。

 

 そこで,私は定跡の作成手法としては,floodgate上位陣の棋譜及び既に様々存在している定跡ファイル(C-Bookなど)を使って連続対局をした棋譜を使用して,勝敗ベースで定跡を作った方が,現実的な時間で強い定跡ができると考えていました。

 

 そこで,今回は,floodgateの棋譜(負けた側がR3800以上の棋譜)と,自己対局の棋譜を合わせて30000対局ほど準備して,定跡作成に臨みました。

 

 まず,定跡の作成手法としては,一番簡易なものとして,任意の局面における,勝ち数が最も多い指し手を採用するというものを作成しましたが,これでは,逆転勝ちの局面も含まれてしまうため,あまり精度が高くなりませんでした。

 

 次に,それを改良して,逆転の起こった棋譜を排除した上で(勝った側が評価値を200より悪くしたことがない棋譜のみ集める),同じく勝ち数が最も多い指し手を採用するものも作りましたが,これも,当該局面における負け局数を考えていないため,勝率は悪いが勝ち局が多い指し手を採用してしまうことがあり,精度はそれほど高くなりません。

 

 そこで,またそれを改良し,任意の局面において,指し手の勝数×2-負数の値が最大となるような指し手を採用する定跡を作成しました。

 最終的にはこの定跡作成手法が,私の技術力で自動化して作ることができる定跡としては最強のものとはなりましたが,これも,進んだ局面で勝率の低い局面に誘導されてしまう可能性があるため,これを採用することはしませんでした。

 

 最後に,最低対局数が5以上である局面について,指し手の勝数×2-負数の値を計測した上で,その数値を評価値として記載した定跡ファイルを作成し,テラショック定跡のmakebook build treeコマンドを使ってゲーム木化した上で末端の局面から初期局面までその数値を伝播させる手法を取ろうとしましたが,やはりテラショック手法の「一つでもおかしな数値があるとそれが伝播してしまう」という欠点等に阻まれ,自動では上手く定跡を作成することができませんでした。

 任意の局面における勝率をベースに,局面に至るまでの手数や対局数に応じてボーナス点を与えた上で,評価値を形成し,テラショック手法でゲーム木化するような良い手法がある,もしくはモンテカルロ木探索的に指し手を選択する定跡を作る手法があると思うのですが,私のレベルでは到達はできませんでした。

 

 そこで,ここからはもう酷いのですが,任意の局面における勝率をベースに手動で(目で見ておかしいであろう勝率の指し手は排除した上で),末端局面から勝率ベースで初期局面まで伝播させるという手法を取り,私の技術力では自動化はできないものの,仕組みだけでも正しいことを証明しようとしたのが,今回のみずうら王が採用した定跡でした。

 

 それが功を奏して,定跡を抜けた時点で評価値が200ほど良い局面に誘導できたり,後手番でも互角のまま中盤まで進むことができたり,全対局について,少なくとも定跡を抜けた時点で悪い評価値を出しているということはなかった定跡を作ることができました。しかし,前述のとおり評価関数の改善が上手く行っていなかったので,結果は前述のとおりとなりました。

 

 

・おわりに

 やねさんは探索部の改善でレーティングを上昇させることが出来ており,それが今回のみずうら王での最大の棋力向上要因となったのですが,私の方が評価関数の方であまり貢献できず,定跡もどれだけ効いていたかはわからず,今回のような結果となり少し残念な気持ちはあります。

 しかし,最終戦に勝っていれば優勝できていたなど,面白い対局をすることはできていた&特にトラブルはなかったという点では満足しております。

 

 最後となりますが,電竜戦を運営していただいた皆様,ご寄付等をいただいた皆様,ご覧いただいた皆様に多大な感謝をいたしまして,この記事を終わりにさせていただこうと思います。大変ありがとうございました!

 

 すいしょうの方はまた気が向いたら記事にしようと思います!

WCSC29を振り返って(前半)

令和元年5月3日から同月5日の間に、第29回世界コンピュータ将棋選手権(WCSC29)に参加してきました。その事前準備や当日の感想をつらつらと書いてみます。今回は、前半ということで、事前準備の部分を書いていこうと思います!

 

1 はじめに

私は、NNUEの野良評価関数を作っていたのですが、無謀にも、1月末にWCSC29に参加することを決めました。

参加するにあたって、目標は、参加者の中で一番強い評価関数を作成することでした。他の工夫(AWSの複数運用等)はプログラミング初心者の私にとっては極めて難しいため、今回は諦め、次回以降の課題としました。

そして、WCSCルールを読むと、ライブラリに登録されていない野良評価関数は使えないと解釈できたため、WCSC28のtanuki-チームの評価関数やApery評価関数を借りて、もう一度NNUEkaiやillqha、orqhaまで強くすることにしました。

 

 

2 評価関数強化の工夫

まずは、Depth8で教師局面を作成し、飽和局面数(これ以上局面を学習させても強くならない局面数)を探索することにしました。交差エントロピーの値や、実際の勝率等で計測すると、HalfKP 256x2-32-32では、10億局面くらいが飽和局面数であることがわかりました。

また、以下のとおり、教師局面の評価値等を事後的に変更する手法を取ることとしました。

(1)前後2手の評価値を見た評価値の修正

n手目の評価値 < n-2手目の評価値 < n+2手目の評価値 かつ n-1手目の評価値 < n+1手目の評価値となっている場合、n手目の評価値は、前後の評価値の推移からすると間違っている可能性が高いと判断されるため、n手目の評価値をn-2手目の評価値まで引き上げるという修正をしました。

(2)勝敗と評価値のずれの排除

勝利側の評価値であるにも関わらず負の評価値となっている場合、敗北側の評価値であるにも関わらず正の評価値となっている場合、その局面の判断が間違っている可能性が高いため、排除してしまうこととしました。その代わり、学習の際のLAMBDAは限りなく1に近くするようにしました(ほぼ勝敗項を見ない学習)。

こんな方法で強くなるはずがなさそうですが、手元の計測では、勝率項に関わる交差エントロピー、勝敗項に関わる交差エントロピーのいずれもが減少し、評価関数の勝率も上昇することとなりました。

 

 

3 評価関数の評価の工夫

評価関数を評価する(言葉がわかりづらい)のに、一番正確なのは、評価関数同士を戦わせ、勝率を計測することだと考えていますが、統計上の有意差を出すまで対局させるととても時間がかかってしまいます。

しかし、学習ログだけを見て判断してしまうと、ログ上はいい結果でも、勝率はよくなっていないということが起こるため、よくありません。

そこで、評価関数を評価するためにとった手法として、学習後の評価関数に教師局面を作成させ、その教師局面の中に、前項(2)のような、勝敗と評価値にずれがある局面がどれだけあるか、割合を計測することとしました。

強い評価関数であれば、勘違いは減るはずなので、教師局面における、勝敗と評価値にずれがある局面の割合は減るはずです。この計測方法は、勝率を計測するよりは時間がかからず、検証をした結果では、ある程度正確だと判断できました。

 

 

4 結果

上記のような工夫をしつつ、評価関数を作成しました。選手権直前までは、ゼロベクトルから評価関数を作成しており、ある程度の勝率を出すことはできたのですが、結局のところ、どうしてもWCSC28のtanuki-評価関数に追加学習をさせた方が強くなる(tanuki-の学習結果が神がかったバランスだったのだと考えています)ため、最終的には、水匠は、tanuki-からの追加学習としました。

追加学習の結果、水匠は、初期局面計測でおそらくorqha1018を超え、中途局面(24手目以降の指定局面)でも、ある程度強くなった気がします。

 

 

5 お詫び

「水匠は、後手では角換わりを避けるぜ、へへへ」などとツイートをしました。

 しかし、棋譜を見たところ、水匠は、2五歩を突かない形での角換わりを目指す場合が多いため、後手番に雁木を指すことが多い、というからくりがありました。すなわち、2五歩を突かれる形での先手番角換わりに対しては、素直に角換わりに応じていました。したがって、上記ツイートは嘘をついています。誠に申し訳ございません。

 

本番でも、後手番で普通に角換わりを指してましたね。ひどい。しかし、角換わり拒否の雁木も結構指していたので、許していただきたいです!

 

後半では、選手権当日のことを書いていきたいと思います!