機械学習周りのプログラミング中心。 イベント情報
ポケモンバトルAI本電子書籍通販中

汎用行動選択モデルの3vs3対応 part03 バトルログ可視化ツールの作成【PokéAI】

従来、AIによるバトル中の行動を定性的に確認するには、シミュレータの出力する機械向けのログを目視で必死に解読していました。例えば1ターンの進行を表すログはこんな感じです。

|
|split|p2
|switch|p2a: Azumarill|Azumarill, L50, M|206/206
|switch|p2a: Azumarill|Azumarill, L50, M|206/206
|move|p1a: Corsola|Earthquake|p2a: Azumarill
|split|p2
|-damage|p2a: Azumarill|169/206
|-damage|p2a: Azumarill|169/206
|
|upkeep
|turn|2

ツールの概要

毎回解読するのは手間なので、可視化ツールを作成することにしました。 バトル1回の各ターンの行動選択およびターンの経過を1つのJSONにまとめて保存し、それをWebブラウザ上で表示する簡単なものです。 JSONの生成まではpythonで行い、表示部分はTypeScript+Reactで実装しました。

対戦ごとに、まず対戦パーティの情報を表示し、次に各ターンの行動選択と出来事を表示します。下図に例を示し、赤い文字で説明を加えています。

f:id:select766:20210204203853p:plain
可視化ツールの見方(対戦パーティ情報)

f:id:select766:20210204203914p:plain
可視化ツールの見方(ターンの行動選択と出来事)

レイアウトは美しいとは言えないですが、文字列のログをそのまま読むよりはかなり改善しました。

可視化結果

実際の行動例を示します。前回最善だった64チャンネル3層のモデル(id: 6ee)を使い、レーティングバトルで最も強かったパーティについて観察しました。

レート: 1925, ID:5f8ac014906132f1650ad6ee+5f633609975eefc2110a5a0d
ラプラス,55,,すてみタックル,れいとうビーム,なみのり,ずつき
エレブー,50,,かみなりパンチ,はかいこうせん,れいとうパンチ,かみなり
キングドラ,50,,どくどく,すてみタックル,なみのり,とっしん

次の例では、エレブーの相手がサンダースの時はどの技でもQ値は似ていますが、相手がマリルリになると効果が抜群な電気タイプの技のQ値が高くなっています。タイプ相性を把握していると考えられます。

f:id:select766:20210204205029p:plain
行動例

次の例では、ラプラスの相手がサンダースで、相性が悪いです。しかし最初のターンでは交代せず、ダメージを受けた次のターンで交代しています。交代をうまく使えているとは言いにくいです。

f:id:select766:20210204205303p:plain
行動例

次の例では、ラプラスの相手がレアコイルで、相性が悪いので交代しようとしています。キングドラに交代し1ターン攻撃した後さらにエレブーに交代するという挙動をしており、戦略が迷走しています。

f:id:select766:20210204205621p:plain
行動例

このパーティが強いのは、ラプラスれいとうビームの通りが良いからというのが主な理由だと思われます。3vs3バトルでは交代という行動が増えた点がポイントですが、それを有効に活用できているとはいえない結果でした。

次回、学習方法の改善を試みます。

P.S. Photoshopの勉強を始めたので、スクリーンショットに文字を書き込むのに使い始めました。この程度だとまだペイントと変わらないですが。

DNNの方策に従来型エンジンのbestmoveをブレンドする 実装編 part02【コンピュータ将棋】

前回、dlshogiのDNN評価と同時にelmoを呼び出し、bestmoveを取得して利用する最低限の実装をしました。その結果、無改造のdlshogiだと2500nps程度出るところ1900nps程度まで下がるという結果でした。今回はこのnps低下の原因究明と改善を行い、無改造のdlshogiと対戦して比較します。結果からいうとレート+70程度の改善になりました。

elmoの探索にかかる時間

elmo (探索部はやねうら王)にランダムな局面を与え、一定ノード数の探索をさせた場合の所要時間を測定しました。pythonからプロセス間通信を用いてpositionコマンドで(互換局面集から抽出した)ランダムなSFENを与え、次にgoコマンドをbyoyomi 100をつけて発行します。エンジンのオプションは、Threads:1,EvalHash:16とし、探索ノード数を表すNodesLimitを変えて所要時間を測定します。

