yshr10ic’s Blog

備忘録

OpenAI Gym入門

最近、強化学習に興味を持って勉強しています。まず手始めにOpenAI GymのDocumentationを通じて、強化学習について学んでみました。

そもそもOpenAI Gymってなに?

あの有名なイーロン・マスクなどが出資する非営利団体「OpenAI」が提供する、強化学習用の検証プラットフォームです。

gym.openai.com

公式サイトには、Gymは強化学習アルゴリズムを開発したり、比較したりするツールキットだと記載されています。

強化学習って?

下記のサイト、本がおすすめです。

blog.brainpad.co.jp

qiita.com

www.amazon.co.jp

Installation

さっそくインストールしてみましょう! gymはpipコマンドでインストールすることができます。(一部の環境では、他にインストールすべきライブラリがあります。)

pip install gym

GitHubからクローンして、インストールすることもできます。

git clone https://github.com/openai/gym
cd gym
pip install -e .

Environments

まずは、簡単に強化学習を試してみます。 以下のコードは、CartPole(倒立振子)を制御するためのものです。

import gym
env = gym.make('CartPole-v0')
env.reset()
for _ in range(1000):
    env.render()
    env.step(env.action_space.sample())

上記のコードを実行すると下記のようになります。 CartPoleでは、倒立している振り子を倒さないように、黒いカートを左右に移動させて制御します。

f:id:yshr10ic:20190217195007g:plain
CartPole

OpenAI Gymでは、CartPole-v0の箇所をMountainCar-v0MsPacman-v0Hopper-v2などに変えると、様々な環境を試すことができます。 なお、環境によってはgym以外に必要なライブラリもありますが、実際に実行した際に表示されるエラーメッセージを見れば、必要なライブラリはすぐに判断することができます。 試しに、環境をHopper-v2に変えて実行してみたところ、下記のようなエラーメッセージが出力されました。エラーメッセージから、mujocoが足りないことが分かります。

Traceback (most recent call last):
  File "<Anaconda Path>\envs\dev\lib\site-packages\gym\envs\mujoco\mujoco_env.py", line 11, in <module>
    import mujoco_py
ModuleNotFoundError: No module named 'mujoco_py'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "hopper.py", line 2, in <module>
    env = gym.make('Hopper-v2')
  File "<Anaconda Path>\envs\dev\lib\site-packages\gym\envs\registration.py", line 167, in make
    return registry.make(id)
  File "<Anaconda Path>\envs\dev\lib\site-packages\gym\envs\registration.py", line 119, in make
    env = spec.make()
  File "<Anaconda Path>\envs\dev\lib\site-packages\gym\envs\registration.py", line 85, in make
    cls = load(self._entry_point)
  File "<Anaconda Path>\envs\dev\lib\site-packages\gym\envs\registration.py", line 14, in load
    result = entry_point.load(False)
  File "<Anaconda Path>\envs\dev\lib\site-packages\pkg_resources\__init__.py", line 2322, in load
    return self.resolve()
  File "<Anaconda Path>\envs\dev\lib\site-packages\pkg_resources\__init__.py", line 2328, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "<Anaconda Path>\envs\dev\lib\site-packages\gym\envs\mujoco\__init__.py", line 1, in <module>
    from gym.envs.mujoco.mujoco_env import MujocoEnv
  File "<Anaconda Path>\envs\dev\lib\site-packages\gym\envs\mujoco\mujoco_env.py", line 13, in <module>
    raise error.DependencyNotInstalled("{}. (HINT: you need to install mujoco_py, and also perform the setup instructions here: https://github.com/openai/mujoco-py/.)".format(e))
