2008年コンピュータ将棋選手権準優勝記

by 棚瀬 寧


 

いまさら感あふれるが、別に記事を依頼されていてそっちを結構頑張って書いたのでこっちはざっくりと。

1年間でやったこと

正直今年はほとんどコンピュータ将棋のプログラムを書いた気がしない。実際難しいことは全く書いていない。
大雑把に言うと、簡単なことを少し実装、結果を待つ、の繰り返しの1年だった。
ただ1年前とは違ってプログラムの基盤は出来ているので、たくさんプログラムを書かなくては強くならないというわけでもないはず。

そんな1年でやったことを具体的に振り返ると。。
前半は主に探索関係で色々設定を変えたりちょっとしたことを実装したりして自己対戦で検証。
はっきり言って全くと言っていいほど成果なし。当初はまだ新しいプログラムだから何をやってもぐんぐん伸びるのではないかと期待していたのだが、さすがに元々強いプログラムを改良するのは難しいものだと再認識した。
ただ、この自己対戦の過程で詰んでないのに詰んでいると言ったバグを発見して修正できたので意味はあった。

細かいことではVS2005を購入した。
去年はVS2003を使っていたが、コンパイラにバグがあり(符号付16ビットシフトで間違った最適化がされることがある)、スピードを少し犠牲にして回避していたのだがその必要がなくなった。
これで少しスピードアップ。
本当はPOGとかいう実行時のプロファイルを使って最適化をする機能を使う予定で購入したのだが、今日に至るまで結局ためしもせず。
ちなみにVS2003からVS2005の移行ではコンパイルエラーが死ぬほど出て一度はあきらめかけたほど。
templateを多用しているとコンパイラ間の仕様の差にほんとに苦労する。
同時期に、岸本がlinuxで使える実行時のメモリリークや未初期化メモリの参照といったチェックをしてくれるvalgrindというツールがえらく便利だというので、g++でコンパイル出来るようにもしたのだが、これも恐ろしく苦労した。
g++は全く意味不明のエラーメッセージが出力されるのだ。
例えば
a.hoge<P>()
というような記述を
a.template hoge<P>()
にしないとエラーが出るとか、
class A {
 static const int a = 5;
};
というようなのを
f( A::a ) という具合に使う場合に、fの定義が f( int& x ) と学習の関係で参照になっているのがなぞめいたリンクエラーを誘発したりとか、valgrindを使いたい一心だけで我ながらよく頑張って解決した。

しかし、valgrindはというと、私のプログラムには何の問題も検出されず苦労した割りに何も得られなかった。残念。

というような状態で11月のGPW(@箱根)を迎え、「いやあ全然進歩してないです」というようなことを言っていたと思う。
GPWから帰ってきて、私は遅刻して出てないのだがfutilityの話があった(動的に調整するという話だったと思う)ので、試みに適当にfutility pruningを行う条件を緩くしてみて5秒将棋で自己対戦してみたところ.560くらいの勝率が出て、初めての成果と喜んだもののちょっと疑わしいのでさらに10秒将棋で自己対戦させてみたところ、案の定.520くらいに落ちた。
前向き枝刈りもそうだが、こういういい加減な話は超早指しでそれっぽい手を速く見つけるのには役立つが、思考時間が長くなるにつれて段々と効果がなくなり、そして逆効果になるのだと思われる。
この件以降、探索で細かい調整をするのが馬鹿らしくなって、評価関数に関心が移っていった。
以来、現在まで評価関数に思いつくままにfeatureを加える作業を行ってきた。
100種類以上は加えたと思う。
ちなみにプロ棋譜との一致率も徐々に上がり、1年前の36%くらいから38.6%まで伸びた。(大差がついたら打ち切ったりするので他のプログラムとの比較は難しい)
1手読みではこれくらいが限界に近いのではないかと喜んでいた。
ところが、4月くらいになって出来上がったパラメータを組み込んで私自身が対戦してみて、時々なんだか変な手を指すようになっていることに気づいた。
以前からプロの棋譜を表面的にまねても強くなる保証はないとはよく分かっていたのに、全く検証もせず一致率を上げるというゲームにはまりすぎた。
やばい、と思い色々とBonanza式学習の弱点となっている部分を回避する方策を適当に考えては、再学習ということをあわてて繰り返したのが最後の1ヶ月。
この頃は購入してあった8コアのMacProが学習に役立った。
ちなみにこのマシン54万円と廉価なので(笑)お勧めである。
ちなみに前回YSSに必勝の将棋をコンピュータとしてはありえない頓死を喰らって負ける原因になった部分は、今大会の直前の5月になってから直した。
バグというよりも私の手抜きが原因で、その部分には以下のコメントが書かれていた。。。
// TODO: 今は適当にやっておく