NodesLimit 1回あたりの実行時間[ms]
10 0.14
100 0.20
1000 1.1
10000 10

結果は上の表のようになりました。ノード数1000だと1.1msかかるため、2プロセス並列で動作させれば(1000ms/1.1ms*2プロセス=1818なので)1900npsになるのはほとんどがgoコマンドの処理時間であり、dlshogiとpython間の通信のオーバーヘッドは小さいと考えられます。また、1000ノードから10000ノードでの所要時間はおよそ10倍になっており、pythonとelmo間の通信のオーバーヘッドも少なく、実際の探索にかかる時間が大部分と考えられます。そのため、プロセス間通信関係を高速化するメリットは少ないと思われます。なお、ノード数100, 10の場合は所要時間が線形には減っていません。1000ノード以下を指定しても探索が正確に少ないノード数で停止しないことと、プロセス間通信のオーバーヘッドが表れているものと考えられます。

以上のことから、dlshogi上のnpsを増加する手段として、並列に動作させるプロセス数を増加させる必要があります。前回時点の実装では、dlshogiの探索スレッドとelmoのプロセスが一対一対応していたので2並列での動作になっていました。今回は、python上の実装を変更し、リクエストをキューに蓄積して4つ(CPUのコア数)のelmoプロセスに割り振る機構を実装しました。実装の結果、無改造のdlshogiだと2384npsのところ、elmoを呼び出してbestmoveを利用する実装が2220npsまで高速化しました。もともとdlshogi自体がCPU使用率30%程度なのでコアの取り合いになり、これ以上の高速化はCPUのコア数を増やさない限り難しいでしょう。

強さ比較

dlshogiとの実時間での比較

1手1秒で、無改造のdlshogiとの比較を行いました。これで勝っていればnps低下があっても読み筋のブレンドに効果があるといえます。dlshogiのバッチサイズは16固定、elmo側の探索ノード数は1000で固定しています。

policy比率[%] value比率[%] 勝-負-分
0 0 44-51-5 (46.5%)
1 0 46-48-6 (49.0%)
2 0 46-50-4 (48.0%)
5 0 59-39-2 (60.0%)
10 0 52-44-4 (54.0%)
20 0 38-62-0 (38.0%)
5 2 52-43-5 (54.5%)
5 5 52-45-3 (53.5%)
5 10 51-41-8 (55.0%)

結果として、policyにelmoの読み筋を5%ブレンドしたものが最も強く、無改造dlshogiに対してレート+70程度となりました。有意に強くなったのはこのパラメータのみです。valueブレンドについてはマイナスの効果しか得られませんでした。

elmoとの比較

elmoと1手1秒で比較しました。ブレンドdlshogiのパラメータは、前の節で最善だったpolicy5%, value0%です。

測定対象 基準 勝-負-分
無改造dlshogi elmo 122-369-9 (25.3%)
ブレンドdlshogi elmo 68-227-5 (23.5%)
ブレンドdlshogi 無改造dlshogi 226-162-12 (58.0%)

elmoとの比較では、ブレンドしたほうが若干勝率が低いという結果になりました。統計的に有意とは言えないですが。dlshogi同士の対局数も増やしたところ、こちらではブレンドしたほうが有意に強いという結果は変わりませんでした。 ソフト同士の相性があるのか、elmoとのレート差が大きくてうまく測れていないのかよくわかっていません。

現状、対戦相手として使用したelmoと、dlshogi内部で呼び出すelmoが同じ評価関数なので、今後別の評価関数についても試したいと思います。

DNNの方策に従来型エンジンのbestmoveをブレンドする 実装編 part01【コンピュータ将棋】

ブレンドのアイデアを実際の対局エンジンに実装して評価を進めていきます。

dlshogiを改造して実装することにしました。昨日時点の最新版dlshogi cc722f5b2362b0364af063f008a5d922aa8c266eから分岐したこちらのブランチに実装していきます。 GitHub - select766/DeepLearningShogi: dlshogiの改造実験 https://github.com/TadaoYamaoka/DeepLearningShogi

やりたいことは、DNNの評価中に従来型エンジンで同じ局面を探索し、最善手と評価値を得て、それをDNNの出力にブレンドすることです。 まずはこのアイデアを極力シンプルに実装しました。C++力が低いので書き方が安定していないのはご了承ください。

