見出し画像

Unity Obstacle Towerの攻略

以下の記事が面白かったので、ざっくり訳してみました。

Competing in the Obstacle Tower Challenge

Unity Obstacle Tower Challenge」で競うのはとても楽しかったです。私は競技会の大部分、ラウンド2では全体でリーダーボードのトップにいました。競技会の終わりまでに、私のエージェントは平均19.4でランク付けされ、人間のベースラインの15.6を超えてました。これは他の提出より圧倒的に高いスコアでした。

これをどうやって実現したのか?
簡単に言うと、人間のデモンストレーションを巧妙に使用しました。他にもいくつかのトリックが関係しており、この投稿ではそれらについて簡単に触れます。

「Obstacle Tower」そのものを見る前に、私は汎化が競争の主なボトルネックになると思いました。この仮定は主に私が「OpenAI Retro Content」に参加した経験から生じました。そこで、いくつかの原始的な解決策を試すことから始めました。

CMA-ESを使用したポリシーの進化。
PPOを使用した、小さな観察結果(5×5画像など)を考慮したポリシーの訓練。
CEMを使用した報酬を最大化するためのopen-loop行動分布の学習。

しかしこれらの解決策はいずれも5階まで達しなかったため、PPOベースラインの方が優れていることがすぐにわかりました。PPOのチューニングを開始すると、汎化が実際のボトルネックではないことがすぐに明らかになりました。100個のトレーニングシードは、強化学習アルゴリズムが汎化するのに十分であることが判明しました。そのため、汎化に焦点を当てるのではなく、データの増強などトレーニングセットの強化を目指しました。

anyrl-pyに基づいたPPO実装は、10階で壁にぶつかりました。そこで、何が起こっているのかを確認するために、環境を詳しく調べることにしました。10階に倉庫番風のパズルが導入されていることが判明しました。このパズルでは、エージェントが部屋に置かれている箱を押して、床にマークされた場所まで運ぶ必要があります。これには、一貫した一連の行動を数秒間(約50タイムステップ)実行することが含まれます。

この時点で、他の研究者は、「Curiosity-driven Exploration 」や「Go-Explore」などを試している可能性があります。私はこれらの手法に時間をかけませんでした。私が知る限り、これらの方法はすべて、視覚的に単純な(多くの場合2次元)環境に対して強い誘導バイアスを持っています。しかし、「Obstacle Tower」では、観測はカメラの向いている場所、エージェントの立ち位置に完全に依存します。

エージェントは、同じ場所に立っていてたとしても、まったく異なる観察を得ることができ、まったく異なる場所に立っていたとしても、似た観察を得ることができます。さらに、倉庫番パズルの箱を押す最初の瞬間は、同じ箱を押す最後の瞬間と非常によく似ています。 私の仮説は、「Obstacle Tower」では従来の探索アルゴリズムはあまり効果的ではないというものでした。

エージェントに倉庫番パズルを解決させるにはどうすればよいでしょうか?
試みるアプローチとしては、パラメータ空間で探索する「進化的アルゴリズム」と、探索問題を完全に回避する「人間のデモンストレーション」です。私は、「人間のデモンストレーション」がより実用的であると判断しました。

「人間のデモンストレーション」を利用するために、私は「Obstacle Tower」のプレイを記録する簡単なツールを作成しました。いくつかのゲームを記録した後、「Behavior Cloning」 (教師あり学習)を使用して、デモにポリシーを適合させました。「Behavior Cloning」は急速にオーバーフィットし始めたため、訓練を早期に停止し、結果のポリシーを評価しました。それはひどいものでしたが、ランダムエージェントよりもパフォーマンスが良くなりました。このポリシーを「PPOで微調整」することで、最初から訓練されたポリシーよりも早く学習できるようになりました。しかし、倉庫番パズルは解決しませんでした。

さらに多くのデモンストレーションを行いましたが、「Behavior Cloning」+「PPOで微調整」では、倉庫番パズルを攻略できませんでした。この頃、PyTorchでコードを書き直して、他の模倣学習アルゴリズムをより簡単に試せるようにしました。そして「GAIL」によって、 箱を押し始めましたが、10階の攻略には結びつきませんでした。エージェントは多くの場合、円を描いて走り回っており、箱やターゲットを見ただけでは覚えていないため、問題には「メモリ」が関係している可能性があることに気付きました。

