前回強化学習の仕組みを作って実際に学習を回してみたところ、Mjxに実装されているShantenAgentと同等の強さまで学習することができた。 ShantenAgentはロン、ツモ、立直ができるときは必ず行うが、それ以外の副露はランダム、牌を切るときはシャンテン数が小さくなる牌の中からランダムで切るというルールベースエージェントである。
ShantenAgentに勝つ
前回の記事では改良ポイントの候補として「リーチがかかったら安全牌を切る(=降りる)」「基礎的な牌効率」を挙げていたが、そのうち安全牌についての情報を特徴量に入れてみることにした。(入れ方に工夫の余地はあるが、手牌の情報は元々入っているため理論上は牌効率を学習できると思っている)
自分の手牌のそれぞれの牌が各プレイヤーに対して安全かどうか(そのプレイヤーの捨て牌+同順内フリテン+立直後の他家の捨て牌)の情報を特徴量に加えて、さらにモデルのサイズやバッチサイズも調整してみたところ、結果は以下のようになった。
学習環境は前回と同じだが、今回は12時間学習してみた。概算で約10万半荘ぶんのデータを学習しており、モデルファイルのサイズは現状10MB程度になっている。
約5時間を過ぎたころからShantenAgentの平均スコアが25000を下回り始め、そこから少しずつ減少しているのが確認できた(もしかしたら前回も学習を止めなければこうなってたかもしれない)
最終的に16000付近まで下がっており、このまま続ければまだ下がっていきそうな感じもある。
実際のところShantenAgentの牌譜を学習して同等の強さになること自体は強化学習というより教師あり学習に近い話であり、そこからさらに強くなっていけるかが重要だと思っていたので、うまくいっているところを確認できてよかった(小並感)
対局を見てみる
強くなっていることは分かったが、現状何ができていて何ができてないのか、人間のプレイヤーと比べて実際どの程度強いのかということはスコアの推移からはあまり見えてこない。
ゲームエンジンとしてMjxを使うメリットの一つに良質なビジュアライザの存在がある。 Mjxでは各局面のオブジェクトから盤面の画像を生成する機能があるので、この機能を使って実際に対局を見てみることにした。 学習したモデルどうしで東一局を6回やってみたところ、それぞれの最終局面は以下のようになっていた。
意外と満貫とかを上がっているのは面白いが、よく見てみると最初に端牌から切るという意識が希薄で、他家のリーチに対してなんとなく安全牌を切っているような感じもあるがよく分からない。
明確に良くない点としては副露の使い方が挙げられる。 門前の価値を低く見ているようで基本的に鳴きを多用しているが、役がなくなる副露が多いのが気になる。おそらく鳴きを連打して、運が良ければ上がれるゲームだと思っているのだろう(スーファミの『スーパー麻雀大会』をプレイする8歳の僕と同じである)
学習時に役というものの存在を一切教えていないため、こうなるのは極めて妥当といえる。自分の手牌は見えているのだから原理的には役の存在に気づいてもおかしくはないが、現在のモデルの構造から考えても難しいだろう(三元牌の対子/刻子の登場率が高いので、いちばん簡単な副露役である役牌は理解しているかもしれない)
今後
とりあえず明確な改善点として、役のなくなる副露をしないように学習させたい。
高級な構造のモデルを使えばある程度学習できるのかもしれないが、どちらかというと役を学習できるように直接的にサポートするほうがうまくいきそうな感じがする。 たとえば、現在は局の終了時に自分の点数の差分だけを与えているが、自分の最終的な手牌になんの役があったか(もしくはなんの役もなかったか)という情報を与え、これも同時に推論させるというアプローチが考えられる。 そのためには役の判定を書く必要があり面倒だが、とりあえずは出現率の高い副露役だけを書くのでも十分かもしれない。
まとめ
- 安全牌の情報を与えて長く学習させると、ShantenAgentより明確に強くなった
- 対局をビジュアライズしてみると、役のなくなる副露が多かった
- 役を学習させられる方法を考えたい