実数値遺伝的アルゴリズムで回転倒立振子の深層強化学習
実数値遺伝的アルゴリズム(Real coded genetic algorithm, 以下RCGA)を使って深層強化学習をしてみたのでその記録です。
RCGAについてはこちらの記事を参考にしてください。
st1990.hatenablog.com
以下の検証に関するコードはgithubにあげてあります。
github.com
1. 本記事の概要
- RCGAで深層強化学習をするモチベーション
- RCGAを使った深層強化学習(方策最適化)の考え方
- RCGAを使った深層強化学習の実装
- 回転倒立振子(OpenAI Gym Pendulum-v0)での検証
- まとめ
2. RCGAで深層強化学習をするモチベーション
強化学習とは、何か行動をするとそれに応じて報酬がもらえるような環境において、報酬をたくさんもらえる行動を学習する手法です。
有名どころだと、マリオだとか囲碁とかありますね。詳しくはGoogle先生に聞いてみてください。
強化学習においてもディープラーニングは活用されており、DQNやらDDPGやらA3Cやらいろいろな手法が提案されています。このような深層強化学習はkeras-RL等のライブラリを使うと、一から作るよりは楽に実装できます。
実際に私もkeras-RLを使って深層強化学習を試してみたことがありますが、普通の教師あり学習よりもきちんと性能を出すのが難しいと感じました。なかなかうまく収束してくれないです。
こちらのOpen AIの論文では、深層強化学習のDNNのパラメータ更新に勾配法ではなく進化戦略(Evolution Strategies)を使っています。
https://arxiv.org/pdf/1703.03864.pdf
強化学習では勾配法より進化戦略的な手法の方が良いかもとかいう噂も聞きます。
そこで、自分の知見を深めるため、進化戦略の親戚的な手法であるRCGAを使って強化学習をしてみました。
(※今回の内容は上記ESを使った論文の手法を再現したわけではないのでご注意ください。)
3. RCGAを使った深層強化学習(方策最適化)の考え方
今回対象とした回転倒立振子(OpenAI Gym Pendulum-v0)について簡単に説明し、この問題を強化学習でどのように学習させるか述べます。
回転倒立振子(OpenAI Gym Pendulum-v0)
対象としたのは回転倒立振子です。OpenAI GymのPendulum-v0を使いました。
Pendulum v0 · openai/gym Wiki · GitHub
この動画のように振子を倒立させ、それを維持することが目的です。
www.youtube.com
Pendulum-v0において観測値(環境)、行動、報酬は以下のとおりです。
観測値(環境)
- cos(theta):cosθ(θは振子の角度)[-1, 1]
- sin(theta):sinθ(θは振子の角度)[-1, 1]
- theta_dot:振子の角速度[-8, 8]
行動
- Joint effort:ジョイント部分にかける力[-2, 2]
報酬
行動を起こすたびに次式の即時報酬を得ます。
-(theta2 + 0.1theta_dt2 + 0.001action2)
倒立した状態で完全に停止し、かつ力もかけていなければ上式は0となります。
逆に、この状態からずれるほど0より小さな値となります。
強化学習での学習のさせ方
さて、RCGAを使った強化学習でPendulum-v0を学習させる方法を述べていきます。
強化学習にはQ学習などいろいろな手法があるのですが、ここでは方策勾配法の勾配を使わないバージョンの方法を考えます。
この方法では、Q値などを考えずに、方策を直接最適化します。
エージェントについて
エージェントという概念を使います。
エージェントは、現在の観測値から次の行動を決定します。行動によって環境が変わり次の観測値が得られるので、この観測値から次の行動を決定します。これを繰り返します。
Pendulum-v0においてエージェントは以下のような動作をします。
- ① 現在の観測値(振子の位置、角速度)を得る。
- ② 観測値を基に、次の行動(ジョイント部分にかける力)を決める。
- ③ 振子に②で決められた力が加えられ、振子の位置及び角速度が変化する。
- ④ ①~③を繰り返す。
最終的に振子を倒立させ、力を加えない状態で維持させられる最適なエージェントを見つけられれば、Pendulum-v0を学習できたと言えます。
最適なエージェント
最適なエージェントとはどのようなエージェントか考えます。
エージェントは行動を起こす度に上述の報酬を受け取ります。エージェントが時刻t=0からt=Tまで1刻みで行動するとすると、得られる報酬Rの合計Vは次式で表されます。
ここで、振子の初期状態はいつも同じではないため、初期状態が不利であればVは小さくなってしまいます。これを避けるため、後半の報酬Rを重視するようにVを次式のように修正します。
あらゆる初期状態についてVを最大にするようなエージェントは一番報酬をたくさんもらう、即ち最適なエージェントだと言えます。
以降ではVを時間割引総報酬と呼びます。
エージェントの表現
エージェントは現在の観測値から次の行動を決定するものでした。
そこで、エージェントを、「入力が現在の観測値、出力が次の行動」となるようなDNNで表現します。
今回の検証では以下のようなDNNでエージェントを表現しました。
入力や出力が[-1, 1]の範囲に収まるように正規化している以外は特に工夫はありません。
RCGAでのエージェントの最適化
さて、最適なエージェントをRCGA(世代交代JGG、交叉AREX)で求めることを考えます。
最適なエージェントを求めることは、Vを最大にするDNNのパラメータを求める最適化問題です。
そのため、以下の手順に従えばRCGAで最適なエージェントを求めることができます。
- ① DNNのパラメータをRCGAの遺伝子とする。
- ② 遺伝子をランダムにNg個作成し、現世代の個体とする。
- ③ 現世代の個体から親個体Np個をランダムに選択し、交叉させて子個体をNc個作成する。
- ④ 子個体の遺伝子をDNNのパラメータに変換する。各子個体のエージェントにPendulum-v0を実行させ、Vを求める。
- ⑤ 良いVとなった子個体Np個を、親個体の代わりに現世代に加え、これらの個体群を新しい現世代とする。
- ⑥ ③~⑤を指定の条件を満たすまで繰り返す。
- ⑦ 一番良いVとなった個体を最適なDNNパラメータ=最適なエージェントとする。
RCGAを使った深層強化学習のいいところ
- DNNを使っているが、勾配法に頼らず最適なDNNのパラメータを計算できます。つまり、勾配法を実装しなくていいので楽です。エージェントの表現を複雑にする場合に効いてくるかもしれません。
- 時間割引総報酬を最大にする方策を直接最適化しているので、他のQ値や勾配法を使うような手法と比べて理解しやすい(たぶん)。
- 計算を並列化しやすい。
- 他あるかなー。
4. RCGAを使った深層強化学習の実装
RCGAを使ったPendulum-v0の強化学習の実装です。言語はpythonです。
RCGAのクラスRealCodecGA_JGG_AREXは以前の記事と同じです。
Pythonでの実数値遺伝的アルゴリズム(Real-coded genetic algorithm)の実装 - st1990のblog
5. 回転倒立振子(OpenAI Gym Pendulum-v0)での検証
上述のRCGAを使った強化学習(方策最適化)を回転倒立振子(OpenAI Gym Pendulum-v0)で検証しました。
条件
Pendulum-v0の条件は以下のとおりです。
- 1エピソードのステップ数は200。
RCGAのハイパーパラメータは以下のとおりです。
- 遺伝子の初期値(DNNのパラメータ)は[-4, 4]の一様分布からサンプリング。
- 各世代の個体数30個。
- 親の個体数30個(現世代の個体すべてを親とする)。
- 子の個体数300個。
- 計算終了する世代数100世代。
- 学習率=0.0。
- その他の条件は原論文の推奨値を使用。
子の個体数が300なので、一世代あたり300エピソード実施されることになります。
その他の条件は以下のとおりです。
- Vを計算するときの割引率γ=0.9。
結果
このようにきちんと学習できました。
ただし、そんなに安定しているわけではなく、同じ条件でも良いエージェントを見つけられなかったりもしました。
RCGAのハイパーパラメータの設定がかなり重要でした。ハイパーパラメータのチューニングが何気に大変。
上記の検討では合計300×100エピソードの計算をしているので、DQN等の他の深層強化学習と比べて単純に学習が早いとは思えません。ただ、DNNの学習にGPUがいらなかったり、CPUでガシガシ並列計算できるのはメリットだと思います。