電王戦 --- 将棋電王トーナメント --- やねうら王特設ページその2
■ 2013/10/28 2:20 前記事が長文になりすぎたので新しいページを開設。
前記事)
電王戦 --- 将棋電王トーナメント --- やねうら王特設ページ
http://d.hatena.ne.jp/yaneurao/20131013#p1
前記事の内容を三行で要約。
・やね裏定跡、やね裏学習メソッドI,IIの実装完了。評価関数パラメーターの収束、祈祷中。
・持ち時間制御などあと3000行ぐらい当日までに書かなくてはならないが、すべてが完璧に書けて、かつバグなしに一発で動くよう祈祷中。
・探索部の根が深そうなバグを修正し、さらに探索パラメーターの調整をしないといけないが、手作業によるチューンによって一発で神調整になるよう祈祷中。
って、祈祷ばっかりやがな!ヽ(`Д´)ノ
皆様もコメント欄でご祈祷のほう、よろしくお願い致します。
なお、電王戦トーナメントの最終局直前までVisual Studioを立ち上げ、やねうら王の開発を続けたいと思います。(気力が残っていれば)
■ 2013/10/28 12:10 評価関数はどうあるべきか
Q) 評価関数のそれぞれのパラメタの値は、ボナンザと似たような感じになるもんなんでしょうか?
A)
まず一般論としてBonanzaと同じ三駒関係であっても、ボナンザメソッドで学習させる棋譜によってそれぞれのパラメーターの値はずいぶん異なってきます。
評価関数の目標は、自分に有利な局面をプラスの値、自分に不利な局面をマイナスの値が出力されることなので、そういう意味では、究極的にはどのソフトでも出力としての評価値は同じぐらいの値に落ち着くべきなのですが、そうはなっていないのが実状です。
その原因としまして、評価関数の分解能(汎化能力)によってはそれが達成できなかったり(似た問題に「XOR演算は線形分離できないのでパーセプトロンでは学習が難しい」がありますが、それと同様です)、あるいは機械学習のアルゴリズムによってはうまい値に収束しなかったり、サンプルとすべき棋譜が足りていないので特定のパラメーターが学習できずに0のままだったり、サンプルとすべき棋譜に誤り(悪手)が含まれていたり…。
ただ、駒得のみの評価関数であっても深さ∞まで探索すれば、現在の局面に対して正確に勝ち負け(と引き分け)が判定できることからして、評価関数が多少粗雑であっても探索を深くすればある程度優劣は正しく判定できるということがわかります。つまり、探索を深くすれば(探索結果としての)評価値は似たような値(少なくとも符号ぐらいは一致する)ようになります。このへんがなかなか神秘的なところですね。
■ 2013/10/28 2:55 ハッシュ衝突を回避
64bitハッシュでも持ち時間が長く、局面数をたくさん探索するとハッシュ値の衝突は起こりうるわけで、今日はそれが気になってそのときにエラーで落ちないようにコードを追加したけど、今度はその追加したコードがバグってないかだとかの検証が大変。
こんなコード追加しても強くなるどころか遅くなって弱くなるだけなのに…。しくしく。
■ 2013/10/28 3:10 思考時間制御
Bonanzaの思考時間制御ってどうなってたかなーと思って、ソースコードを読み返したら、大雑把に言えば、今回の思考時間 = 残り時間/35 みたいな式になっていた。つまり、時間は1/35ずつ減るので、時間消費量は、(34/35)^N みたいな指数関数的な減衰をする。
この関数の半減期(?)は 1/2 = (34/35)^Nの両辺logをとって、N = log(1/2) / log(34/35) ≒ 23.9。24手ほど自分が指すと思考時間が残り半分になっている計算だ。(実際は、思考を早めに切り上げたりすることがあるので半減するのにもう少し余裕がある)
終盤の時間が徐々に減っていくので私はこの方式は、どうかと思うのだけど、Bonanzaがやってるぐらいなのでそんなに悪くないのだろう。
Stockfishは、時間配分はソースコードがC++templateで書かれていて読み解く時間がないのだが、時間延長の処理としては反復深化でbestmoveが更新された回数を局面の不安定性として捉え、今回の思考時間 = (その回数×今回の指し手のための時間 / 1.4) だけ時間を延長する、みたいな方法が取られている。
このへん、なかなか興味深い。
■ 2013/10/29 3:15 計算資源の貸し出しについて
いまから思考時間制御のコードを書いて、自己対戦をしてパラメータの調整などをしないといけない。ところが自己対戦200戦もするとなると、2分切れ負けでも相当時間がかかる。そもそも2分切れ負けだと後半、ほとんどの指し手が1秒なので実験にならない。
そこでテスト用のマシンが複数必要になる。このマシンを本来は不特定多数からお借りすることが出来ればいいのだが、インターネットが普及して20年近く経とうというのに、いまだ仮想化された計算資源を、投げ銭をするぐらいの手軽さで他人に貸し出すことはできない。だから、いくらこのブログにそこそこのPVがあり、日々の訪問者が何千人いようとも計算資源の貸し出しという観点においては全くの無意味である。
本来、その程度のことはOSがサポートすべきなのである。OSがこういう機能をサポートしないのは、怠惰であり、科学技術の発展を阻害しているわけである。
OSがサポートしてくれないなら、ブラウザに頼るほかない。仮想環境自体はGoogle Native Client程度のもので良いのだ。問題は、それをクリック一つで他人に貸し出せなければならないということだ。(貸し出すからには、相手が自分のPCのリソースをどれだけ使用しているのかだとか、いつ使用していたのかだとか、そういう統計情報の表示が必須である。)
ブラウザを作っている人たちは、どうかご一考いただきたい。
OSレベルでサポートされない以上、あなたたちこそが最後の砦なのであるから。
■ 2013/10/29 5:20 思考時間制御が一応書けた
なんか適当に書いたのにそこそこうまく動いている(気がします)
if (byoyomi == 0) { // 秒読み時間が設定されていない(無し)のときの戦略 myOptTime = remain / 35 ; // 35で割って、その1/3を目安にiterationする myMaxTime = remain / 25 ; // これ以上使うとさすがにやばいだろ.. myMinTime = 0; // どうせ端数は繰り上げる } else { // 秒読み時間が設定されているときの戦略 if (remain >= byoyomi * 20) { // 残り時間が秒読み時間に対して極めて長い。(そもそもそんな短い秒読みとかありえん気がするが…) myOptTime = remain / 35 + byoyomi ; // 35で割って、秒読みも加味してその1/3を目安にiterationする myMaxTime = remain / 25 + byoyomi ; // これ以上使うとさすがにやばいだろというライン myMinTime = byoyomi ; // どうせ端数は繰り上げる。 } else { // 残り時間少なくなってきたので、秒読み時間を使うこと前提の時間配分に変更しよう。 myOptTime = remain / 10 + byoyomi ; // 10で割って、その1/3を目安にiterationする myMaxTime = remain / 5 + byoyomi ; // これ以上使うとさすがにやばいだろ.. myMinTime = byoyomi ; // どうせ端数は繰り上げる } }
あとStockfish風に(さっきソースコード見て知ったばかりなのに!)、iteration中にbest moveが変化した回数に応じて探索時間の加算をしてます。
myOptTime(optimum timeの意味)を基準に考え、1回のiterationごとに経過時間がこの時間の1/3を超えていたら(PonanzaのC#のソースコードがそうなっていたから!)、探索を終了します。
しかし、終了するときに秒読み時間が余っていたらもったいないので、myMinTimeの時間分だけは是が非でも思考するという風に作ってあります。
また、探索時間延長時にmyMaxTimeを超えないようにします。これを超えると時間切れの可能性が出てくるので。
iteration部は、aspiration searchになっていて、aspiration中のbest moveの取り出しについては置換表などの関係から結果が安定しない(YSSの山下さんがそんなことを言っていたと伝え聞き)らしいのですが、やねうら王ではaspiration searchでもそこから無理矢理、結果を取り出しています。一応、自己対戦の勝率からすると、その部分はきちんと効果が出ているようです。(たぶん)
aspiration searchの中の思考結果の取り出しについてはいろいろ書きたいことがあるのですが、ちょっと専門的かつ長くなるので、これについてはもう少しよく考えてから論文か本にでも書きます。(一言で言うと、Fail-Highしたスコアがそのノードの真のスコアの下界(下限)だと仮定できるなら、例えば探索開始局面の最後の手だけFail-Highしたなら、aspiration searchの探索窓を広げての再探索をしなくてもいいだとか、そういう結論が得られます。ところが…みたいな話です。)
■ 2013/10/29 5:45 探索がおかしい原因が判明
原因の一つがなんとなくわかった。良かれと思って3年ほど前に高速化のためにやったことが全くの裏目に出ているであろうことがわかった。さっき寝てたら、突然夢のなかでわかって、飛び起きた。
バグというよりは、設計上のミスというか、将棋というゲーム木の探索の性質をよく理解していなかったというか、そういうことに起因する問題であり、プログラム自体は私の意図通りに動いていたのだと思う。
これをなおすにはソースコードを大量に書き換えないといけない。時間がもう残されていない。そんなに大量のソースコードをバグなしで一発で書き換えられる自信がない。私は目が超悪くなってから、typoが絶えなくて、ロジックのミスがなくとも何らかの打ち間違いなどによるエラーが起きる可能性が高い。こんな状況でやるべきことではない。
この部分をなおせば、おそらくBonanzaには勝ち越すはずなんだが(他にも原因がない限り)…いまからではその書き換えは間に合わないだろう…本当…残念でならない。iOS版のテイルズオブハーツRという超大作ゲームをこんな時期に出してきやがったナムコバンダイが恨めしい。なんて面白いゲームを作りやがるんだ、くそ〜!
■ 2013/10/29 13:25 best moveの変化
Stockfish風にbest moveが変化した回数に比例させて思考時間を延長するコードにしたのだが、以前のバージョンと対戦させると4:6ぐらいで負け越し。(時間がないのであまり正確な計測ではない)
best moveが変化すると言っても(反復深化の)iterationの直近で変化するのと、最初のほうのiterationで変化するのとでは大きく意味が異なり、直近で変化した場合、それはそれなりに大きく評価しなければならないと思う。
本当はこのへん、統計をとってどうこうすべきだが、そんな時間もないし、
best_move_changed += iteration_depth/3;
みたいな適当なコードを書いておいた。直近のほうがbest moveの変化に対する意義が大きいと言う意味でだ。
5分ぐらいの持ち時間ならば、これでうまく指せているようなのだが、これが大会の持ち時間になったときに本当に大丈夫かどうかはわからん…。ただただお祈りするのみだ。
■ 2013/10/29 13:40 強さの判定には標準的な定跡が必要
やね裏定跡などという変な必勝定跡(?)を搭載してしまったので、自己対戦させても序盤で形勢に差がついていて、強いのか弱いのすらわからない。かと言って定跡をオフにすると似た進行ばかりになり対戦の意義が薄れてしまう。
こういう事態を避けるために、強さを計測するための標準的な定跡が必要不可欠である。
(あかん。そんなこといまさらそんなこと言ってももう間に合わん…。)
■ 2013/10/29 15:15 CSA拡張プロトコルにおける秒読みの意味
いま気づいたんですが、
消費時間の計測は、デフォルトで、いわゆるチェスクロック方式。また、byoyomi_timeが1以上であれば、total_timeで指定された持時間を消費し尽くしたのちに、秒読みとなる。
ただし、byoyomi_timeが060のときに限り、1分単位のいわゆるストップウォッチ計測。すなわち、消費時間は1分単位で切り捨てられたのち、持時間から減らされる。1分未満に指せば持時間は減らない。持時間がゼロになった時点で時間切れ負け。
プロ棋士との対局時の5時間+1手1分の1分はただの秒読みじゃないんですね、これ。ということは、考慮時間が残っているときに、4分0秒みたいな時間の使い方はもったいなくて、4分59秒みたいに使わないといけないという…。知らなかった…。その処理、いまから書きます。
2013/11/16 追記 上のは私が誤解してました。「060」のときだけストップウォッチ計測。「60」のときはチェスクロック計測。そして今回はチェスクロック計測。つまり、今回のために上のような処理は不要でした。
■ 2013/10/29 15:30 秒読み60秒に対応
前回の電王戦みたく代理の人が指すなら50秒目ぐらいまでに指し手を返すべき?
if (!listener->isInfinite && listener->byoyomiTime == 60*1000) { // 秒読みが60秒に設定されていると、CSA拡張プロトコルでは、ストップウォッチ計測らしい // 1分で切り捨てて50秒足しておくか。これだけは使わないともったいない的な意味で myMinTime = ((myMinTime-1)/60000)*60000 + 50000; // あと、maxはギリギリの値だと怖いので、maxもX分50秒にしておく myMaxTime = ((myMaxTime-1)/60000)*60000 + 50000; // 1引いてあるのは持ち時間なしになるとmyMinTime == byoyomiTimeになるので1引いていないと1分50秒になるから。 }
しかし、これいまから5時間の1手1分なんて持ち時間での動作テストできないので、うまく動くかは知らない…。
ロジックがおかしくてうまく動かないなら、そのときは思考エンジン設定で秒読み50秒とかに設定して、普通に指せばいいや…。
■ 2013/10/29 15:35 CSAプロトコルの秒読み
予選が15分 + 1手10秒なんですが、CSAプロトコルは秒の端数切捨てて(また1秒未満は1秒として計測)なので、例えば0.1秒も1.8秒も1秒と計測され、また秒読み10秒だと10.9秒まで使えることになるはずなんですが…これ正しいんですかね。一応、そのつもりでプログラムを書いてるんですが、さすがに予選リーグで秒読みで切れ負けしたら格好悪いですよねぇ…。
いまからドワンゴのテストサーバーで試してきます(´・ω・`)
■ 2013/10/29 15:45 秒読みありで残り時間が少ないとき
残り時間15秒、秒読み10秒みたいなとき、もう残り時間を使いきって25秒考えたほうが得ではないかと思い、次のコードを追加。
// こんな端数の残り時間は、使いきっちまいなよ if (remain <= byoyomi*2) { myOptTime = remain + byoyomi; myMaxTime = remain + byoyomi; myMinTime = remain + byoyomi; }
■ 2013/10/29 16:50 ドワンゴのサーバーでは秒読みテストにならない件
対戦相手に放置してあるサンプルプログラムが弱すぎて、秒読みになる前に自爆するため秒読みのテストにならないようです。
CSA拡張プロトコルなのでwhoコマンドで対戦相手を探して選べるらしいので自分でもう一台のPCから参加してそいつとマッチングさせられればいいのですが、将棋所でコマンド送信はたぶん出来ないと思うのでよくわかりません。このへん時間があれば調べるのですが、それを調べている時間も惜しいという…。
この分では当日朝早く行くか、前日参加でテストしないといけないようです。そう言えば前日のテスト日なのですが書類に「希望者のみ」と書いてあったのですが、事前表明要るのでしょうか…。
まあ、当日の朝テストします。10.9秒まで思考させてタイムアウトになるようなら思考エンジンをコンパイルしなおさなくとも秒読み設定を9秒に変更すればいいわけですし。
■ 2013/10/29 18:05 Bonanza6の時間の使い方が下手すぎる件
Bonanza6なのだが、いま対戦テストしているのだけど、電王戦トーナメント予選時の設定(持ち時間15分・秒読み10秒設定)だと60手目ぐらいで持ち時間を使い切る。いくらなんでも早すぎる気がする。
ただ、そこで形勢が大差になっていると残り1手に10秒もあればコンピューターはなかなか間違えないのでこれはこれで結構嫌なのだが。
ちなみに、やねうら王は上記設定においては100手目付近に時間を使い切るように調整した。形勢互角ぐらいで100手目ぐらいまでくれば8割ぐらい勝てると思うのだけど、100手目までに大差になっていると挽回できない。そんな感じ。
あと、Bonanza6だと秒読み10秒あるにも関わらずone reply(1手しか応手がない場合)即指しする。ここはきちんと10秒間、考えたほうが得だと思うのだが。
やねうら王は即詰みを見つけたとき(相手からの即詰みも含む)以外はone replyでも秒読み時間は使い切るようにしてある。
BonanzaはBonanza6からは修正されているとは思うのだけど、思考時間まわり、どうなんだろう…。電王戦トーナメント予選の秒読み10秒という設定はそれ相応の対策をしていないと…。
■ 2013/10/29 19:53 思考エンジン設定
拡張CSAプロトコルの秒読み60秒に対応させ、この設定のときに何秒まで使うかというのを将棋所で設定できるようにした。
こういう設定を保存したり、保存したものを復元したり、これに関連してドキュメントを更新したりで凄く時間が取られる。そもそもこんな設定、電王戦トーナメントで上位5位に残らないと何の意味もないのに…。
■ 2013/10/29 20:00 思考時間の制御はもういいや
15分+秒読み10秒の連続対局だと時間がかかりすぎるので、その1/3の時間(5分+秒読み3秒)でテスト。そこそこうまく使ってくれているようなので、もうこれでいいや。
電王戦トーナメントの本戦は2時間切れ負けらしいのだけど、このテストも1回ぐらいは2時間の持ち時間でやっておくべきのような気がするのだが、そのマシンがない。本戦でオーバーフローとかで誤動作して落ちたりしてな…。
■ 2013/10/29 22:00 Bonanza定跡だとハマる
Bonanzaと対戦させているとBonanzaに登録されている定跡はそんなに多くないせいか、比較的簡単に前回と同じ局面になる。
今回の電王戦トーナメントと同じスペックのマシンが私の手元にないので同じ局面になったところでそのあとのBonanzaの指し手はわからない。(しかも大会に出てくるのがBonanza 6そのままということもないので、実際は同じ局面になるかもわからないが。)
大会に出場するバージョンのソースコードを一式公開しているようなソフトの場合、比較的簡単にやね裏学習メソッドの餌食になる。もっとも、事前にシミュレーションするためには、大会と同じスペックのマシンが必要だ。
今回の電王戦のように大会が統一ハードでなされるのであれば、お金さえあれば同じハードを用意できるわけで、出場ソフトは、事前に大会バージョンのソースコードを公開しない(GitHubで公開したまま開発するとか禁止!)、(定跡ファイルなどの)手の内を明かさない、みたいな対策が必須となってくる。…気がする。
■ 2013/10/30 9:40 思考時間がオーバーする問題
秒読みが10秒なので9.92秒まで使うようにしていたのだが、やね裏学習メソッドI(局中に指し手のDBへの記録)をONにしていると将棋所で思考時間11秒と記録されてしまう。明らかにタイムオーバーになっている。
思考開始時間というのは、USIプロトコルによるgoコマンドが来てから計測しているのだが、サーバー的には、positionコマンドで局面を送った時点で計測開始していたりしないだろうか…。まあ、それについては誤差だと思うのだが、考えてみるといろんなオーバーヘッドがある。
サーバー、クライアント間の通信時間や、将棋所と思考エンジンとのやりとりの時間はもちろんのこと、メインスレッドとサブスレッドとのやりとりの時間もある。best moveの報告用のスレッドをSleep(0)とかSleep(1)とかで待機させておくと思考部のCPU資源を少し食うのでSleep(10)とかで待機させているのだが、これだと少なくとも10msの遅延が生じる。
プログラムに多少詳しい人ならば「Sleep使わずにシグナルを使え」と言うだろうけど、Sleep(0)のほうがシグナルを使うよりレスポンスがはるかにいい。*1 このような理由で(?)Bonanzaは全体的にSleepで書いてあり、やねうら王もそれに倣い全体的にSleepで書いてしまった。いまから書き直すのは結構の分量になるので、それは避けたい。(電王戦終わってから考える)
その他、一番大きな理由として、SQLite3がCPU資源を消費するということだ。SQLite3はスレッドセーフであり、非同期処理をしているようなのだが、それはすなわちスレッドが別にどこかに作られているということで、これにより、思考エンジンで使用している他のスレッドの動作が緩慢になる。間接的に影響を受ける。
それより増して問題になるのは、SQLite3がデータベースの書き出しをファイルに行なうとき…いまどき、DMA転送になっているのだが、バーストモードだとCPUから制御を奪うのでCPUの動作に支障を及ぼす気がする。(よく知らん)
ともかく、SQLite3がディスクに書き出すときにサブスレッドの動作に遅延が発生しており、これがせいで、将棋所で秒読み10秒設定なのに11秒と計測されてしまうのである。将棋所でそう計測されるぐらいだから、大会のようにサーバーと接続している場合、間違いなくアウトである。
そこでこの9.92秒の秒未満の0.92秒(920[ms])という数字を思考エンジンの設定ダイアログで変更できるようにした。ここまでが昨日の話である。
いま問題なのは、この920という数字をいくらにすべきかということだ。SQLite3はDBファイルが大きくなってくると読み書きに時間がかかるようになる。正直、読めない意味がある。下手すると、インデックスの再構築なんかで瞬間的に大きな負荷がかかる可能性もある。
電王戦トーナメントの本戦は2時間切れ負けなので、秒読みの問題はないのでこのへんは無視できるのだが、予選のほうは、秒読みなのでこの問題が避けられない。時間切れで、下位のソフトに負けでもしたらもはや本戦出場が危ぶまれる。
そこで下位のソフトと対局するときは、将棋所の対局設定として秒読みを10秒ではなく9秒に設定しておくだとか、局中の学習をオフにしておくだとか、そういった対策が考えられる。あまり真っ当なやり方ではないが、大会マシン性能(ディスクまわりも含めて)が予想できないので、緊急回避策である。
このように、対戦相手に応じて対局設定を変更しないといけないわけであるが、対戦相手確定後に対局設定を変更できるのかどうかは知らない。駄目なら秒読み9秒のまま運用するしかないが…。
■ 2013/10/30 10:00 10年後のコンピューター将棋について
前のバージョンの改良が正しく行えているかを自己対戦して勝率で計測するのですが、これが対局時間設定が短いとかなりいい加減な感じです。時間を長くすると、検証し終わるのに時間がかかりすぎますし、それで検証しても、なんというか、定跡を抜けた局面ですでに形勢に優劣が多少ついているので、そのまま押し切ってしまうことが結構あります。
コンピューター将棋が人類未踏の領域に踏み込もうとしているからなのですが、これが10年後とかですと、さらにコンピューター将棋の精度(中盤〜終盤)が上がっており、滅多に逆転を許さないようになっているでしょう。そうすると、定跡選択だけで勝敗が決まってしまう(100%決まらなくとも、勝率には大きな影響を及ぼす)ようになることは想像に難くありません。
そのときになって、やね裏定跡や、やね裏学習メソッドI,IIの重要性が見直される…といいですなぁ…(遠い目)
■ 2013/10/30 10:30 評価関数が収束?
まだ以前のバージョンと対局させているところなのでよくわかりませんが、評価値がおかしい値にはなっていないことだけは確認できました。良かった良かった。これでとりあえず電王戦トーナメントに出場できますね。
■ 2013/10/30 10:40 千日手問題が発覚
やねうら王には千日手を回避する機能があり、探索部で以下のような処理になっています。
つまり、千日手局面を龍の価値分(龍損の半分)の評価値をつけておけば、互角の局面とかなら、千日手手順を自動的に回避するという、そういうhackです。
// 同一局面4回での千日手。 // このチェックをしておかないと下手な探索延長をすると繰り返しで終わらなくなる。 case four_fold_rep: // 自分の手番ならわずかに不利という扱いにしておこう。 // そうすればこの手順は回避するはずだ。 // 置換表上、整合性が取れずにまずいかどうかは知らん…。 // そもそもscore_inferiorだってこれに近い扱いだし…。 if (TURN == tree->root_turn) { // 龍の価値分とみなす。 // ここから逆転勝ちできる可能性は1/2よりは小さいだろうから引き分けで1/2の勝ちが拾えるなら // それは得だろう。 if (Search::avoid_sennichite) best_alpha.value = -DDragon; else best_alpha.value = score_draw; } else { // 相手による千日手も回避したいなら、このスコアを相手有利のスコアにしておくべき。 if (Search::avoid_sennichite) best_alpha.value = +DDragon; // 相手から見て龍の価値分ぐらいの得だとしておこう。 else best_alpha.value = score_draw; } return best_alpha;
ところが、やね裏学習メソッドI(局中に自分の指した手を記憶しておく)をONにしていると、自分の指した手を覚えているので、2回目以降その局面に遭遇するとそれが千日手手順であってもそこに踏み込んでしまいます。
千日手になって下位のソフトと引き分けになることほど馬鹿らしいことはないので、これをなんとかして回避する必要があります。
そこで、指す前に千日手になる手かどうかを判定し、千日手になるのであれば、再探索するようなコードが追加で必要となります。これはこれで結構の改造ですが、いまから…やります…。
こんな改造してエンバグしないといいんだがなぁ…。(´・ω・`)
■ 2013/10/30 15:25 ホテルの予約完了
ホテルの予約忘れてたのでいまやりました。そのあと仕事の電話がかかってきて、応対してたらこんな時間に…。
とりあえずいまから千日手回避のコード追加します。
■ 2013/10/30 15:30 棋譜からの学習は過学習の塊
棋譜からの学習、実戦で出てこない(学習に使っている棋譜に出てこない)形は評価できず特徴因子の値が0になる。(実際は0ではないけど0相当である)
また、実際は無関係なのに関連付けて学習してしまう。一言で言うと過学習である。手でチューンしたら絶対こんな値にならないのに、という値になっている因子がたくさんある。これらを如何にして是正するかが、ボナンザメソッドの課題である。だからこそ、他の開発者は、Bonanzaのパラメーターを可視化したりしていかにしてパラメーターを是正するか考えているのである。(例 : bona6.0の3駒評価の可視化 http://d.hatena.ne.jp/suzume_r/20130904 )
私は過学習は嫌いなので、棋譜との指し手の一致度を上げるより、過学習を抑えるほうに力を入れたほうがいいのではないかという派である。これに対して、棋譜との指し手が一致しているほうがいいという派の人たちも結構見かける。(もしかしたらほとんどの開発者が後者かも知れない)
「一見無関係に思える、端歩と突き捨てとの関係も、その戦型においては意味のあることだから」うんぬん。
それはそれで一理あるのだが、探索が深くなってきたときに副作用を及ぼしかねない部分はバッサリ切り捨てていくほうが将来的なことを考えると正しいアプローチだと私は信じている。この先、10年後ぐらいにPCのスペックが格段に上がったときにこのことが実証される。(といいなぁ…)
■ 2013/10/30 18:00 千日手回避コードが書けた
上で書いた、千日手、探索の途中で中途半端な評価値をつけるアイデアはあまりよろしくなく(置換表上の整合性が取れなくなる)、うまく機能しなかった。置換表の書き出しに対してもうひと工夫する必要がある。
ここを下手にいまいじりたくないので、千日手は100%回避するようにした。千日手を無理矢理回避した結果、不利な局面になって自滅しても、それはそれで仕方ない。
ただ、千日手になった局面を自分の負けとして評価値を設定すると、千日手になりそうな仕掛けは事前に見送るという効果もあるので、早めに不要な探索が打ちきれて良いような気も少しする。
■ 2013/10/30 18:10 旧バージョンと対戦させると…
改良しておかしなバグを仕込んでいないかを検証するために以前のバージョンと対戦させてテストするわけだが、以前のバージョンは秒読みいっぱいまで読む戦略だったし、局中の学習定跡も未実装だったのでDBへのアクセスもしていなかった。それゆえ、0.5秒分ほど得なんだ。
3分切れ負けにおける1手0.5秒ハンデの重みは相当で、たぶんこれのせいで、負け越す。たぶんこれのせいだよ。バグのせいじゃないよ。これのせい、これのせい。
などと呪文のように唱えながら、改良するごとに勝率が下がってくるのを見ていると心が折れそう。
■ 2013/10/30 18:40 テイルズオブハーツRをやりすぎてしまった…
コンピューター将棋の開発はマシンが3台ぐらいしかないと、少しコード書いては1時間テストして、みたいな開発サイクルなので、結構空き時間が退屈である。本当は1日にちょっとコードを書いて寝ている間にテストして、みたいな開発サイクルが一番効率的なのだろう。
そんなわけで大量に空き時間が出来るわけであるが、私の場合、その間に仕事を他の片付けたり、ブログを更新したり、テイルズをやったりするわけである。気づいたらテイルズ、60時間近くやっていた…。いま二周目だが、フルコンプ(?)まであと50時間ぐらいかかりそう。さすがに電王戦の開催時間にはやらないが。(待機時間にはやるかも知れん)
ちなみに、このテイルズオブハーツRと言うゲーム、「デスピル病」という「スピリア」の病(やまい)がゲームの主題となっている。このゲームで「スピリア」とは「精神」のことらしく、それを病んでしまうわけだ。要するに精神の病である。精神病とは違うのかも知れないが、「デスピル病」を「精神病」(あるいは具体的な病名)と頭のなかで読み替えながらゲームを進めるとなかなか味わい深いものがある。
例えば、ヒロインのお母さんが主人公たちを殺そうとしたときも、主人公たちはお母さんを庇って、「デスピル病なんでしょ?だから仕方なかったんでしょ?」みたいに言うわけだ。でもお母さんは結局はデスピル病ではなかったのだ。そのことを知って愕然とする主人公たちに向けた二千年生きている女の子、リチアさん(右後ろの緑の髪の少女)の言葉。
なんか味わい深くないですか?
人の精神は精神疾患でなくても時として暴走し、恐ろしい振る舞いをしてしまうのです。(どーん)
なんでもかんでもデスピル病であるかデスピル病でないかということを基準にしか考えられない主人公たちへの、あるいはゲームのテーマ自体への痛烈な批判となっております。なかなか味わい深いものがありますね。
■ 2013/10/30 20:00 千日手回避のコード
千日手回避のために千日手局面になったところで、score_foul(このへん、定数の意味はBonanzaと同じ)を返すようにしたら、千日手に遭遇したら指し手を返さないようになった。無論、タイムアップまでまっしぐらいである。さっき、対局テストしてたらこの現象になって、冷や汗が出た。ここは、score_inferiorを返さないといけない。
なんか怖くなってきたのでもう改造するのはやめて、今日・明日は動作テストに徹することにします。
皆様、ご祈祷ありがとうございました…。
■ 2013/10/30 20:10 千日手を回避して本当にいいのか?
将棋は意外と千日手になる手順が出てくるゲームであって、馬を作って、飛車を責めるような手順ですぐに千日手になる。その局面を回避しようと思うとそのような手を指させないようにしないといけなくなり、特定の指し手がすべて封じられてしまう。
いわばハンデ戦のようになって、そういう戦い方をするとすこぶる不利なのではなかろうか。
Bonanzaは、千日手による引き分けはscore_draw(±0)として扱ってあり、回避する試みすら感じられない。そのため、千日手になる手順であろうが平気で踏み込んでくる。こっちは千日手にさせないようにいくつかの指し手を封じられているのにまったくたまったもんじゃない。
どう考えてもこちらの戦い方は損である。
■ 2013/10/30 20:20 時間計測の件
大会ルールをいま読んだところ、CSAルールのようで、このルールでは秒未満は切り捨てで正しいようです。
(消費時間)
第 17 条
1 手毎に、実際の消費時間を計測した上で秒未満を切り捨てたものを 1 手毎の消費時間とする。
ただし、ある手の消費時間が 1 秒未満の場合、その手の消費時間は 1 秒とする。
すなわち、計測された消費時間を x 秒、このルール上の消費時間を s 秒と表わすとき、x<2 であれば、s=1 とする。
また n を 2 以上の自然数とするとき、n<=x
将棋所はCSAルールに対応していないので、将棋所の指し手ごとの秒数としては1秒多い秒数が表示されるんですかね。
ということで将棋所では5分+秒読み10秒ではなく、5分+秒読み11秒に設定して対局すると良いということでしょうか。
こんなギリギリのコンマ何秒を稼ぐためにタイムアップと隣り合わせなのは気が進まないですけど…。
■ 2013/10/30 20:30 やね裏学習メソッドIIに関するアイデア
コメント欄でご指摘いただいたのですが、やね裏学習メソッドIIで検討するときに終局図からさかのぼって検討したほうがいいのではないかという点についてお答えします。
私の実装も逆順で検討するようになっています。そのほうが少し得だと思います。詰みが絡むような時には、詰みの値が置換表に書かれているわけですから。
また実装としてはDBに未検討の局面についてqueryかけるときに「手数(初手から何手目か)」でORDER BYでDESC(降順)にすればいいだけですのでこの実装で良ければすこぶる簡単ですよね。
■ 2013/10/30 20:45 やね裏定跡は嫌な予感がする
やね裏定跡による先手勝率は後手のそれよりかなりいい。何故かと言うとやね裏定跡同士だと先手のほうが有利になる変化が多いからだ。
そもそも将棋において後手は1手分損しているはずであり、損しているからには、評価値が少し悪くなって当たり前なわけである。それなのに互角以上だと判断していたソフトは、(たまたま試合には勝てたのかも知れないが)形勢判断がおかしなソフトなのかも知れない。
そういう意味では、やね裏定跡の後手のほうは、結構、損な分かれになっている局面がある。特に嫌なのが先手にストレートに穴熊に組ませる変化だ。か、、勘弁してくれ。この定跡、手で修正してやろうかとちょっと思わないではない。しかしそのためには定跡編集ツールが必要だ。(そのうち作ろう…)
■ 2013/10/30 20:50 置換表のサイズはいくらがベストか?
置換表のサイズはいくらがベストか悩ましい。大きいほうが良さそうだが、大きいとCPU cacheのhit率も下がるわけで、本当に大きいほうがいいかどうかはわからない。特に浅い探索であれば置換表は小さいほうが好ましいはずだ。
しかし深い探索になってくると探索ノード数が増えるので、小さい置換表だとエントリー(登録しようとする局面のデータ)が衝突しやすくなる。そうすると探索効率が低下することになる。
これらのテストをきちんとやるためには、大会用のマシンで、大会用の持ち時間で何百局も対局させるしかないわけであるが、そんなマシンもそんな時間もないので結論はわからない。他の開発者はどう設定してるんだろう…。
大容量のメモリ積んでいるからと言って、最大に近いメモリにすると、置換表のクリア等ですごい時間がかかったり、あるいは、変数のどこかが32bitになっていて4GBを超える置換表だとソフトが落ちたりして…。(笑い事ではないな)
このように置換表のサイズを決めるのも大仕事なのである。早めに行って動作テストしないと…。
■ 2013/10/30 21:15 コンピューター将棋はPGOしたほうがいいのか?
Visual StudioにはPGO(Profile Guided Optimization)という機能がある。実際に実行させて、その統計的な情報により、メモリアクセスのlatencyを隠匿するようなコードにしてくれたり、よく通るほうの条件分岐をnon-jumpにしてくれたりするのである。(たぶん)
一般的なプログラムではPGOにより10%ぐらいの速度が改善することがあるのだが、コンピューター将棋ではPGOはあまり効果がないようだ。Bonanzaでも昔のBonanzaはPGOで3%ぐらい速くなったらしいのだが、いまその話が通用するかどうかすらよくわからない。
当時はICC(Intel C++ Compiler)だと数%速くなるから、最終版のコンパイルだけICCでやるという話を保木さんがされていたのだけど、それも昔の話。いまやVisual C++の最適化もそこそこマシになったのでICCと優劣はほとんどつかないのが実状だと思う。
そんなわけでPGOは今回は見送る。PGOかけて、コンパイラバグってて、大会で落ちるとかシャレにならん。Visual C++もMSDNにはVisual Studio 2013が来ているのだが、いまこのタイミングで差し替えてコンパイラがバグっていても嫌なので私は差し替えていない。
「Visual StudioのRTMは絶対にバグだらけなので、サービスパックがリリースされるまで仕事に使わない」というのが人生を賢く生き抜くためのhackである。(そんな大層なもんでもないか…)
■ 2013/10/30 22:35 今年の反省点
まだ始まってもいないのに反省もどうかと思うが、書くだけ書いておく。
いまのコンピューター将棋は(特に本番環境だと)PCスペックが高くて結構探索が深いのだ。評価関数を改良するということは、大局観を良くしているようなもので、改良すればするほど深い探索においては効果を発揮し、それは勝率として跳ね返ってくる。
ところが、短い持ち時間だと探索が浅すぎて簡単な詰みの見落としとかがあって、頓死をしょっちょう喰らうので実際のところ大局観とかほとんど関係がない。
そのため3分切れ負けでテストして勝率を調べても何の参考にもならない(いろんな局面においてバグがないかというテストにはなるが…)というのが実状なのである。今回の開発期間(1週間ほどしかなかったけど)でそれが良くわかった。
今後、大会のことを考えると、どうしても開発テストのため大会と同じぐらいのスペックのマシンが何台か欲しいわけだ。
ところが、Haswellの8コア版とか来年末発売と言われているし、到底来年の電王戦(開催されるのかどうかは知らないが…)には間に合わない。あと、ハイパフォーマンスなマシンを何台もぶん回したときの電気代も怖い。以前開発していたとき月の電気代が6万円を突破した。読者の方は「やねさんともあろう御人がたかだか6万円ぐらいが何だ」とおっしゃるかも知れないが、6万円を笑う者は6万円に泣くのである。(なんのこっちゃ)
なんにせよ仮想化された計算資源だけ借りられなければこの先やっていけないのである。
しかし、ただで計算資源だけ貸せなどと厚かましいことは言わない。
そこで無料で遊べるオンライン将棋道場の開設である。
専用のソフトを使ってそこで対戦してもらい、その間、コンピューターの計算資源をお借りするわけである。
あ、いや、それって将棋道場でなくても良くね?
そうだ!無料で遊べるオンライン型カードバトルとかにしとこう。あ、無料とは言ってもレアガチャは1回300円な。(嘘)
なんか駄目なアイデアしか出てこない。誰か、コメント欄で素晴らしいアイデアを頼む。
■ 2013/10/30 22:50 Bonanza6に対して勝率6割のBonanzaを作る方法
一つ前の記事で時間配分を台形にする戦略について書いたが、あの台形戦略、以前のテストでBonanzaをあのように持ち時間を変更すると6割ぐらい勝ち越すことがわかっていた。
持ち時間や定跡選択(narrow bookかどうか)によっても勝率が変わるので別に確定情報ではないので話半分で聞いて欲しいのだが、下手に局面の不安定度を求めて持ち時間を計算しても、その時間制御が適切でなければ結局はムラのある読みになっているわけだ。
だから、そういうムラのある読みをするぐらいなら、穴熊なら40手目から本気を出すだとか、横歩取りなら20手目から本気を出すだとか、戦型に応じて時間配分を事前に決めておいた比率分を割り当てるほうがまだ理に適っているのだろう。
そこで、自己対戦を自動で繰り返しその勝率から戦型ごとの時間配分を自動で調整するような、そういうプログラムにすると面白いと思うのだが、先ほども書いたように短い持ち時間でテストしてもあまりその時間配分はあてにならないので、短い持ち時間用にチューンしても仕方がない意味もある。
そういう意味ではなかなか悩ましい。
■ 2013/10/31 00:38 Bonanzaがhangする問題
予選トーナメントの持ち時間の1/5の時間でBonanza6と対戦させようと思ったら、Bonanza6(+ u2b)では秒読み2秒だと投了が間に合わないことがあるらしく、応答がないまま、いたずらに思考時間が過ぎている。(将棋所にはタイムアップを判定して停止させる機能がないため)
某掲示板でも将棋所にタイムアップの判定機能がないと嘆いている人がいるのだが、本当、タイムアップを監視して負けにする機能(設定でON/OFFできることが望ましい)は連続対局させる上では必須である。千日手になって何千手にも及ぶ泥仕合になることもあるし、今回のように思考エンジンがバグっていて対局が終わらないこともあるからである。
何故将棋所の作者はこんなこともわからないのか…。
安定して自動連続対局が出来ないと思考エンジンの開発者は安定したテストが行えず、いたずらに時間を消費し、ひいてはコンピューター将棋の進歩が遅れるのである。
■ 2013/10/31 1:00 将棋所がisreadyを二つの思考エンジンに同時に渡す問題
将棋所のisreadyの実装も首を傾げざるを得ない。それというのも、対戦する二つの思考エンジンの双方に同時にisreadyを送信しているのだ。こんなことをするとその二つの思考エンジンが同時にリソースの初期化(例えば評価関数のパラメータをファイルから読み込むなど)すると、ディスクI/Oが奪い合いになる。
Windowsのファイルシステムはこういうファイルの同時のアクセスのスケジューリングが下手なので、こういうところを並列化すると余計に初期化に時間がかかるようになる。それ以外に、CPU時間も相手の思考エンジンとの奪い合いになる。
isreadyで何らかの思考をさせようとしたときに(例えば局前検討や、局前のデータベースの最適化など)、自分と同じタイプの思考エンジンだと(例えば自己対戦させているとしたら)同時に思考してこれまたCPUリソースの奪い合いになる。
なんでこんなところを並列化するのかと言いたくなる。実際の思考プロセスでは、片方の思考エンジンずつに思考させているわけだから、当然isreadyの初期化も片側ずつ行なうべきなのである。
とまあ、思考エンジン製作者にとって、将棋所では思考エンジンの開発用途として不十分な点が多々あり、ソースコードも公開されていないので改造も出来ず、また作者は自分で思考エンジンを作っている人ではないため、思考エンジンでの必要性をいくら説いたところで無駄なのである。だから、将棋所に変わる、開発者向けのGUIを誰かが作るべきなのである。
将棋所は、将棋ファンが思考エンジンをダウンロードしてきてその思考エンジンで対局して遊ぶには最高のGUIなだけに、思考エンジンの開発者のための機能が不足していることがただただ惜しまれる。
■ 2013/10/31 2:00 トーナメント図
本戦のトーナメント図
http://ex.nicovideo.jp/denou/tournament/rule.html
A,B,C,Dのいずれのブロックでもいいので残れば4位以内であることが確定する。
予選1,2,3,4位のソフトは1度負けても100%の権利で敗者復活に参加できる。つまり予選1〜4位は自動的に本戦2日目まで参加。
逆に、予選で勝ち残って本戦で最短で終わるパターンは予選5〜12位で本戦1回戦負け。この場合、敗者復活がないので1回の対局でお帰りである。(とは言っても持ち時間が双方2時間あるので4時間ぐらいかかるんだが…) 予選が5位〜12位でも1回でも勝てば、敗者復活の権利が得られるから2日目に残留確定。
■ 2013/10/31 2:05 トーナメント攻略
さて、どのブロックがやねうら王にとって一番有利だろうか?
やねうら王より強いソフト(1,2,3と仮定)と当たった場合、勝率は3割だとする。
やねうら王より少し強いソフト(4と仮定)と当たった場合、勝率は4割だとする。
やねうら王と同等のソフト(5,6,7と仮定)と当たった場合、勝率は5割だとする。
やねうら王より弱いソフト(8,9,10,11,12と仮定)と当たった場合、勝率8割だとする。
予選1位抜け→Aブロック代表になる確率 80%
予選2位抜け→Cブロック 80%
予選3位抜け→Dブロック 56%(6と11は6が8割勝つとして、80%×50% + 20%×80% )
予選4位抜け→Bブロック 50%
予選5位抜け→Bブロック 40%
となる。
予選で少しでも上位のほうが本戦で上位になる確率は高くなるようになっており、番狂わせがあまり生じないようにうまく配慮されていると思う。
仮に予選4位のほうが予選3位よりブロック代表になる確率が高いのなら、戦略上、狙って負けるという方法もあるのだろうけど、上の計算によるとわざと負けるのは損っぽい。
ただし、事前に公開されているプログラムが仮にあるとしたら、この状況は変わってくるかも知れない。事前に公開していてそのソフトには100%勝てるとわかっている状況であるなら、そのプログラムと当たるためにわざと予選で負けたほうが得なケースは存在するだろう。まあ、ソロコフが絡むのでわざと負けて狙った順位になるのは至難の業かも知れない。
■ 2013/10/31 2:20 将棋所でBonanza(+u2b)が固まる件
コメント欄でご教示いただきました。
ボナンザが投了時に固まる件についてですが、解決策になるか分かりませんが、将棋所の作者の方がu2b.exeの代わりに使うbonadapterというツールを公開されていますので、使ってみてはどうでしょう。
http://www.geocities.jp/shogidokoro/bonadapter.html
bonadapterについては知ってましたが、u2bをわかりやすくしただけだろうぐらいに思っていたのですが、いろいろ改良されてます。
投了時に停止する問題はもちろん解決されていますし、あと、思考エンジン設定がわかりやすいです。将棋所側の持ち時間設定も守ってくれるみたいですし、これで開発が少し捗ります。またx64環境でSSE4が使えるならbonanza_x64_sse4.exeのほうを実行するようです。なかなか気が利いてますね。
ちなみに定跡がnarrow bookでないほうがデフォルトになっているようで、そのままの設定だと糞みたいな定跡を選択します。これu2bではデフォルトはnarrow bookだったと思うのですが。bonadapter使って、「Bonanza6に8割勝つようになった〜」とか喜んでても、実はnarrow bookでないだけとか、そういうオチもありえます。
ともかく、素晴らしいツールを提供している将棋所の作者に感謝!
■ 2013/10/31 2:45 Bonanzaは入玉が弱い件
Bonanza6をBonanza6と自己対戦させているとよく入玉模様になる。対局条件にもよるのかも知れないけど5局か10局に1局ぐらいは入玉模様になる。
入玉阻止のための金を打っておけばいいだけなのに、Bonanza6はそれすらしなくて入玉模様になる。Bonanza6のfv.bin、あれ玉が4段目以上にいる場合に上空にある敵の金の価値を手で補正してやれば入玉が阻止できるようになって勝率が上がると思う。
本当、つまらないhackだけどこういうの実に効果がある。
Bonanza6のfv.binについては過学習しているところを均して、入玉絡みのところを手で補正すれば3駒関係の本来の力を引き出せると思う。
まあ、これについては来年のやねうら王で成果を…。
■ 2013/10/31 3:50 Bonanzaが強い理由
Bonanzaが安定して強いのは、バグがほとんどないからだ。ソースコードが公開されており、たいへん読みやすいので多くの研究者がソースコードをこねくり回し、その結果、ほとんどの致命的なバグは修正された。私もそのバグ潰しにずいぶんと貢献した。(つもり)
コンピューター将棋はいくつかバグがあっても普通に動いてしまうことだ。探索まわりなんて特にそう。1手詰めがバグっていようが、ほとんどのケースで問題はなく、たまーに、探索の末端でそれが問題となる局面があるとわずかに影響が出る程度だ。
しかし、そのわずかな影響が積み重なって、思考エンジンは蝕まれていくわけである。
そしてどこかの時点で「何故か知らないけど以前のバージョンより弱くなっている」と気づくわけである。
200戦程度自己対戦しただけでは、なかなか本当のところはよくわからない。
結局のところ、思考エンジンは大変複雑であるにも関わらず、その思考にまつわる部分においてバグは限りなく0%でなければならない。これは平均的なプログラマーが一人で開発している場合には到底達成不可能な目標である。
もちろん、ベテランプログラマーにとってもこの規模のソースコードでバグ0%というのは大変過酷な条件なので、StockfishやBonanzaなどなるべくロジック上のバグが0%に近いとわかっているオープンソースなソースコードを参考にしながら、なるべくバグのないプログラムに仕上げるわけである。
それでもバグはたまに仕込んでしまうので、ソースコードをきちんとバージョン管理して、以前のバージョンより弱いと感じたら、以前のバージョンと差分を取り、いままでの修正箇所を順番に追跡し、検証していくような、そういう地道な作業を繰り返しているわけである。
Bonanzaと言うとボナンザメソッドばかりに注目が行くが、バグが限りなく0%。
これがBonanzaの強さの秘訣だと私は思っている。
■ 2013/10/31 13:40 長手数の詰将棋ルーチンは必要なのか
コンピューター将棋の研究の偉大な成果としてボナンザメソッド以外にdf-pn+がある。これは長手数の詰将棋を瞬く間に(?)解いてしまう凄い奴だ。研究成果としてはボナンザメソッドと双璧を成すと言っても過言ではないだろう。
ところが、df-pn+はなかなか実際のコンピューター将棋に採用されない。実装が非常に難しいこともあるし、df-pn+のアルゴリズムについて書かれた論文の説明の仕方が悪く、非常に理解しづらいからというのもある。それとは別に、採用してもあまり勝率が上がらないからというのもある。
Bonanzaでもdf-pn+による詰将棋がソースコード上は実装されているが、1PCのときはたぶんこのルーチンは使わないだろう。
それは、なかなか長手数の詰将棋が出現するような局面にならないというのがあるし、そもそも詰将棋で勝てる局面というのは自分有利な局面のはずであり、そんな長手数の詰将棋に頼らずとも他にも勝ち方があることが多いからというのもある。
また、その「自分有利な局面」まで持っていくために、df-pn+はほとんど寄与しない。寄与しないどころか、詰みもないのに通常探索の時間をいたずらに消耗する、悪玉コレステロールのような存在である。これでは「自分有利な局面」になるものもならない。
このへんは対局条件にもよる。短い時間だと頓死を食らいやすいのでα値を更新したときに3手詰め(Bonanzaのmate3.c)を呼び出すことには意味がある。その3手詰めをdf-pn+に変更することにもたぶん意味があるだろう。
長手数で本当にそんなに頓死するものなのかどうかはそこまで実験する時間がないので私にはよくわからない。そもそも、通常探索でも王手となる手はそれなりに延長されるわけで、1手3秒でも15手詰めぐらいは読める。
持ち時間が長くなったとき、あるいは、マシンスペックが向上したとき、どれくらいの頻度で長手数の詰みの見落としによる頓死を喰らうのか。そこらへんは今後の研究課題なのである。(たぶん)
■ 2013/10/31 13:55 入玉対策
やねうら王は入玉対策をしていない。いまからでもしたほうがいいとは思うのだが、下手にいじりたくない。
持ち時間が短いとするっと上部に逃がしてしまうことはあるのだが、持ち時間が多くなってくると寄せ間違いみたいなのはずいぶん減るわけで、入玉される率自体は下がると思うのだが…。
それでもいまから対策できるものなら…したいのだが…。考え中である。
■ 2013/10/31 14:00 将棋ソフト名
将棋ソフトに動物の名前とか食べ物の名前とかをつけるのが流行りである。(たぶん)
兎(うさぴょん)、ひよこ、クマ、カツ丼などがある。
ひよこ将棋が、プロを打ち負かした場合、
プロ棋士「こんなひよっ子に負けるだなんて…」
カツ丼将棋が、プロを打ち負かした場合、
プロ棋士「こんな食い物に負けるだなんて」
など、プロ棋士としても嫌なものがあるのではなかろうか。
ボンクラーズのときも故米長会長から当初は「(ボンクラに負けるのは嫌だから)プロとやるときはこの名前を変えてくれない」と言われていたらしい。*2
その点、習甦なんか、文字の中に「羽生」の文字が入っているので、「羽生さんに負けるなら仕方ない」みたいとプロ棋士も諦めがつくのではなかろうか。
そういう意味では、「やねうら王」ぐらいではまだまだインパクトに欠けるので、来年は「やねうら神」ぐらいにして、プロ棋士に「神様に負けるなら仕方がない」と思わせる感じにしたらどうかと思っているのだが。(冗談です)
■ 2013/10/31 17:30 TDDでコンピューター将棋のバグは減らせるのか?
コメント欄での質問にお答えします。
> Bonanzaが安定して強いのは、バグがほとんどないからだ。
TDDをやるのと、こういうのを作るのは相性がわるいんでしょうか?
ソースコード上に大量にassertは入れてあって、実行時におかしな挙動になればすぐにわかるようにはなっています。(まともな思考エンジンの開発者ならば)
しかし、TDDでは探索に関係するバグはなかなか見つけられませんね。
探索の深いところの結果が問題になるので、実行時に直接的に落ちるとかそういうわけでもなく、また、探索は少しパラメーターを変更すると探索結果は変わるものなので、探索結果が以前のものとの同一性が問題となるわけではないので、テストパターンの書きようがないのです。
将棋の問題集の問題を解かせて、その解答速度や正答率が落ちていれば怪しいとは言えるでしょうけど、その問題集も何万問もの問題セットがないとあまり意味がないでしょう。100問やそこらやったところで何もわからない(ベンチマーク的な指針にはなりますが)というのが本当のところです。
そういう意味では、何万行も書いて一つのバグも出さないという職人芸的な仕事が要求されます。
平均的なプログラマーにはこれが大変困難なので、探索のアルゴリズムを改良とか、学習アルゴリズムの改善だとか、新しいアルゴリズムを試すだとか、そういうこと以前に、まず将棋ソフトとして完成品に至らないのです。
■ 2013/10/31 17:35 fv.binの改造方法について
Bonanza6のパラメーターの可視化は、スズメレンダラーの人(クマ将棋の作者)がやっているので、さっきその公開されているツールをダウンロードして動作とかソースコードとか確認したのだけど、私が思っているようなツールではなかったでござる。
bona6.0の3駒評価の可視化
http://d.hatena.ne.jp/suzume_r/20130904
やりたいのは、玉の位置およびもう一駒(or ニ駒)をユーザーがインタラクティブに動かして、そのときに大きな点数のつく三駒関係を調べたり、ニ駒を固定しておき、三駒関係の値をgridみたいなので編集したりすることなんです。手でチューニングする上でそういうツールが必須なんです。ホント、お願いしますよ〜、雀ちゃん!(←馴れ馴れしいな!)
■ 2013/10/31 17:45 クラウド開発手法
今回の電王戦に参加する他の思考エンジン開発者でこの時期にブログを更新している人は私以外にはほとんどいないようだ。
私とて、暇だからブログを更新しているわけではなく、ここにアイデアを撒き散らすことにより、面白いと思ってくれる人が集まり、そして大量に人が訪れることにより、秀逸なアイデアがコメント欄に書き込まれ、それを頼りに開発するという、いわばクラウド開発の新しい形をブログを通じて実験的に行なっているわけである。
今回は電王戦不参加になった大合神クジラちゃんであるが、あのアイデアも結局、ソフトおよび作者のカリスマ性やソフトの目新しさ、ソフトの人気などを利用して注目を集め、その力をマシンパワーに転化しようという意味で私と根本的な考えかたは同じなのである。(クラウドファンディングに通ずるものがある。)
今回、ブログコメントで私はずいぶん助けられているので、ブログを書くのに費やした時間よりもらえたコメントの価値のほうが上回るはずである。だから今回ブログを書きながら開発をして良かったと思っているし、読者の方には感謝しているのである。
■ 2013/10/31 17:50 いまから評価関数をいじる!
「お前は一体何を言っているんだ」という感じですが、いまから評価関数を改造します。いじったあと、朝まで200局ほど前バージョンと対戦させてみて、動作が不安定および、勝ち越さないようであればrevert(前の状態に戻す)します。
あらかじに書いておきますが、入玉対策ではありません。
入玉対策は…明日までに何か素晴らしいアイデアが思いつくといいのですが。
■ 2013/10/31 20:35 評価関数の改良が半分ぐらい
評価関数の改良、半分ぐらいソースの改造が終わったところでメールをチェックしたら大量に仕事が来てた。いまから片付けなければならない。ほんと、勘弁して欲しい。
今回、電王戦にやねうらおはカネ目当てで出るのかと言われているが、そうだ。私は金が欲しいのだ。何もいままで開発に費やした分の労力に見合う報酬をくれと言うのではない。電気代だ。いままで開発のために使った電気代を一部でいいから返して欲しいわけだ。
だいたい、Bonanzaのfv.bin(評価関数のパラメータ)にしても当時の最先端のXeonマシンを3ヶ月もぶん回して(それ以前の試行錯誤も含めるともっと大量の時間だろう)作られたものである。つまり、機械学習やら何やらにはお金がかかるのである。仮に最先端のPCで10万時間の計算時間を費やして作られたfv.binがあるなら、何十万円もの価値があるだろう。つまりは、学習させたパラメータファイルに値段がつく時代なのである。
機械学習の結果を直接的に売り買いするようなビジネスというのはあまり聞かないが、そういうビジネスは当然成り立つのである。
■ 2013/10/31 23:50 やっと終わった!(違うほうの仕事が)
評価関数の改善に取り組む。計算が難しくて一発で正解となるコードを書ける自信がないけど…。
紙の上での計算は出来たので、もうちょっと頑張ってみます。
■ 2013/11/01 0:50 将棋所での置換表のサイズ設定について
やねうら王のほう、本番マシンで置換表サイズをどれくらいにしようかと悩んでいたのだが、使える以上、最大サイズにしようと思うに至った。
そのためには少なくとも8GBでうまく動くかテストしておきたい。(どこかでオーバーフローするかも知れないから)
ところが、私の持っているマシンは16GBのものしかない。将棋所で8GBと設定すると、もう片方の思考エンジンにも8GBと設定されてしまい、置換表だけでPCの全メモリを使いきってしまう。(なんてこったい…。)
将棋所はどうして片側の思考エンジンごとに置換表サイズを設定できるようにしてないのか首を傾げてしまう次第であるが、ともかくろくにテストもできないので電王戦トーナメント予選の日に会場でテストしようと思う。
この他にもやねうら王には「会場でテストする」予定の項目はたくさんあって、「これでまともに対局できてたら奇蹟じゃねーの」というぐらいの状態である。でも勝つ。ここから勝つ。勝っていままでの電気代を取り戻す!
■ 2013/11/01 2:45 評価関数の改造失敗した…/(^o^)\
速攻revertした。せっかく書いた5時間が水泡に帰した…。
■ 2013/11/01 2:50 やね裏学習メソッドに対するこだわり
言っときますけど、やね裏学習メソッドにこだわりはないですよ?
だいたい、やね裏学習メソッドだのやね裏定跡だの言っても、そんなものはドワンゴの窓口の人からアピールポイントについて書くようにメールが来たので何か返さないとと思って1分ででっち上げた嘘っぱちである。
その嘘っぱちを1週間ほどの期間で実装できたんだから、嘘から出た実と言うより他ないが、私としてはこのメソッドに全くこだわりも、何の思い入れもないわけである。単に、出来れば面白いだろうなーというレベルのアイデアだったわけである。
この手のアイデアは、誰だっていくらでも出せるだろうし、実装するのも(腕のあるプログラマーにとっては)容易である。思考エンジンの探索部や評価関数の改良と違って試行錯誤がほとんど発生しないから、だいたい期日通りには出来る。
私の場合、間でちょくちょく他の仕事が入ってくるというのと、今回、3年前のソースコード(それも大改造の途中のもの)からのスタートだったので余計に時間がかかったというだけだ。本来なら2日もあれば十分出来て然るべき内容なのだ。
それに対して、思考エンジンとして棋力を上げるための改良は大変だ。丸一年かけても全く改善しない場合だって多々ある。私はそういうのに耐えられそうにないのでささっとコンピューターチェスで成功しているアイデアや、他の分野で成功しているアイデアのみを取り入れて書いてしまうのだが、今回いろいろ試してみて、コンピューター将棋の開発って、本当は大変なんだなと思いを新たにし、そして他の開発者の人たちに敬意を払わなければと思った次第である。
ああ、でも今回の電王戦でいままで費やした電気代はキッチリ返してもらうけどな!ヽ(`Д´)ノ
■ 2013/11/01 3:16 コンピューター将棋、弱すぎるな…
人類未踏の、人外の領域まで達したとかまことしやかに噂されているコンピューター将棋ソフトではあるが、自分で作ってて言うのもなんですが、序盤が弱すぎますわ。
動作テストしてるとよくわかるのだけど、定跡を入れていないと平気で相手に穴熊に組ませて、「形勢互角やで、どや?」みたいなドヤ顔で評価値±0とか出しやがる。0じゃねぇわ、その局面。圧倒的大差だぜ。
こんなのが本当に強いのか。確かに終盤はべらぼうに強いが(入玉以外は)、将棋は終盤だけで決まるゲームなのか?それならそれで、人間側も優勢の終盤を勝ちきるための技術をもっと磨くべきじゃないかと思うわけだ。
コンピューター将棋の終盤には新手筋みたいなのはたくさん隠されている。そういうのを問題集のような形にして、そこから人間が学べば大きく棋力が上達するに違いないのである。
■ 2013/11/01 11:22 Bonanza入玉将棋
Bonanzaは入玉将棋が弱いと言われているが、玉が中段のときに、その上空にある敵の金に点数がついていないのかと思ったら、きっちりついていた。多少変な点数になっているところがないではないが、十分意味のあるスコアリングと言えると思う。
つまり、入玉阻止が悪いのではなく、入玉に対する評価が甘すぎるのだろう。玉が敵陣まで行ったらスコアとしてプラスαすれば一応はマシにはずで、一番手軽な対策はそれだろう。(やねうら王は検証する時間がないのでそれはやっていないが)
あと、KKP(3駒関係)より、まずはKP(2駒関係)のほうでいろいろ問題のある数値がある。KPなら手で編集するのも不可能ではない範囲なので、これについては今後検討する。
いずれにせよ、棋譜の質でも評価関数の精度が変わるが、棋譜の質を上げると棋譜の数が減る。棋譜の数が減ると出現しない特徴因子が出てきて、その特徴因子が未学習のままになる。(その特徴因子の値はほぼ0になる)
それを考えると棋譜の質を上げたほうがいいのか、棋譜の数を増やしたほうがいいのかは判断の難しいところだ。
■ 2013/11/01 11:30 Bonanzaの終盤弱いんですけど
Bonanza6の終盤、他のソフトより明らかに弱い。詰将棋探索がないとか、そんな次元ではない。王手に対して探索延長しているのだけど、ここの条件が甘くて、なんでもかんでも延長しているような、そんな状態になってろくに探索できていない。これでは勝てない…。
王手状態のノード割合
http://d.hatena.ne.jp/suzume_r/20131007
ただ、その分、Bonanzaは序・中盤にそこそこ頑張るので、どっちかと言うと中盤で頑張って、そのあと逃げ切るのがBonanzaらしい戦い方なのだろう。
■ 次記事
電王戦 --- 将棋電王トーナメント --- やねうら王特設ページその3
http://d.hatena.ne.jp/yaneurao/20131101#p1