バリューネットワークの学習を試しているときに試合をよく見ていたらゲームエンジンのバグを見つけた。
UTTTでは前のターンに相手が指した場所に対応するローカルボードにしか指すことができないが、対応するローカルボードがすでに取られている場合はまだ決着がついていないボードの好きな場所に置くことができる。このとき、まだマークされていないマスすべて、つまり、すでに取られているローカルボードにもマークできるようになっていた。
実際のゲームではすでに取られているローカルボードにマークできても戦略上あまり意味はなさそうだが、今回の場合はかなり違いがある。ゲームエンジンでは、ローカルボードの決着判定をする際に[(0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6),(1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6)]という順で確認しており、マークが揃っていれば決着と判定している。つまり、すでに相手が取っているローカルボードがあるとき、そこに自分のマークを置くことで相手より判定が早いラインを取れば、後からローカルボードを奪うことができてしまうようになっていた。
さらに、合法手の数が増えることでMCTSエージェントの強さにも影響が出ていたと考えられる。MCTSエージェントはゲーム木を構築する際に合法手をすべて試すので、プレイアウト回数が固定ならば終盤になる(合法手が少なくなる)ほど深く読むことができるようになっていく。つまり、合法手が本来より多くなっていればその分だけMCTSエージェントも弱くなる。
仕方がないので、ゲームエンジンの修正後に教師データを生成しなおしたら、24時間常に動かし続けて丸1週間かかってしまった。そのデータを使って前回と同じように学習させると、合法手が減った影響か1000エポック時点でaccuracyは50%を超えた。
その際の強さは、1000プレイアウトのMCTSに対して勝率75%程度、5000プレイアウトのMCTSに対して勝率30%程度となっていた。ゲームエンジンの修正前はMCTS5000に対して勝率5割を超えていたので、やはり先述の理由でMCTSの強さは上がっていると考えられる。
legal = [pos for pos, state in enumerate(self.flatten()) if state == 0]
↓
legal = [pos for pos, state in enumerate(self.flatten()) if state == 0 and self.grobal_board.flatten()[pos // 9] == 0]
次回は、改めてバリューネットワークについて考える。まだバグがあったら嫌だな……。
戻る