5月3日に会場に隣接するホテル入り。
そこで去年に引き続き通称ドーピングを少々行った。
以上が1年間のあらまし。

結局1年間でプログラムがどう変わったかというと、
・細かいバグがいくつか発見・修正された
・探索は少しだけいじった程度
・評価項目はだいぶ増えた
・プロの物まねは去年よりうまくなったと思われる
・駒の価値が去年よりも正しくなったと思われる
・ドーピングがほとんど必要なくなった

駒の価値について。
原因は不明だが、昨年大会バージョンでは持ち駒の1枚目の歩を1とした時に1枚目の桂馬がたった1.8くらいに学習されていた。香車も同様に低かった。
道理で桂香損を厭わなかったはずだ。(二次予選のK-Shogi、激指戦、決勝の竜の卵、激指戦などにはっきりと影響が見える)
また、バグにより相手陣の飛車=飛車の基本点+歩の価値、相手陣の角=角の基本点+歩の価値、という変な制約が入っていた。
イメージ的には相手陣の飛車は竜に近く、通常の飛車の価値よりも1歩以上価値が高く、逆に相手陣の生角はそれほど価値がないものと思われ、現在はそうなっている。
これらの改善は明らかにプラスに働くはず。
とはいえ、去年も十分選手権で通用していたわけで、将棋では駒の価値は適当でも何とかなるものなんだなということが分かる。

で、実際に強くなったかどうか。
上に挙げた事実から恐らく強くなっているだろう、ということしか言えないのが現状である。
何しろ1年間、私のプログラムは私以外の人間及び他のプログラムと、一度も対戦させていない上、昨年バージョンとの対戦もさせていないのだ。
さらに、5月5日の決勝に臨んだ棚瀬将棋は、直前の明け方まで学習させた出来たてほやほやのパラメータをそのまま利用したため、まさに完全ノーチェック状態であった。

 

大会

今年は決勝シードだが1日目から会場入りして1次、2次ともに結構観戦した。ホテルの部屋に戻ったり会場に戻ったりかなり往復したが。(これが隣接しているとは言え微妙に距離がありいい運動になる)
印象的だったのは2次での大槻-TACOS戦で楽勝に見えた大槻将棋がTACOSに食いつかれて危ない局面を迎えたとき。
大槻さんが頭痛にでも悩まされているかのように、険しい顔で目をつぶり、とても話しかけられないような雰囲気になっていた。
彼も巨大掲示板などで期待されて、プレッシャーを感じていたのではないかと思う。あるいは本当に頭痛だったのかもしれないが。

というわけで迎えた決勝。
今年はいきなり決勝からなので去年よりも緊張した。
全敗するのではないか、などと考えてしまうのもIS将棋時代に何度も経験したことである。

1回戦。奈良将棋戦
奈良さんは個人的に応援していたのでやっと決勝進出を果たし、私も嬉しかった。
ただ2次予選最終戦の結果的に勝った方が決勝に進むことになった習甦-奈良将棋戦は筋違い角の面白い戦いになりそうなところでいきなり終わってしまったので残念だった。
本局、こちらが振飛車で相手が居飛車穴熊。
これだけで嫌になるが何となく勝利。

2回戦。備後将棋戦
またもこちらの振飛車に相手の居飛車穴熊。
しかも向飛車でこれは勝ちにくいと思ったが、なかなか味のある指し方で快勝。
備後将棋は本局に関してはあまり内容がよくなかったが、他の棋譜やfloodgateなどで見る感じでは、4強にかなり近い位置に来ていると思う。

3回戦。大槻将棋戦
今度は大槻将棋が振飛車穴熊でこちらが居飛車穴熊。
戦形だけで勝った気分で実際快勝。
大槻将棋は将棋倶楽部24でレーティング2700近くと怖い存在だが、本局は力が出せない形になった。

4回戦。Bonanza戦
Bonanzaの振飛車穴熊にこちらは居飛車穴熊。
Bonanzaが竜を作る代償にこちらが桂香のもろ得。
低い陣形で竜に対して強い形だし、さすがにこの交換はこちらが相当得をしたと思うのだが。
一見怖い形になったが、本局のBonanzaの攻めは高い駒(竜)が先頭に来る攻めなので絶対受けきれると信じていた。
最後はギャラリーから早くから決め手として予想されていた△6五角打が出て勝利。
週刊将棋や将棋世界では大きめに取り上げられたが、個人的な感想としては若干淡白な一戦。

