やねうら王のGitHubに私が7ヶ月ほど前にcommitした改良、盛大にバグっていたことが判明した。
探索は主にsearch(通常探索)とqsearch(静止探索。末端の局面でsearchから呼び出される)との2つの関数があるのだが、このqsearchで、詰んでいないのにmateのスコアをreturnしているというバグがあった。それもかなりの頻度で、である。
具体的な箇所はここである。ここを7ヶ月ほど前に改良のつもりでこう変えたのだが、これが大チョンボであった。
// ※ この部分の正しい条件式は、
// if (ss->inCheck && bestValue == -VALUE_INFINITE)
// である。このように書き換えればこの問題は修正される。
qsearchで、moveCount==0の時(生成された合法手がない時)、私は詰みだと思っていたのだが、王手がかかっていない時は、MovePicker(指し手オーダリング器)がcaptures(捕獲する指し手)とchecks(王手となる指し手)しか生成していなかった。
逆に、王手がかかっている時はevasions(回避する指し手)を生成するので、その場合に限り、moveCount == 0なら詰みの局面と言える。
だから上のソースコードでは、王手がかかっていない局面で、捕獲する指し手も王手となる指し手もない時、その局面の評価値としてmateのスコアを返していることになる。
これだけ盛大にやらかせば、極端に弱くなりそうなものである。しかし、これが何と強くなるのだ。(誤差程度ではあるが) こんなにやらかして強くなるのだからわけがわからない。酒飲んで強くなる、酔拳にも似たものがあるな。😅
まあ、そのへん詳しく書き出すと話が進まないので、とりあえず、そういうこともあるということなんだけど、問題は、これ修正したほうが良いのかということである。修正すると弱くなるのである。(誤差程度ではあるが) 弱くならない形で修正しようと思っているが…。
それはそうと、qsearchがmateスコアを返してくるので、強化学習を行う時にわりと大きな影響があって、たぬきシリーズの開発者の野田さんは、「学習に使うなら、最新のやねうら王はバグがあるようなので1年以上前のやねうら王を使うことをお勧めします」とやねうら王初心者にアナウンスしていたほどである。私はその時は半信半疑でそれを聞いていたのだが、結果的にそれは正しかったわけであるな。
あと、やねうら王(NNUE評価関数)をPyTorchを用いて学習をさせれば爆速で学習できるはず!!ということで、同じく野田さんが取り組んでおられるのだが、学習がうまくできなくてそのまま開発が停滞している。学習時には、通常探索(search)は呼び出さず、静止探索(qsearch)を呼び出すので、qsearchがバグっているなら、多大な影響が出そうである。なので、PyTorchでうまく学習できない件も、もしかするとこれが原因なのかも知れない。
そもそもそんなバグを私は何故仕込んでしまったのかと言うと、こう変更したほうが(棋力が)強くなったからである。強くなったもんで、これで正しいのだと信じてしまった。間違っているのにも拘わらず強くなることがあるんだなということで、この記事を終わりたい。
学習時のqsearchとは静止探索の評価値を静止探索の局面に学習させるって意味ですよね。
教師データ作るときにやっておけば全部不要になってPyTorch使った学習は劇的に速くなりそう。
私もそう思います。爆速になると実験が捗るので嬉しいですね。
関係ないバグか?だとは思いますがちょっと前に水匠が変な挙動をしていたのを見かけました。
Suisho6test2_TR3990Xが詰んでないのに詰んでいると誤認するバグ
Kurara-test vs. Suisho6test2_TR3990X (2022-04-09 11:00)
http://wdoor.c.u-tokyo.ac.jp/shogi/view/2022/04/09/wdoor+floodgate-300-10F+Kurara-test+Suisho6test2_TR3990X+20220409110004.csa/102
それはhash衝突絡みですね。やねうら王をTT_CLUSTER_SIZE=2にしてコンパイルした実行ファイルだとその現象は起きないことは確認しています。
べ、別に時間を割くような手筋じゃないけど詰んではいないんだからねっ!勘違いしないでよね!
みたいな感じでいいですか?w
ワロタ