gym.error.DependencyNotInstalled: No module named 'mujoco_py'. (HINT: you need to install mujoco_py, and also perform the setup instructions here: https://github.com/openai/mujoco-py/.)

Observations

Environmentのstep関数に、どのように行動するかが記述されています。 step関数は以下の4つを返します。

  • observation (object型):環境を観察するための環境特有のオブジェクト。例えば、カメラのピクセル情報、ロボットの関節の角度や速度、ボードゲームのボードの状態などです。
  • reward (float型):直前の行動によって獲得した報酬の総和。報酬の大きさは環境により異なりますが、目標は常に報酬の総和を増加させることです。
  • done (boolean型):環境をリセットするかどうかを判断する変数。ほとんどのタスクは明確に定義されたエピソードに分割され、エピソード終了時にdoneがTrueとなります。
  • info (dict型):デバッグに役立つ情報。

タイムスタンプごとに、エージェントは行動(action)を選択し、環境(environment)は状態(observation)と報酬(reward)を返します。

f:id:yshr10ic:20190218201655j:plain

import gym
env = gym.make('CartPole-v0')
# エピソードを20回繰り返します
for i_episode in range(20):
    # エピソードの最初に実行され、状態を初期化します
    observation = env.reset()
    # 最大100回行動します
    for t in range(100):
        # 画面に現在の状態をレンダリングします
        env.render()
        print(observation)
        # ランダムに行動
        action = env.action_space.sample()
        observation, reward, done, info = env.step(action)
        if done:
            print("Episode finished after {} timesteps".format(t+1))
            break

上記のコードを実行すると下記のようになります。

f:id:yshr10ic:20190219214254g:plain
レンダリング動画

[-0.02557018  0.00245127  0.02048424 -0.01868486]
[-0.02552116 -0.19295837  0.02011055  0.28039005]
[-0.02938032  0.00187102  0.02571835 -0.00588284]
[-0.0293429   0.19661487  0.02560069 -0.29034166]
[-0.02541061  0.00113741  0.01979386  0.01030424]
[-0.02538786  0.19596998  0.01999994 -0.27606835]
[-0.02146846  0.39080096  0.01447858 -0.56237679]
[-0.01365244  0.58571678  0.00323104 -0.85046331]
[-0.0019381   0.78079452 -0.01377823 -1.14212848]
[ 0.01367779  0.9760938  -0.0366208  -1.43910026]
[ 0.03319966  1.17164732 -0.0654028  -1.74299798]
[ 0.05663261  1.36744966 -0.10026276 -2.05528828]
[ 0.0839816   1.1734857  -0.14136853 -1.79523137]
[ 0.10745132  0.98020202 -0.17727315 -1.54962217]
[ 0.12705536  1.17695256 -0.2082656  -1.8919686 ]
Episode finished after 15 timesteps
[-0.03312327  0.01541595 -0.02496491  0.02577558]
[-0.03281495 -0.17933925 -0.0244494   0.31047843]
[-0.03640174 -0.37410449 -0.01823983  0.59535156]
[-0.04388383 -0.56896647 -0.0063328   0.8822337 ]

Spaces

すべての環境には、行動空間と状態空間があります。 これらはSpace型で定義されます。

import gym
env = gym.make('CartPole-v0')
print(env.action_space)
#> Discrete(2)
print(env.observation_space)
#> Box(4,)

CartPole-v0では、行動空間はDiscrete(2)、状態空間はBox(4,)となっています。 Discrete(x)型は、非負の離散空間で0~x-1の範囲の値を取ります。 Box(n)型は、n次元の配列を表します。Boxの最大値・最小値は以下で確認できます。

print(env.observation_space.high)
#> [4.8000002e+00 3.4028235e+38 4.1887903e-01 3.4028235e+38]
print(env.observation_space.low)
#> [-4.8000002e+00 -3.4028235e+38 -4.1887903e-01 -3.4028235e+38]

Discrete型とBox型はもっとも一般的なSpaceです。 Spaceからサンプリングしたり、Spaceに属しているかを確認することができます。

from gym import spaces
space = spaces.Discrete(8)
x = space.sample()
print(space.contains(x))
#> True
print(space.n)
#> 8

Available Environments

Gymには、様々な環境が用意されています。

  • Classic control and toy text:大部分が強化学習の論文から引用された小規模なタスクです。
  • Algorithmic:複数の桁の足し算や文字列の順序の逆転などの計算をするタスクです。こうした計算はコンピュータは得意ですが、強化学習ではこれらを例題からアルゴリズムを学習します。これらのタスクは、シーケンスの長さを変えることによって難易度を変えることができます。
  • Atari:アタリのゲーム。
  • 2D and 3D robots:ロボットのシミュレーションを制御します。これらのタスクでは、高速で正確なロボットシミュレーション用に設計されたMuJoCoのエンジンを使用します。

The registry

Gymの目的は、共通のインターフェースを公開し、比較ができるようにバージョン管理された多くの環境を提供することです。 利用可能な環境のリストは、gym.env.registryで確認できます。

from gym import envs
print(envs.registry.all())
#> dict_values([EnvSpec(Copy-v0), EnvSpec(RepeatCopy-v0), EnvSpec(ReversedAddition-v0), ..., EnvSpec(MemorizeDigits-v0)])

出力結果が多すぎたので省略しましたが、私の環境では、2019年2月20日現在、797の環境が提供されていました!

おわりに

いかがだったでしょうか? まずはOpenAI Gymでどのような環境があり、どのように実装されているのかを確認すれば、強化学習の勉強を進めやすくなると思います!実際にstep関数がどのように実装されているか、GitHubで確認してみたいですね。