2021年7月26日月曜日

学習率は高すぎるといけない

前回エージェントがゆっくりだが成長しているかもしれないと書いた。 実際のところ、成長しているかどうかはもっと長期間トレーニングをしてみないとわからない気がする。 スマブラとは別によくわかっている系での強化学習で、data-efficient Rainbowの学習率を変えて実験してみた。 結果、与えられた0.0001という学習率では、10万ステップ以降の学習が困難になり、0.000025あたりだと学習することがわかった。 この数字をガオガエンに適用した結果、ほどなくしてLv1のマルスを倒すようになった(半分強程度の確率で)。 小さいが重要な変更である。深層学習の教科書にも学習率は最も大事なハイパーパラメータだと説明されている。 よりよい値があるかもしれないが、とりあえずしばらくこれでいこうと思う。 この結果に気をよくし、Lv8のマルスと戦わせることにした。もしLv8にも勝てるようになったらまた動画を上げよう。

2021年7月24日土曜日

不可解な自滅の理由は Catastrophic forgetting ではなかった

 昨日立てた仮説は、リプレイメモリの容量が足りないために途中でどのように自滅をしていたかを忘れて再度自滅をしてしまう、ということだった。(Catastrophic forgetting としてフォーラムで解説されている。) これを検証するためにリプレイメモリを30万回分から100万回分に増やしてLv1のマルスと再度戦わせた。その結果がこちらである。

リプレイメモリ30万回のとき

リプレイメモリ100万回のとき
となった。50000ステップごとに評価モード(Greedy Policyになる)で報酬を5回計算し、その平均をとっている。1ストックにつき2ポイントでダメージには部分点が入る。勝利者には+1ポイントされる。一見して言えることは、ノイズが大きくて結論が出しにくいという点である。おそらくリプレイメモリ30万回の最初の方で結果の上ぶれもあり、それがその後の成長を隠していた可能性もある。両方の図を見ると双方今後もっとゆっくりとしたペースで成長を続け、いずれはコンピュータマルスLv1を難なく倒す日が来る可能性も考えられる。
リプレイメモリが多くて困ることはないので、リプレイメモリ100万のまましばらくトレーニングを続けることにする。可能であればトレーニングを加速したい。今のところアイディアは2つある。1つはより深い(多層の)ネットワークを使うこと。深いネットワークはより強い可塑性を与えるのでパフォーマンスがよくなる可能性がある(強化学習においてはその効果があまり聞かれないので注意は必要だが)。もう1つはコントローラ出力をスティックとボタンに分離すること。今は9 x 6の54通りのどれかという形で出力しているが、分離するとスティック部で9つ、ボタンで6つとなり、出力しなければいけない数字の数が15まで減少する。この単純化はトレーニングの上で役に立たないだろうか。今のトレーニングを継続しつつコードを書き始めてみることにする。

ちなみに今のガオガエンの動きはこんな感じである。





2021年7月23日金曜日

スマブラは育成ゲームになった

残念ながらAmiiboの話ではない。

この手記は最強無敵のガオガエンをスマブラに産みだすための工程の備忘録のようなものである。まだちゃんと動いていないし成功するかどうかはわからないが、研究することに価値はあるだろう。

まずは手法を簡単に説明する。ガオガエンと他のファイターを戦わせ深層強化学習を行う。強化学習はパソコンで行われるので、スイッチから映像を読み出す装置(キャプチャーボード)とスイッチにコントローラ入力をする装置が必要になる。

映像の読み出しは一般的に広く行われている方法で可能である。今回は Elgato HD60 S+ を用いる。一般のビデオキャプチャーデバイスとして扱うことができるので(Webカメラなどと同じ方式)、MacやLinuxでも使用でき、後述のOpen CVからも読み出しがしやすい。

コントローラ入力はArduinoとシリアルポートを用いて行う。ArduinoにUSB接続のプロコンのふりをさせてスイッチに繋ぎ、Arduino本体のシリアルポートからの入力で操作できるようにする。パソコン側にはUSB接続のシリアルポートデバイスを接続し、Arduinoに結線する。このような仕様でスイッチを動かす手法は既に確立されており、GitHubにリポジトリが存在するので、それを用途に合うように少々改変して使用させていただくことにする。Arduinoは家に転がっていたUno R3を用いることにした。

これらの手法をとることによって、スイッチとの入出力を外部機器で行うことができる。すなわち、本体やソフトに改造を施すことなく、強化学習の環境が構築できる。もちろん入出力の遅延を考慮しなければいけなかったり、実行時間が実時間以上にならないことを考えるとよいことばかりではない。しかし、現行機のゲームに強化学習が使えるようになるのは画期的といえるだろう。

強化学習エージェントは DeepMind の開発した Rainbow を用いる。GitHub に PyTorch での実装があるのでそれを適当に改変して使わせていただく(data-efficientの設定を用いる)。 Environment の部分はほぼ全面的に書き直さなければならないが、なんとなくうまくいくように適当にやった。

少々手をこまねいたのがダメージや撃墜の認識の部分で、これは取得した映像から読み出さないといけない。数字の部分の色(具体的には小数点の色)を見て判断することにした。報酬関数も適当に書いた。このあたりの詳細はそのうちコードを公開するときにでも解説できたらと思う。

紆余曲折あって強化学習っぽいことをするようになった。映像取得はほぼ20Hzで行い、その全フレームに対してコマンド出力を行う。コマンドはスティック8方向+中心の9パターンに、ボタン操作6つ(A, B, ガード、ジャンプ、つかみ、押さない)を掛けた、54通りの出力とした。この組み合わせだと、強攻撃がとっさに入力できない等の不完全性はあるが、まずはパターンを減らすことを優先した。手法の詳細は先行研究(スマブラDX+DQN強化学習)に依存するところが大きい。

とりあえずLv9のマルスと一晩戦わせてみたが、あるところから成長をしなくなってしまった。相手が強すぎたかと思いLv3やLv1のマルスに変えてみたが、やはり成長を途中でやめてしまうようだった。Lv1で試したときは約30万ステップ(5時間程度)の時点で成長をやめ、自滅をするようになってしまった。これが、その時使用していたリプレイメモリのサイズと一致していたので、リプレイメモリの最初の部分(自滅が多い)が失われると、どんなときに自滅になるかを忘れてしまい、また自滅をするようになる、と仮説を立て、検証することにした。

今晩は同じ設定のLv1のマルスを相手に、リプレイメモリのサイズを100万にして戦うことにする。これによって30万を越えて成長するようになるのであれば仮説は正しいことになる。次の懸念は100万を越えたときにどうなるかだが、越えたときにまた成長を止めてしまうようであればリプレイメモリの更新の方法を考慮する必要がありそうだ。

とりあえず今日のメモはここまでにする。今回は動画もなにもなく説明ばかりになってしまったが、翌日以降は興味深い動作などがあったら記録していきたいと思う。