それでは、エージェントのメモリの問題をどのように解決すれば良いのでしょうか?
私の経験では、強化学習のRNNは多くの場合、ユーザーが何を望んでいるかを覚えていません。そこで、エージェントが過去を思い出すのにRNNを使用する代わりに、過去50のタイムステップを積み重ねて入力の一部としてエージェントに提供できる状態表現を作成しました。

もともと、状態表現は(action, reward, has key)でした。このようなシンプルな状態表現でも、「Behavior Cloning」の方がうまく機能しました。しかし、この状態表現には箱やターゲットについて表現してないので、状態表現をカスタマイズすることにしました

倉庫番パズルを解くのに役立つ可能性のある情報をエージェントが思い出せるように、箱、ドア、箱のターゲット、キーなどの一般的なオブジェクトを識別する分類器を訓練しました。次に、これらの分類出力を状態表現に追加しました。 この改善された「Behavior Cloning」は倉庫番パズルを定期的に解決し始めました。

エージェントのメモリが改善されたにもかかわらず、「Behavior Cloning」+「PPOで微調整」はまだ倉庫番パズルを解決できず、「GAIL」はあまり改善されていませんでした。 エージェントが10階に着き始める頃には、箱を押す方法を完全に忘れていたようです。私の経験では、このような強化学習での忘却は、エントロピーボーナスが原因であることが多いです。このボーナスは、すぐに目立った報酬をもたらさないエージェントの事前に訓練された行動を破壊する傾向があります。

エージェントの行動を破壊するエントロピーボーナスに加えて、行動クローンエージェントが妥当な低レベルの行動を実行したことに気づきました。しかし、高レベルのコンテキストでは不合理でした。
たとえば、箱を部屋の隅まで押し込んでも、間違った隅に押し込んでしまう場合があります。 エントロピーボーナスを使用する代わりに、エージェントが苦労していた高レベルの問題を解決できるようにしながら、これらの低レベルな行動をそのまま維持するボーナスが必要でした。
そこで、私はPierarchyを使ってKL termを実装しました。

いちど整ったら、物事はかなりスムーズに進みました。 この時点で、より多くのデモンストレーションを記録し、エージェントをより長く(5億タイムステップのオーダーで)訓練することが問題の焦点となっていました。

ただしそれだけでなく、以下のようなパフォーマンスを向上させるためのトリックも実施していました。

・私の実際の提出物は2人のエージェントで構成されていました。
1つ目は1〜9階を解決し、2つ目は10階以降を解決しました。 後者のエージェントは、10〜15の間でランダムにサンプリングされた開始フロアでトレーニングされました。これにより、最初に1〜9フロアを攻略するのではなく、倉庫番パズルから解くようになりました。

・私が人間としてゲームをプレイするのが簡単であることがわかったため、行動空間を減らしました。

・私のモデルは、IMPALA論文のCNNアーキテクチャに基づいていました。 ビデオゲームでの強化学習の私の経験では、このアーキテクチャは、元のNatureの記事で使用されたアーキテクチャよりもよく学習し、汎化します。

Fixup初期化を使用して、より深いモデルの訓練を支援しました。

MixMatchを使用して、他の方法で必要とされるよりも少ないラベル付きサンプルで状態分類器を訓練しました。

・「Behavior Cloning」には、従来のタイプの画像データ拡張を使用しました。 ただし、イメージと行動が一緒にミラーリングされるミラーリングデータ拡張も使用しました。 この方法で、訓練レベルの数を効果的に2倍にすることができます。すべてのレベルにもミラーイメージが付属しているからです。

・「prierarchy」訓練中に、「Obstacle Tower」にデータ増強を適用して、過学習を支援しました。これが必要だと実際に確認したことはありませんでしたし、そうではなかったかもしれませんが、他の出場者は間違いなく私以上に過学習に苦労しました。

・タイムオーブを拾うための小さな報酬ボーナスを追加しました。 エージェントがほとんどのタイムオーブを逃したため、これがどの程度の効果をもたらしたかは不明です。 これは、改善が間違いなくより良いエージェントをもたらす1つの要因です。

ラウンド2の大部分はチェックアウトしました。コンテストに積極的に取り組むのをやめ、多くの時間、何も訓練していませんでした。 コンテストの終わり近くに、他の参加者が倉庫番パズルを解き始めたとき、私はエージェントをもう少し訓練して新しいバージョンを提出しましたが、それは必要ではなかったことが判明しました。

私のコードはGithubにあります。 この投稿で説明した解決策を反映したままにしておきたいので、リポジトリを変更する予定はありません。


この記事が気に入ったらサポートをしてみませんか?