ランド研究所の「機械学習による航空支配」を実装する（その１３）： 2D問題 mission_1 を強化学習する

#1. はじめに
本記事は、ランド研究所の「機械学習による航空支配」を実装する（その１３）です。

[Air Dominance Through Machine Learning: A Preliminary Exploration of Artificial Intelligence–Assisted Mission Planning, 2020](https://www.rand.org/pubs/research_reports/RR4311.html)

（その１２）では、ランド研究所のレポートに従って、環境（2D 問題用のシミュレータ）を作りました。

（その１３）では、学習が少しづつ難しくなるように順次設定を変えて行き、ランド研究所のレポートに示された手法の限界を見極めます。実は、最初から難しい問題設定でやってみたのですが、全く学習が進まなかったので、どのあたりに限界があるのか順番に調べて行きました。レポートでは PPO を使えば上手くいったとあっさり書いてあるのですが、十分な計算リソースがあれば問題ないのでしょうか？それとも、カリキュラム学習や reward shaping を試行錯誤でやって行ったのでしょうか？これらを使ったような、使っていないような曖昧な記載になっていて判りませんが、結論で唐突に reward shaping は非常に重要だと書いてあります。ただ、reward shaping をやっていると、次第に強化学習ではなく if-then rule を作っているような気分になって来るので私は嫌いです。また、どうしても試行錯誤が必要になるので、ランド研究所並みの計算機パワーがあればよいのですが、ビンテージ・マシーンの場合、余程がまん強くないとできません。このため別の方法で性能改善を試みました。

今回は、まずランド研究所のレポートの方法のままだと、なぜ上手くいかないのか、原因を探り、改善策を考えます。

過去記事へのリンクは最下段にあります。

作成したコードは、下記 GitHub にあります。今回使用するのは、mission_1 フォルダです。

>>https://github.com/DreamMaker-Ai/AirDominance_2D_RL

#2.　SAC (Soft Actor Critic)

2D 問題のアクション空間は連続ですので、これに対応できる強化学習アルゴリズムを使用する必要があります。1D 問題で使用したアルゴリズムの内、Actor-Critic 系のアルゴリズムである A3C (A2C) と PPO は、連続アクション空間に対応しています。ランド研究所のレポートでも、この2つを使っています。

ここでは、ランド研究所のレポートでは使用していなかった SAC（Soft Actor Critic）を使いました。（レポートで、SACが使われなかった理由は、研究時期の問題だと思います）。
> [Soft Actor-Critic: Off-Policy Maximum Entropy Deep Reinforcement Learning with a Stochastic Actor, 2018](https://arxiv.org/abs/1801.01290)

PPO, A3C, SAC のどれが良いのかは、「数値積分としてどのアルゴリズムを使うのが良いのか」という議論に似ていて、いろいろ指針はあるのかもしれませんが、つまるところやって見ないと分からない、のが現状だと思います。したがって、本来は、PPO、A3C も実施して比較してみるべきなのですが、ビンテージ・マシンなので SAC のみを実施するだけで精一杯でした。（Stable Baselines を使う場合、数行の変更だけで、SAC 用のトレーニング・プログラムを、PPO や A2C 用に変更できるので、その内やってみたいとは思っています）。

SACは、普通の強化学習の目的函数：
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/ce10d11a-2941-11c5-7882-b304d116fab3.jpeg)

の代わりに、ポリシーのエントロピー項 H(π(・|s)) を追加した目的函数：
![キャプチャ1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/c352799a-0f02-0382-a0fb-f14e16f131ef.jpeg)

を最大化します。ポリシーに高いエントロピーを持たせるのは、下記記事によると、探索を明示的に促し、Q 函数の値が同じ、又は、ほぼ等しいアクションに対して、等しい確率を割り当てるようにポリシーを促し、また、学習が崩壊（collapse）して特定のアクションを繰り返し選択することがないようにするのが目的とのことです。

> https://towardsdatascience.com/soft-actor-critic-demystified-b8427df61665

式 (1) の α は温度係数と呼ばれ、エントロピー項をどの程度重視するのかを設定するパラメータです。SACでは、α も最適化してくれる（固定値として設定することも可能）ので、調整すべき重要なハイパー・パラメータが１つ減りますから、ビンテージ・マシン利用者には嬉しいアルゴリズムです。

さらに、[下図](https://docs.ray.io/en/master/rllib-algorithms.html#sac)に示すように Replay Buffer と多数のロールアウト・ワーカを使ったオフポリシー（Off policy）のアルゴリズムなので、サンプル効率が高い（つまり、学習が早い）のもビンテージ・マシン利用者には嬉しいところです。

図２
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/5ae8a16c-7631-6220-bf4d-1bcd7dee05e8.jpeg)



#3. ケース・スタディ
以降のシミュレーションでは、主戦場の広さは 100 km x 100 km、主戦場の周りには 20 km のマージンとして、副戦場を取っています。登場エンティティ（Fighter, Jammer, SAM）のいずれかが、破壊されるか、副戦場よりも外に出ると、そのエピソードは終了です。

図３
![Battle field.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/c51b8cf2-c5f9-f13d-06e8-c6a65c83eb6e.png)

ニューラルネットのアーキテクチャはデフォルト設定のままとしましたので、ソフトQ函数、ポリシー函数ともに、ユニット数 = 64 の 2 層 MLP となっています。重み共有はありません。







##3.1 Fighter, Jammer の初期位置固定、初期ヘディング・エラー無しでの学習
最初に、最も基本的な幾何学関係として、Fighter, Jammer の初期位置を固定し、初期ヘディング・エラー無しのミッション条件でトレーニングして、学習できるかどうか試してみました。ここで、「初期ヘディング・エラー無し」とは、シミュレーション開始時点で、Fighter, Jammer の速度ベクトルがともに SAM 位置を指向していることを意味しています。また、SAMは、主戦場の中央 (50, 50) km に固定しています。したがって、エピソード毎の変動要因は、Fighter と SAM の射程だけになります。

使用した Fighter, Jammer, SAM の位置関係は下図に示すようにセットしたので、Fighter, jammer の初期ヘディング角 = π (180deg) 、位置＝(50, 90) km 固定です。

図３．１．１
![Battle field w2_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/5f02b626-ecb4-09da-e407-4f34ac4c7dd4.png)

この最も簡単なケースが学習できないようではお話になりませんが、下図に示すように、問題なく学習できています。下図で、横軸が学習ステップ、縦軸が 1000 のテスト・エピソードから計算した成功率です。薄い赤ラインは成功率の生値、濃い赤ラインは α=0.8 の指数移動平均（EMA: Exponential Moving Average）です。worker 数は 32 としました。

図３．１．２
![w2_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/e1076134-6374-8a48-3609-f377538dd368.png)

プランナーが生成したプラン例を示します（図３．１．２と軸が 90 度回転しています。ゴメンナサイ）。

以下の動画では、濃紺の丸が Fighter、半透明で濃紺の大きな円が Fighter の射程、緑色の丸が Jammer、半透明で緑色の大きな円が Jammer の有効レンジ、赤の丸が SAM 配備位置 、半透明で赤色の大きな円が SAM の射程を表しています。SAMの射程を表す円は、ジャミングを受けると、それに対応した大きさの円に変わります。

Jammer が Fighter よりも少しだけ先に進出し SAM の射程を縮退させます。そこに、Fighter が進出して SAM を撃破します。

![sac_w2-0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/348729fd-28ae-10f6-0524-beb6b2769ec9.gif)



##3.2　Jammer初期位置のみ前後にランダムに振ってみる

次に、下図に示すように、Jammer の初期位置のみ [85, 95] km の範囲で振って学習させてみます。

図３．２．１
![Battle field w2_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/e3eb56ec-d7db-1ab1-39de-bab271e6fc59.png)

このケースでも学習に支障はありません。

図３．２．２
![w2_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/39c70ef6-0c54-af43-63dd-041625694ff6.png)

プランナーが生成したプラン例を示します。Jammer が Fighter よりも前方にいる場合、Jammer は SAM の射程を縮退させるように進出した後は、SAM の縮退した射程に沿って円を描くように、つまりSAM の射程外から、継続的に妨害をかけることができるように移動します。そこに、Fighter を進出させて SAM を撃破します。


![sac_w2-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/77be515e-5f94-5994-c5ba-99b9dfc56162.gif)


##3.3　Fighter の初期位置（固定）をJammerから45度離角した位置に変更する

Fighter の初期位置を Jammer に対し、固定の離角 45 [deg] をとるようにして学習させてみます。ヘディングエラーは無しのままです。

図３．３．１
![Battle field w2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/1cf21d1c-9aa1-9d1b-3014-8f5a963acaff.png)

このケースでも学習に支障はありません。

図３．３．２
![w2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/22453ea3-f5bc-47e1-1fd1-9984adb536d0.png)

プランナーが生成したプラン例を示します。やはり、Jammer は SAM の射程を縮退させるように進出した後は、SAM の射程外から、継続的に妨害をかけることができるように移動します。

![sac_w2-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/363cb97d-ca3a-3017-0da8-108912a50d52.gif)



##3.4　Fighter の初期位置を Jammer から ±45 度離角した位置でランダム選択

Fighter の初期位置を Jammer に対し、固定の離角 45 [deg] 又は -45 [deg] をランダムにとるようにして学習させてみます。ヘディングエラーは無しのままです。

図３．４．１
![Battle field w2_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/94c55e23-5ac1-937f-503c-2f7ac158736e.png)

学習に時間がかかるようにはなりましたが、学習に支障はありません。

図３．４．２
![w2_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/42b804db-ea6a-54cd-bb73-f3fcc1eae044.png)

プランナーが生成したプラン例を示します。この例では、Fighter は進出タイミングを計るように回り込んでSAMを攻撃しています。

![sac_w2-4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/4f77f378-391a-3db0-1fee-7af9805c4d80.gif)



##3.5 Jammer に初期ヘディング・エラーを持たせる

Jammer に初期ヘディングエラー ±5 [deg] を持たせて学習させてみます。初期ヘディングエラー ±5 [deg] というのは小さすぎる気はするのですが、これ以上大きくすると学習が進まなかったため設定した数値です。この改良は、あとで実施します。

図３．５．１
![Battle field w2_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/24e8c049-c504-5108-2545-3679e4bea81c.png)

ヘディングエラーが無い場合と同程度の時間で学習ができています。

図３．５．２
![w2_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/2d0e4f76-db2d-42a8-d3ca-19ee38731eff.png)

プランナーが生成したプラン例を示します。やはり、Fighter が Jammer の方に回り込んで SAM を攻撃するプランとなっています。

![sac_w2-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/3d4ab389-a018-5eda-e30a-adc6a1e59fcd.gif)


##3.6 Fighterの初期位置を、円周上のランダムな位置にする

Fighter の初期位置を SAM を中心とした半径 40km の円周上にして学習させます。ヘディングエラーは無しです。

図３．６．１
![Battle field w2_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/8c28fce8-eecd-8973-ca11-31f45e154c17.png)

成功率＝１を達成するプラン（薄いラインが成功率の生値です）が少し減りますが、学習できています。

図３．６．２
![w2_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/dc08a061-9de9-aa62-9aa2-08d2aef84d3e.png)

プランナーが生成したプラン例を示します。ここで示した例では、Jammer は SAM の射程を縮退させる距離を維持しながら飛翔し、SAM の射程が縮退したタイミングで Fighter が進出し SAM を撃破します。

![sac_w2-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/f0d9cf78-c322-8a6a-6fce-a154dd1c76a0.gif)



##3.7 Fighter, Jammer に初期ヘディングエラーを持たせる

Fighter, Jammer に、±5 度の初期ヘディングエラーを持たせて、学習させてみます。

図３．７．１
![Battle field w2_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/6dd08d4c-5afa-eccb-7463-9ba4d8dd2fbf.png)

成功率＝１を達成するプラン（薄いラインが成功率の生値です）がなくなりますが、それなりの成功率で学習できています。

図３．７．２
![w2_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/ea2efd33-d682-77b3-42d3-fa8de9a7302f.png)

プランナーが生成したプラン例を示します。Jammer は SAM の射程を縮退させる距離を維持しながら飛翔し、SAM の射程が縮退したタイミングで Fighter が進出し SAM を撃破します。

![sac_w2-4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/9a7c6b2a-2df9-1c1d-9097-3e5580af14d2.gif)


##3.8 Jammerの初期位置も、円周上のランダムな位置にする

Fighter, Jammerの初期位置を下記の青いリングの内側の任意の場所にします。初期ヘディングエラーは ± 5 度です。

![Battle field w2_7-9 Hard to train.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/3e37c66b-3e47-5bdd-c987-f0f3155d8ceb.png)

この段階で、学習が全く進まなくなりました。学習率を何通りか変えて学習させてみましたがダメでした。


#4. なぜ、急に問題が難しくなるのか？解決策は？

Jammer の初期位置を円周上のランダムな位置にした時に、急に学習が出来なくなりました。この原因は、Fighter と Jammer のすべての離角関係が観測されるため、観測空間が急に大きくなるため、学習が急に困難になるのではないかと推測します。ランド研究所のレポートの方法では、観測が Fighter, Jammer の絶対座標系での（正規化）位置（x, y）なので、例えば、下図の 2 つの幾何学位置関係は、全く別の観測量になります。実際には、この二つの幾何学関係は、90 度半時計方向に回転させただけですが、これらの関係を全て別の観測量として学習する必要があるので、このケースでは、それ以前のケースに比べ、観測空間が急激に増大し学習が困難になるものと考えられます。

![Battle field 幾何学関係.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366937/74e04490-bc85-663a-1ff3-79f7300a37ad.png)

これに対処する方法としては、ネットのサイズを大きくするのが王道なのでしょうが、ネット・アーキテクチャやハイパー・パラメータを試行錯誤で大きくする作業は、ビンテージ・マシン向けではありません。

このため、上の図をもう一度考えてみると、エンティティ間の相対関係は全く同じです（全てを 90 度回転しただけなので当たり前です）。そこで、観測量を絶対量で与えるのではなく、相対量だけで与えれば、上の二つの図の観測量は全く同じになるので、観測空間の巨大化を防ぐことが出来るのが判ります。この場合、Fighter と Jammer の両方を円周上の任意の場所に配置しても、相対関係だけの問題となるので、Jammer 初期位置を固定して、Fighter の初期位置だけを回転したケースと同じ観測空間大きさで済むはずです。Fighter の初期位置だけを回転したケースは、デフォルト設定で学習できているので、相対観測量にすることでデフォルト設定のままで、このケースも学習できるのではないかと期待できます。（その１３）では、この方針に従うことで、思った以上にうまく問題に対処できることを示します。

#（その１４に続く）
（その１４）では、観測量を相対量にすることで、mission 1 に対処できるロバストなエージェントを強化学習できることを示します。


#過去記事へのリンク
- [ランド研究所の「機械学習による航空支配」を実装する（その1）：レポートのまとめ](https://qiita.com/DreamMakerAi/private/95e0aad16e450cb0c53d)
- [ランド研究所の「機械学習による航空支配」を実装する（その2）：1次元問題について](https://qiita.com/DreamMakerAi/items/72c90f9df5339dedd9cd)
- [ランド研究所の「機械学習による航空支配」を実装する（その3）： 1D simulator for GAN と Random mission planner の実装）](https://qiita.com/DreamMakerAi/private/1a0e25a9f673e531ee6f)
- [ランド研究所の「機械学習による航空支配」を実装する（その4）： conditional GAN の実装とトレーニング](https://qiita.com/DreamMakerAi/private/3a416d5cb64d9b7e86db)
- [ランド研究所の「機械学習による航空支配」を実装する（その5）：トレーニング結果の分析](https://qiita.com/DreamMakerAi/items/6c78181b71c470632fcf)
- [ランド研究所の「機械学習による航空支配」を実装する（その６）：トレーニング・データの重要性と GAN の性能向上](https://qiita.com/DreamMakerAi/private/b8ae6c9afd28e90b5b5c)
- [ランド研究所の「機械学習による航空支配」を実装する（その７）：1D simulator for RL の実装](https://qiita.com/DreamMakerAi/private/f008fa9981c3ad74c3cc)
- [ランド研究所の「機械学習による航空支配」を実装する（その８）： Stable Baselines による強化学習](https://qiita.com/drafts/37e6a18810b83d759d81/edit)
- [ランド研究所の「機械学習による航空支配」を実装する（その９）： 少し複雑な環境](https://qiita.com/DreamMakerAi/private/f4d3e35c07ab053608ea)
- [ランド研究所の「機械学習による航空支配」を実装する（その１０）：GAN / 強化学習プランナーの連携を考える](https://qiita.com/DreamMakerAi/private/6cb416e42fc35a7a425c)
- [ランド研究所の「機械学習による航空支配」を実装する（その１１）： ２次元問題の概要](https://qiita.com/DreamMakerAi/private/3572afde356ba5719123)
- [ランド研究所の「機械学習による航空支配」を実装する（その１２）： 2D simulator for mission_1 の実装](https://qiita.com/DreamMakerAi/private/af22d730bf8cbff23fdd)