5回戦。柿木将棋戦
棚瀬将棋の振飛車に柿木将棋の居飛車穴熊という展開。
ほんとにこのパターンは嫌である。
しかも棚瀬将棋が駒得に目がくらみさばき合いに行ってしまい、いかにも危ない局面を迎えた。
実際途中で△5七と、と柿木将棋に突進されていたら負けていたことを後で確認した。棚瀬将棋自身この手を指せないようだったし、まだまだである。
本局は本大会で一番危なかった一戦だと思う。

6回戦。激指戦
運命の一戦。
未だにこの将棋の棋譜を見ることが出来ない。
それでも強烈に記憶に残っている。
悪手もあったかもしれないがあの複雑な大乱戦を激指相手に勝ちまで持っていった棚瀬将棋は強かったと自分でも思う。
本来なら何度も並べ返したくなる棋譜になるはずだった。
結局時間切れの原因は何だったのか。
これは大会後1ヶ月近く経ってから原因がやっと判明した。
大会の時はサーバの時間を取っていなかったためローカルでの計測と差が開いてしまったと思ったし、将棋世界等にもそう書かれた。
しかし、その辺りはGPW杯の時にちゃんと対応していた。本局の最後も時間が切迫していることを認識していた。
実際の原因はなんと「スレッド間の優先度の差」だった。。
どういうことかというと、思考スレッドと、サーバからの指し手の通知を待つスレッドがあり、サーバからの指し手を待っている間も思考スレッドは動いているが、指し手が通知されると思考スレッドにその旨伝える。
ところが、選手権当日は私の不注意で思考スレッドの優先度が指し手待ちスレッドの優先度よりも高くなっていて、これだけのことで毎回指し手の通知が3、4秒程遅れるのだ。
つまり思考スレッドとしては10秒で指したつもりでも大体14秒としてサーバには記録される。

この程度ならまだしも、長手数になった激指戦では最後思考スレッドは1秒で指しているつもりが思考開始が遅れて4、5秒ずつ計測されてしまった。(そもそも本来ならあれくらいの手数で1秒で指さなくてはいけない状況にはならない)
これは致命的だった。残り時間が一気に減って行った。

7回戦。YSS戦
時間切れの原因が分からないまま、結局持ち時間を22分にするという対処療法で臨んだ。
YSSが不出来な内容で、ぼーっと見ているうちにぼろ勝ちになった。

 

エキシビション

結果6-1の2位となり2003年以来のエキシビションに臨めることになった。
棚瀬将棋の相手は加藤幸男アマ。
加藤さんはこれまで公式の場でのコンピュータとの対戦(激指,Bonanza×2,YSS)に全て勝利を収めてきている。
対局前はまだ少しぼーっとしていたため、勝算とかは何も考えず淡々と試合の準備をした。
本局については色々なところに書かれたので細かいことは略。

勝負が微妙に揺れ動いたのが34手目に加藤さんが△4二玉と指したとき。この手を見て解説の村山五段が「普通は△5二金ですけど次上がれば同じですか」というようなことを言った。その言葉どおり棚瀬将棋は定跡データベースから離れた。36秒考えて▲3七桂。加藤さんは△5二金とそこで指したものの、既に微妙に過去のプロの実戦例にない局面になっていたようで、以降データベースに戻ることはなく想像もしなかった急激な展開に突入していった。

勝利したことで嬉しい気持ちは全くなかった。むしろ悲しい気持ちしかなかった。
2局目の清水上-激指戦の終局近くに一緒に観戦していた山下さんが、会場に包まれた悲しい雰囲気が97年のKasparov対Deep Blue戦とそっくりだと言った。(山下さんは実際ニューヨークまで観戦に行っている)
実際終局時の拍手も弱弱しかった。昨年とは明らかに違った雰囲気だった。
大会後、当日会場で観戦していた中川七段が棚瀬将棋が加藤さんに指した▲7七桂を公式戦で採用したことを知った。これはとても嬉しかった。


おわりに

2年連続の不運な準優勝…、というのはあくまでも表面的な結果にしかすぎない。
実際、現在のコンピュータ将棋の決勝のレベルにおいて、今の棚瀬将棋の実力から期待される勝ち数は明らかに6もないだろう。恐らく4.5勝くらいが実力だと思う。
それがものすごい幸運で2年連続で7勝全勝をほとんど掌中にするところまで行った、がそこからはすごく不運だった。
今大会はアマトップにソフトが2連勝したことにより様々なメディアで報道され、コンピュータ将棋界にとってそれなりに歴史的な一日だったことは間違いない。
もし最終戦YSSに負けていたら、あの場に私はいなかったわけでそれこそ想像するだけで身の毛もよだつ悪夢である。
やっぱり私は幸運である。

私のプログラムはまだ新しく、これからまだいくらでも強く出来そうな気がする。
今は前向きな気持ちでいっぱいである。
これからもまた、明るく楽しく棚瀬将棋と向かい合っていきたい。