450 likes | 496 Views
強豪囲碁ソフト「彩」について. 山下 宏 2009年9月11日 機械振興会館. ※彩(あや)と読みます. モンテカルロ法って?. 乱数を使って数値計算を(適当に)行う手法 円周率( π) の計算など ギャンブルで有名なモナコの地名 フォン・ノイマンが命名 …なぜかラスベガス法ではない. モンテカルロ法の衝撃. 1996年 囲碁プログラム「彩」を作りはじめる 2007年 GnuGo が KGS で6級、彩は8級 2007年 10月にモンテカルロ法に移行 2008年 2月、モンテカルロ法の彩が3級に
E N D
強豪囲碁ソフト「彩」について 山下 宏 2009年9月11日 機械振興会館 ※彩(あや)と読みます
モンテカルロ法って? • 乱数を使って数値計算を(適当に)行う手法 • 円周率(π)の計算など • ギャンブルで有名なモナコの地名 • フォン・ノイマンが命名 • …なぜかラスベガス法ではない
モンテカルロ法の衝撃 • 1996年 囲碁プログラム「彩」を作りはじめる • 2007年 GnuGoがKGSで6級、彩は8級 • 2007年 10月にモンテカルロ法に移行 • 2008年 2月、モンテカルロ法の彩が3級に • 12年かけてGnuGoにすら届かなかったのが4ヶ月でGnuGoを遥かに追い越した! • 従来の人間の思考の真似をしていたプログラマには大ショック
モンテカルロ法のおかげで製品化 • 2009年7月に彩が「囲碁世界V」として発売 • ただ最強ではありません。KGSで2級。
最強の囲碁ソフトと対戦するには • 2009年9月18日に発売予定の「天頂の囲碁」 • 思考エンジンはZen(作者は尾島陽児さん) • KGSで初段(日本だと3段程度に相当)
彩の仕組み • 評価関数はモンテカルロ法 • 囲碁知識やパターンを利用 • 木探索はUCT • 従来の局面認識を利用した読む手の絞込み
従来のプログラムの評価 局面が与えられたらそれを分析 右上の黒石は死んでいそうだな… 左下は黒の陣地かな? 黒が9目勝っている
モンテカルロ法による評価 どうやって判断したらいいか分からないな・・・ とりあえず、でたらめに最後まで打ってみよう! 白が15目勝ち
モンテカルロ法を使った囲碁の仕組み 1.乱数で黒石、白石を交互に置く 2.打つ場所がなくなったら終了 3.点数を計算する 4.1. - 3. を何度も繰り返す ※本当に乱数で打っていくと終わらないため 「眼」には打たない、というルールを付け加える。 (実際のサンプルを表示)
9路でのシミュレーション(playout) 初期局面 30手目 終局図
19路でも基本は同じ 初期局面 100手目 終局図
目数差ではなく、勝率、を使う 1 • 1回目は 15目勝った (+15) • 2回目は 20目負けた (-20) • 3回目は 81目勝った (+81) 大きく勝ちすぎ! • 4回目は 10目負けた (-10) • ーーーーーーーーーーーーーーーーーーーーー • 目数差 合計 +66 • 平均 +66/4 =+16.5目勝ち
目数差ではなく、勝率、を使う 2 • 1回目は 15目勝った 勝ち +1 • 2回目は 20目負けた 負け +0 • 3回目は 81目勝った 勝ち +1 • 4回目は 10目負けた 負け +0 • ーーーーーーーーーーーーーーーーーーーーー • 合計 +2 • 平均 +2/4 =0.50 勝率 50%
目数差ではなく、勝率、を使う 3 • 目数差のほうが情報量が多い気がするが、実際に対戦させると勝率の方が強い。 • 「勝率」の利用が 33勝5敗、勝率0.86 • 「勝率」の方が安定した評価ができる! • 100目勝っても半目勝っても勝ちは勝ち? • 勝率と目数差を組み合わせる? • 15目勝ちは +1 + 0.15 、など
従来の彩の局面評価(人間の真似) • 石の死活 • 探索で調べる • 陣地の大きさ • 影響力関数を使う • 石の強さ • 石の連絡 • 陣地の大きさ • 周囲の敵、味方の状況 • 逃げ出せる可能性
影響力関数(陣地の判定) • 石の近くほど点数が高い • 黒石は+、白石はー • 死石は相手の石として計算 • すべてを合計して+なら黒地、-なら白地
陣地の判定の比較 従来の地の評価 モンテカルロによる地の評価 モンテカルロの方が右辺の黒地に評価が滑らかに出ている
石の強さ(生存確率)の評価 従来の評価 モンテカルロによる評価 従来は100%、68%と大雑把。モンテカルロは滑らか。
シミュレーションの精度を上げる • 囲碁知識を利用 • アタリを逃げやすく、石を取りやすく • 3x3の範囲のパターンを学習 • 人間の棋譜から統計を取る • 着手確率を求める アタリ 低確率 高確率
黒石の着手確率 数値が大きいほど着手確率が高い
パターンを利用したサンプル サンプルを再生
単純乱数(上)と囲碁っぽい乱数 単純乱数(上)は途中図がひどい。最後はどちらも同じ感じ
石の強さ(生存確率)での比較 単純乱数 囲碁っぽい乱数 単純乱数は本来生きている石が不安定になっている
局面評価の結果(極端な例) 単純な乱数 パターンを利用 単純な乱数は上下の黒石が接続しているのが分かってない パターンを利用した方がより正しく局面を理解できる
単純乱数と囲碁っぽい乱数の棋力 • 9路盤では100回対戦させて99回囲碁っぽい乱数が勝つ • 19路盤では100回全部勝つ • 囲碁の知識をシミュレーションに組み込むことは非常に効果がある!
9路盤と19路盤での違い • 探索速度 • 9路盤 6300 playout/秒 Core Duo 1.83GHz • 19路番 1600 playout/秒 1 coreのみで • それほど速いわけではない • 9路盤では枝刈しなくてもそこそこ強いものが作れる • 19路盤では可能な手の数が多いため「手をしぼる」作業を行わないとあまり強くできない。
19路盤での候補手の選択方法 • 全ての手に確率を与える • 3x3のパターン • 盤の端からの距離での確率(3線、4線が高確率) • 直前の相手の手からの距離(近いほど高確率) • 連の死活探索の結果 • 「死んだ」石が動き出す確率を極端に下げる • 眼形の急所(中手や欠け眼) • AMAFで評価が高い手 • 上位20手程度だけを探索
得意と苦手 • モンテカルロ法とはいえ万能ではない! • 手順が形によらず強制されるケースに弱い • 隅の死活 • 攻め合い • ぼんやりした判断は強い • 石の連絡 • 石の強さ • 厚みの評価(中で生きられない、中央の地)
以前からの局面評価も無駄ではない • モンテカルロ法に以前からの局面評価を組み合わせると効果的 • 部分的な死活探索 • 眼形認識 • 中手 • 欠け眼の判断 • セキの認識 • 重要な手を素早く抽出できる
シミュレーション(playout)の手順 • 1.全ての可能手から乱数で手選ぶ • 2.自爆する手?(アタリに突っ込む手) • 中手はOK • セキ? • 確率を下げて別の手を選びなおす • 3.着手 • 4.可能な手の確率表を更新 • 5.1.に戻る
可能な手の確率表更新(パターン) 3x3のパターンの更新 今打った手の周囲 確率を上げる 1手前の相手の手の周囲 確率を下げる
可能な手の確率表更新(囲碁知識) 今打った石が1手で取れるか? 今打った石の修正の敵石がダメ2で取れるか? 局面を動かさすに取れるか調べる 自分の石がダメ1(アタリ)にされた 逃げる手(確実に逃げれる手のみ) 自分の石がダメ2にされた 周囲のダメ2の敵石を取りにいく 自分の石がダメ3にされた 周囲のダメ2、ダメ3の敵石を取りにいく 1手前がコウなら埋める 2手前がコウならコウを取り返す 三目中手の形が出来たら中手を打つ などなど
可能な手の確率表更新(その他) UCTで黒Aと打ったときの最善手が白B、の場合、 playoutの中で 黒Aと打った場合、白Bと打つ確率を上げる。 元々死んでいる石が次に生きよう、とした場合に殺す手の確率を上げる。(Aと打たれたらBと打て、という規則を事前に調べておく) (黒は死んでいる) 黒にここに打たれたら 白はここに
Playoutに行く前の処理 今打った手で死んだ石は動かないように (死石のダメに打つ確率を下げる) 今打った手が死石が動く手なら、ちゃんと殺す手の確率を1000倍に(地平線効果対策) セキの場合は自爆しないように確率を0に セキ。黒も白も生きている 水色には黒も白も打たないように
AMAF(AllMovesAsFirst) 1 手の評価速度を速くする工夫(All MovesAs First、AMAF) 仮に黒D5白E7黒E6・・・とplayoutで打った場合に、最初の黒D5と黒E6の順番が仮に変わっても結果は一緒だろう。だから黒D5と打って勝ったのなら、黒E6と打っても勝った、として 計算してしまおう、という手法です。これを拡張してもし黒が 勝った場合、黒が打ったすべての手を「最初に打たれた」と仮定して全部更新してしまおう、という非常に乱暴な手法です。 9路なら半分の50手ぐらいが1回のplayoutが更新できるので 50倍くらい手の評価速度が上がります。
AMAF(AllMovesAsFirst) 2 実際は各手ごとに、「通常のUCBの値」と「AMAFでの値」の2つを持ち、下の用にミックスさせて一番値が大きい手を選びます。 ucb_value = child->GetUcbValue(); // 通常の評価 amaf_value = child->GetAmafValue(); // AMAFでの評価 beta = sqrt(K / (3 * node->visits + K)); // K=100,ミックス定数 ucb_amaf = beta * amaf_value + (1 - beta) * ucb_value; 探索回数が少ないうちはAMAFの評価を重視するように。 Rave(Rapid Action Value Estimate)も同じ意味で使われています
メモリの節約1 • 基本はまだ一度も探索したことのない局面で1回playoutを行う。 • 既に1回でもplayoutを行った局面ではそこで可能な手をどれか選び、その手に対してplayoutを行う • この方法だとメモリを非常に食う
メモリの節約2 • CrazyStoneではある手に対して81回playoutを行った後に、初めて次の局面に移り、そこで手を選ぶ。 • 9路では81回、19路では361回。 • メモリは少なくて済む • MoGoは1回でもplayoutを行ったら、次の局面に移り手を選ぶ。 • どちらが良いかは不明。
playoutを増やしたときの勝率 GnuGo相手に9路盤で
時間をかけると強くなる? • レーティング(強さを点数化) • 100点で1段差 • 100点上がると勝率は0.64上昇 • 2倍の思考時間を使うとレーティングは • 将棋 63点上昇(将棋プログラムYSSの場合) • 囲碁 65点上昇(囲碁プログラム彩の場合) • 囲碁も将棋も同じ程度強くなる • しかし並列化した場合は…?
並列化がしやすい • 将棋 • αβ法は並列効率が悪い • 囲碁 • モンテカルロ法は並列効果がよい! • マルチコア化が進む現在のCPU事情を考えると未来は明るい!
並列化の方法 • playoutのみを並列化 • 探索木の情報を一つのハッシュ表に保存 • 読み書きするたびにロック • A-B-C-D-E と読む場合は、局面Aをロック、アンロック、局面Bをロック・・・と進む • Eまで来たらアンロックしてplayoutを行う
Virtual Loss 1 • 並列の効率を上げるテクニック • 最善応手手順が A-B-C-D-E の時、すべてのスレッドが同時に A-B-C-D-E と読もうとするとロックが頻発して効率が下がってしまう。 • そこで最初のスレッドはAの手を選んだとき、この手を「1回負けた」として点数を下げる(後で戻す) • 同様にB,C,D,Eでも下げる。 • Dの手とFの手が同じくらいだった場合は、2番目のスレッドはA-B-C-F-G とFの手を選ぶ。
Virtual Loss 2 • こうして別の手を探索しやすくなることによりロックの回数が減って効率が上がる。 • シングルスレッドと比べて本質は変わってしまうが影響は小さい。