https://github.com/select766/DeepLearningShogi/compare/d579c3009b9f5760c259e8a00198047cd9dbb8de...9df1086bb0af0954f3b6ff644c2af5f36a7a8be8

実装概要

  • dlshogi探索部でDNN評価すべき局面をキューに追加する際、その局面のsfen文字列も別のキューに追加
  • dlshogiがDNNのバッチ評価を行う直前で外部評価プロセスにsfen文字列の集合を送信
  • dlshogiがDNNのバッチ評価を行った直後に外部評価プロセスから評価結果を受信し、結果をブレンド(線形補間)
  • 外部評価プロセスは、TCPでdlshogiと連携、USIプロトコルで従来型エンジン(やねうら王)と連携
    • dlshogiから来た局面を、positionコマンドでやねうら王に送信、goコマンドで思考、infoコマンドで評価値を取得、bestmoveで最善手を取得
    • dlshogiの探索スレッド1つ(=1 TCP接続)につき1つのやねうら王プロセスを起動

動かし方

dlshogiのブランチをビルド、将棋所に登録。オプションとして、Blend_Ratio_Policy(外部エンジンのpolicyブレンド比率%(0ならDNNのみ))、Blend_Ratio_Value(外部エンジンのvalueブレンド比率%(0ならDNNのみ))が追加されているので設定。

同じマシン上で、評価用プロセスを起動させておく。

python -m searchblend.searchblend path\to\YaneuraOu\YaneuraOu_NNUE_tournament.exe --options Threads:1,EvalHash:16,NodesLimit:1000

強さの評価

無改造のdlshogiだと手元の環境で2500nps程度出るのですが、今回の実装では1900nps程度まで低下しました。この原因は今後調査することとして、ブレンドそのものの効果を測定しました。ブレンド比率0の場合でもやねうら王の結果に0を掛けて捨てることによりnps低下による棋力低下を無視しています。dlshogiの評価関数にはGCT(電竜戦2020)を用いました。

従来型エンジンは、やねうら王4.89、elmo2019評価関数(NNUE)、エンジン設定はThreads:1,EvalHash:16,NodesLimit:1000となっています。

ブレンド比率0のものを基準とし、互換局面集を開始局面とし、1手1秒で勝率を測定しました。

policy比率[%] value比率[%] 勝-負-分
10 0 61-36-3
0 10 43-53-4
10 10 60-34-6
50 0 32-65-3

結果は、policyに10%だけ従来型エンジンの出力を足したものが最も強く、DNNだけの評価より強くなることがわかりました。policyを50%足すのは過剰のようで、弱くなりました。valueブレンドについては有効性が確認できません。fail low/highが発生していても、とにかく最後のinfoメッセージの評価値を使っているのがまずい可能性もあります。評価値の利用はスケーリング等厄介な問題が多そうなので、深追いはしません。 今後は、nps低下を抑える実装を検討します。

DNNの読み抜け例を観察する【コンピュータ将棋】

前回、DNNの方策に従来型エンジンのbestmoveをブレンドすれば読み抜けが減らせるのではないかというアイデアを示しました。

select766.hatenablog.com

このアイデアが成立する条件として、DNNで1局面を評価するのと同程度の時間従来型エンジンに手を読ませたときに、DNNが見落とした(確率を非常に低く見積もった)にもかかわらず最善の手を発見できることが必要です。 探索速度を手元の普通のPCで測定しました。CPUはCore i5-7600K(物理4コアHTなし)、GPUNVIDIA GTX 1060 6GBです。従来型エンジンにはelmo(2019年、評価関数はNNUE型)を用い、DNNを用いたエンジンにはGCT(電竜戦2020)を用いました。elmoは8スレッドで動作させ、300万nps程度でした。一方GCTはバッチサイズ16で動作させ、2500nps程度でした。バッチサイズ128だと3000nps程度出ますが、1手1秒でelmoとGCTを対局させた際、バッチサイズ128だとelmoが100%勝利する状況でした。バッチサイズ16だとelmoが80%勝利するという状況で、こちらのほうが強かったため採用しています。この実験環境では、GCTで1ノード評価する間にelmoは1000ノード程度探索が可能といえます。もちろんこの比率はCPUのコア数、GPUの性能により容易に10倍程度の変動が生じます。

