Q学習でOpen AI GymのPendulum V0を学習した

強化学習のQ学習を勉強したので、せっかくなので Open AI Gymの 「pendulum v0」の学習を実装した。

この記事では Q 学習の基礎は知っているという前提で、学習環境や実装で苦労した点を説明する。

gym のインストール

  • gym をインストール
$ pip install gym
  • pybox2d をインストール
$ brew install swig
$ git clone https://github.com/pybox2d/pybox2d
$ cd pybox2d
$ python setup.py build
$ python setup.py install

Pendulum v0

Open AI Gym にはいくつかの強化学習評価用の環境が用意されているが、 今回は以下の「Pendulum v0」を選んだ。

https://github.com/openai/gym/wiki/Pendulum-v0

タスクの目的

振り子へ適切にトルクを与えることで、垂直に振り上げた状態を維持すること。

環境

「Pendulum v0」では以下の3つの値を環境の状態として取得できる。

  • cos(theta): 振り子が角度 θ のときの cos の値
  • sin(theta): 振り子が角度 θ のときの sin の値
  • theta_dot: 振り子が角度 θ のときの 角速度

行動

エージェントは環境を観測し、振り子へ与えるトルクを決定し、振り子を回転させる。

報酬

エージェントは、行動の結果、以下の式で計算される報酬を受取る。

-(theta^2 + 0.1*theta_dt^2 + 0.001*action^2)

終了条件

実装者が適当に決めて良いということなので、 今回は1エピソードの中で1000 回の行動をし、その中で観測した sin の値の平均が 0.91 を上回ったら終了、とした。

Q学習による制御

実装したコードは以下。大体500エピソード前後で終了する。

https://gist.github.com/uu64/71529c63b374a9103486395811fc77bf

施行錯誤した点がいくつかあるので紹介する。

報酬の与え方

デフォルトの報酬に加えて、以下の条件で追加報酬を与えた。これによりできるだけ早い収束を目指した。

  • sin の値が 0.98 より大きい場合は、最大 100 点のボーナス
  • sin の値が -0.98 より小さい場合は、最大 100 点の罰則

行動の決定方法

行動の決定には epsilon-greedy 法を使ったが、以下の式で epsilon を決定した。これは 0 エピソード時点では 40% の確率でランダムに行動を選択するが、徐々にその確率を減少させ、251エピソード以降は Q が最大となるような行動を選択するようにしている。

epsilon = -0.0016*episode + 0.4

epsilon が小さすぎると、Q 値の学習が足りないのか、sin の値がなかなか向上しなかった。

状態の離散化の解像度

環境の状態を示す値はすべて連続値なので、適当な解像度で離散化する必要がある。

theta_dot が -8.0 から 8.0 の間で、最初はあまり荒くてもよくないかと思い、0.4刻み(40分割)で学習をしていたが、細かすぎるのか収束に 2000 エピソード近くかかった。

最終的には解像度を 0.8 刻み(20分割)まで落としたところ、500エピソード前後で収束するようになった。

感想

振り子が立ち始めるまでは簡単だったが、そこから収束のスピードや精度を向上させるための細かいパラメータ調整に時間がかかった。状態の属性数が増えるとなかなか厳しいのでは、という印象。

次は流行りの DQN でもう少し難しいタスクに挑戦したい。