まずはGCTが読み抜けを起こすような局面を探す必要があります。GCTとelmoを1手1秒で対戦させ、棋譜と同時に評価値を記録しました。その結果、下図のような評価値グラフが得られました。グラフから自動的に読み抜けを発見する数式はまだ構築できておらず、目視で読み抜けと思われる事例を抜き出しています。

f:id:select766:20210115220026p:plain
GCT-elmoの評価値グラフ

値はelmo(この対局では先手)側から見た符号に合わせてあります。60手目付近で、GCTは自分が良いと思っていますが直後にelmoが良いという判断に大きく変化しています。この付近の局面で読み抜けがあったのではないかと予想されます。

f:id:select766:20210115220524p:plain
60手目付近の進行

60手目付近の進行です。59手目▲44銀打(elmoの指し手)のあと、△46金(GCTの指し手)、▲53銀成、△47金、▲52成銀と進みました。この付近の局面を、GCTとelmo両方に読ませ、先手番から見た評価値をプロットしたものが下図になります。思考時間は実際の対局と同じ1手1秒です。

f:id:select766:20210115220750p:plain
60手目付近の局面をGCTとelmo両方に読ませた評価値

63手目の思考時点でelmoは先手良しとしていますが、GCTはまだ気づいていない、という状況です。なお62手目時点ですでにGCTとelmoで評価値に差があります。62手目をelmoに30秒読ませたところ先手から見て341点、GCTに30秒読ませたところ先手から見て238点となり、62手目の1秒での評価はelmoのほうが正しいようです。問題の62手目ですが、GCTが△47金を指しました。GCTが想定する応手は▲18飛となっていました。しかし実際は▲52成銀で、予想が外れています。▲52成銀が指された後の局面(64手目)ではGCTで評価しても先手有利であることを認識できています。64手目以降の局面評価は正しいが、△47金を指す時点ではこの応手が見えておらず、誤った評価の元で△47金を指してしまったと考えられます。△47金の直後の局面(63手目)をGCTで30秒間思考させたところ、最初の読み筋は▲18飛ですが、思考が進むと正解の▲52成銀が出てきました。DNNの方策を表示させた(DebugMessage=true)ところ、最大確率は▲61飛車打(24%)で、▲18飛は6%で5位、▲52成銀は1%で14位でした。かなり順位が低い指し手のため、探索初期では全く検討されません。一方で、一度検討されると有力であることを認識できています。この手を早期に検討できるようにすることが有力であると考えられます。そしてこの指し手がelmoで1000ノードだけ思考させた場合(NodesLimit=1000)に最善手となるかどうかが課題です。試したところ、10回中8回は▲52成銀を出力し、2回は▲44歩でした。マルチスレッドの影響でランダム性がありますが、この局面では高確率で正解の手を出力することができました。

今回試したのはあくまで1局面ですが、DNNの方策関数が見落とした最善手をelmoが1000ノード分の探索で見つけられるということがわかりました。方策関数に対して従来型エンジンの最善手をブレンドするというアイデアに対する肯定的な結果が得られました。実際には、従来型エンジンの最善手が間違っていて探索の邪魔になってしまうケースがありうるため、統計的にメリットが得られるのかどうか検証することが今後の課題となります。

DNNの方策に従来型エンジンのbestmoveをブレンドする【コンピュータ将棋】

第31回世界コンピュータ将棋選手権の参加申込が始まり、私も久々にコンピュータ将棋の研究を再開しました。

評価関数としてDNNを使い、MCTSで探索を行う将棋AIの弱点として、読みぬけの問題があります。ここで読みぬけとは、DNNが出力した方策で、ほぼ確率0の指し手が実は有力だった場合に全く探索されず、相手がその手を指してきて評価値が一気に悪化するという現象を指しています。評価関数の精度向上はもちろん重要ですが、2020年秋の電竜戦で、評価関数の学習に相当なコストをかけているdlshogiの評価値が一気に悪くなった対局があったように思います(読みぬけなのかどうかは定かではありませんが)。この問題に対処するアイデアとして、KPPT・NNUE評価関数などを用いる従来の全幅探索型のエンジンと協調して探索することを考えます。DNNは局面を表す行列に巨大な係数行列を掛けて方策を出力する一方、全幅探索型のエンジンは数手先まで探索することにより方策を出力する仕組みで、相補的に使えるのではないかと期待しています。

具体的なアルゴリズムですが、ある局面に対し、DNNで評価すると同時に全幅探索型のエンジンで数手分の探索を行い、指し手と評価値をDNNの出力とブレンドすることにしました。MCTSにおける末端局面Bに対し、DNNが出力する方策ベクトル P_D(B) (合法手それぞれに対する指し手確率)、全幅探索型のエンジンでNノード分探索した結果の最善手(bestmove)を確率1とする方策ベクトル P_S(B)を係数 \alphaを用いて (1 - \alpha)P_D(B) + \alpha P_S(B)とし、これを方策として用います。同様に、DNNが出力する勝率 V_D(B) (勝ちを1、負けを-1とするスカラー)、全幅探索型のエンジンの評価値を600で割ってtanhに通した勝率 V_S(B)に対し、係数 \betaを用いて (1 - \beta)V_D(B) + \beta V_D(B)を勝率として用います。

非常に小さな環境で実験を行いました。小さすぎて評価結果が怪しいのでご了承ください。Pythonを用いた(並列化のない)純粋なMCTSを実装し、DNNの評価と同時に全幅探索型のエンジンをUSIプロトコル経由で呼び出して局面の評価を行います。全幅探索型のエンジンとして、やねうら王4.89+elmo2019評価関数(NNUE型)を用い、1000ノード固定で探索させました。DNNは、KPPT評価関数の探索結果から教師あり学習した64チャンネル19層のCNNです。教師データに対する方策正解率37.8%、勝敗正解率78.9%となっており実用的なモデルよりかなり弱いです。対局の開始局面として、平手初期局面から24手進んだ互角局面集を用いました。

そもそものDNNの強さを評価しました。やねうら王1000ノード固定探索を基準として、DNNだけでMCTS探索した場合の勝率を測定しました。

MCTSノード数 勝-負-分
500 31-67-2
1000 53-44-3
2000 71-25-4

探索ノード数が500~1000ノードの間でやねうら王1000ノード分と同じ強さになるようです。もう少し強いDNNモデルで評価すべきでした。

先述のアルゴリズムで評価関数をブレンドしたものを、ブレンドなしのDNNのみの評価関数と対戦させて勝率を測定しました。いずれもノード数は1000です。

 \alpha  \beta 勝-負-分
0.01 0.01 52-41-3
0.1 0.1 40-0-0
0.5 0.5 43-0-0
1.0 1.0 56-9-0
0.5 0.0 52-0-0
1.0 0.0 49-0-0

従来型エンジンの探索結果を10%ブレンドするだけで、ブレンド前に100%勝てるという結果になりました。この極端な結果の原因は、DNN評価関数が弱く、従来型エンジンで1000ノード読んだ結果のほうが圧倒的に強いためであると考えられます。MCTSの1ノードの評価のために従来型エンジンを1000ノード分探索させているので、MCTSで1000ノード探索させることで実質的には100万ノード分の探索をさせていることになります。肯定的な結果ではあるものの、実験条件が本来の対局と乖離していてよくわからないというのが正直なところです。

純粋なMCTSの実装ではDNNをバッチサイズ1で評価することになり、1000ノード分の評価に10秒ほどかかってしまい、これ以上ノード数を増やした実験は困難です。またやねうら王の探索ノード数設定を1000以下に設定しても、実際には局面に応じて1000近い局面が読まれてしまうためこれ以上小さく設定することもできませんでした。純粋な環境での実験は諦め、並列化された実用的な探索エンジンに実装して試したいと考えています。例えばdlshogiには末端局面での詰み探索が搭載されているので、これをNNUE等の評価関数を用いた通常の探索に置換すれば実験できそうです(ソースコードをほとんど読んでいないのでどの程度簡単かはわかりません)。

汎用行動選択モデルの3vs3対応 part02 単純な学習【PokéAI】

前回提案した、3vs3対応の特徴量を用いて行動選択の強化学習を行っていきます。

パーティ

実験に用いる、3体からなるパーティはランダムに1000個生成しました。各ポケモンの種族・覚える技については過去記事に準拠しています。持ち物なしです。

select766.hatenablog.com

パーティの例を示します。

キレイハナ,LV50,とっしん,どくどく,はかいこうせん,ギガドレイン
フシギバナ,LV50,はかいこうせん,すてみタックル,ロケットずつき,ソーラービーム
ヤドラン,LV55,ばくれつパンチ,ずつき,バブルこうせん,れいとうビーム

デリバード,LV50,かげぶんしん,れいとうビーム,どろかけ,ふぶき
ピジョット,LV50,はがねのつばさ,どくどく,どろかけ,はかいこうせん
ライチュウ,LV55,かいりき,ちきゅうなげ,ずつき,かみなり

シャワーズ,LV55,かげぶんしん,どろかけ,すてみタックル,はかいこうせん
マタドガス,LV50,サイケこうせん,ヘドロばくだん,かげぶんしん,どくどく
エレブー,LV50,ロケットずつき,どくどく,でんじほう,スピードスター

シャワーズ,LV50,たきのぼり,はかいこうせん,のしかかり,どろかけ
ドククラゲ,LV55,ヘドロばくだん,いあいぎり,ロケットずつき,れいとうビーム
エアームド,LV50,ドリルくちばし,スピードスター,いあいぎり,どろかけ

アーボック,LV50,かげぶんしん,ギガドレイン,かいりき,ヘドロばくだん
スターミー,LV55,おんがえし,ふぶき,れいとうビーム,バブルこうせん
グランブル,LV50,おんがえし,はかいこうせん,でんじほう,かみなりパンチ

実験1

まずは1vs1と同様の学習パラメータで強化学習を行っていきます。

DNNモデルは16チャンネル、3層です。バトル10万回で学習しました。

設定ファイル

battles: 100000
party_tags:
- random_200917_1
tags:
- testrun
trainer:
  dqn_params:
    epsilon: 0.3
    epsilon_decay: 2.0e-06
    gamma: 0.95
    lr: 1.0e-05
  feature_params:
    party_size: 3
  model_params:
    bn: false
    n_channels: 16
    n_layers: 3

バトル10万回学習した最終的なモデル(id: 3b3)と、途中の1万回時点のチェックポイントと、ランダムに行動するエージェントがそれぞれ学習時と同じ1000パーティを操作し、合計3000プレイヤーでレーティングバトルを行いました。各エージェントが操作したプレイヤーの平均レートを示します。

エージェント 平均レート
1万回時点 1530
10万回時点 1589
ランダム行動 1380

強化学習により、ランダムより強いエージェントが作れること、また学習が進むことで強さが向上することがわかりました。

実験2

1vs1ではDNNの構造は16チャンネル、3層がパラメータチューニングの結果最良でしたが、より複雑な戦略が要求される3vs3ではよりパラメータ数が多いモデルが良い可能性があります。そこで、64チャンネル3層のモデル(id: 6ee)を学習しました。他の条件は実験1と同じです。

設定ファイル

battles: 100000
party_tags:
- random_200917_1
tags:
- testrun_201017_1
trainer:
  dqn_params:
    epsilon: 0.3
    epsilon_decay: 2.0e-06
    gamma: 0.95
    lr: 1.0e-05
  feature_params:
    party_size: 3
  model_params:
    bn: false
    n_channels: 64
    n_layers: 3

同様にレーティングバトルを行った結果を示します。

エージェント 平均レート
64チャンネル3層 1584
16チャンネル3層 1560
ランダム行動 1355

若干ですが64チャンネル3層のモデルのほうが良いことがわかりました。今後、モデルの構造はこれを採用します。

定量的に、ランダムに行動するより良いモデルが学習できました。次回、バトル中の行動を定性的に確認します。

汎用行動選択モデルの3vs3対応 part01 入出力の拡張【PokéAI】

前回まで、汎用行動選択モデルは1vs1バトルの環境で学習をしていました。今回から3vs3バトルに拡張していきます。

select766.hatenablog.com

9月から着手していたのですが、2020年12月時点では、動作しなくはないが定性的にいまひとつの結果という状況です。それもあって全く新しい手段である木構造探索に手を付けているのですが、時間がたつと忘れてしまうので、進捗を書き留めておきたいと思います。

本記事では、1vs1バトルのシステムから最小限の変更で3vs3バトルを可能にします。汎用行動選択モデルにおける行動選択の仕組みは、(ディープニューラルネットワーク=DNNで表現された)Q関数に選択肢を表現したベクトルを入力し、その出力が最大となるような選択肢を選ぶというものでした。1vs1バトルでは選択肢は場に出ているポケモンが覚えている技4つのうちどれを選択するかでした。3vs3バトルでは、技のほかに、控えのポケモン(最大2体)のいずれかと交代する選択肢が追加されます。選択肢を表現するベクトルが交代を表現できるようにすれば、3vs3バトルが可能になると考えられます。パーティ固有行動選択モデルだと、(ポケモン1の技1(のQ値), ポケモン1の技2, ポケモン1の技3, ポケモン1の技4, ポケモン1に交代, ポケモン1に強制交代, ポケモン2の技1, ...という固定の18次元ベクトルを出力するようにしていました。汎用行動選択モデルでは、Q関数自体の出力はスカラー値で、場に出ているポケモンの技4種類それぞれに対応するベクトルと控えのポケモン最大2体に交代するベクトルの最大6つのベクトルを独立にQ関数に入力することになります。

Q関数へ入力するベクトルは、残りHPや状態異常などバトルの状態を表した「状態特徴量」と選択肢固有の情報を表した「選択肢特徴量」を連結して生成します。

状態特徴量は1vs1バトルのときと同じです。

特徴 次元数 自分/相手 説明
生存ポケモン 1 両方 瀕死でないポケモン数/全ポケモン
ポケモンタイプ 17 相手 場に出ているポケモンポケモンのタイプ(ノーマル・水・…)に該当する次元に1を設定
HP残存率 1 両方 場に出ているポケモンの現在HP/最大HP
状態異常 6 両方 場に出ているポケモンの状態異常(どく・もうどく・まひ・やけど・ねむり・こおりのうち該当次元に1を設定)
ランク補正 6 両方 場に出ているポケモンのランク補正(こうげき・ぼうぎょ・とくこう・とくぼう・すばやさ・命中・回避それぞれ、ランク/12+0.5を設定)
天候 3 - 場の天候(はれ・あめ・すなあらし)に該当する次元に1を設定

選択肢特徴量は以下のようになります。

特徴 次元数 説明
交代 1 選択肢が交代(強制交代も含む)を表すとき1
強制交代 1 選択肢が強制交代を表すとき1
ポケモン 251 技の選択肢では、場に出ているポケモンに対応する次元を1にする。交代・強制交代の選択肢では、交代して繰り出すポケモンに対応する次元を1にする。
267 技の選択肢では、繰り出す技に対応する次元を1にする。交代・強制交代の選択肢では、交代して繰り出すポケモンが覚えている技すべてに対応する次元を1にする。
持ち物 47 技の選択肢では、場に出ているポケモンの持ち物に対応する次元を1にする。交代・強制交代の選択肢では、交代して繰り出すポケモンの持ち物に対応する次元を1にする。

強制交代とは、場に出ているポケモンが瀕死となった際に交代先となる控えのポケモンを選択する場合を指します。3vs3バトルのために追加した要素は交代・強制交代の2次元だけです。この入力で交代を含めた行動の選択が可能であると考えた理由は、1vs1バトルでのQ関数の出力を観察した結果です。

select766.hatenablog.com

この観察から、場に出ている自分のポケモンと相手のポケモンの相性にあわせてQ値が変動していることがわかります。相性の情報は、状態特徴量における相手のタイプと、選択肢特徴量における自分のポケモンの種族から判定するようにQ関数が学習されたと考えられます。仮にそのQ関数の入力として自分の場に出ているポケモンを表す部分に交代先のポケモンの情報を入れた場合、そのポケモンが相手のポケモンに対して相性が良いのであれば高いQ値、相性が悪ければ低いQ値が得られ、自然に交代を行動選択に考慮可能であると考えました。技の部分についても、相手のポケモンに有効な技を持っていれば高いQ値が得られると期待できます。ただし、交代に1ターンかかるので場に出ているポケモンが技を出す場合と比べ、同じ技であってもQ値を割り引く必要があります。それを考慮可能とするため、選択肢特徴量に交代であるかどうかの情報を含めました。

細かいことですが、ポケモン金銀における技は251種類ですが、めざめるパワーについて、タイプ不定のもののほか、16タイプそれぞれを別の技として追加してあります。ただ当面はめざめるパワーを覚えたポケモンは使用しません。持ち物については「持ち物なし」に対応する次元を含めてあります。こちらも当面持ち物なしの環境で実験を行います。過去記事で決めた有効なポケモン・技のサブセットを継承しています。

select766.hatenablog.com

次回以降、この拡張を用いて強化学習を試みます。