11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Stable BaselinesとOpenAI Gymで強化学習の環境構築

Last updated at Posted at 2021-03-09

強化学習のライブラリstable baselinesを使ってpythonで強化学習を行うためのメモ。

環境:Ubuntu 20.04

#目次

1. 必要要件まとめ
2. インストール前の注意
3. インストール手順
4. 使い方  
  4-1. OpenAI Gym
  4-2. Stabe Baselines 基本編
  4-3. Stabe Baselines 環境の並列化


#必要要件まとめ
Python 3.7
pip 20.1.1
gym
TensorFlow 1.14.0
stable-baselines 2.10.1

強化学習を行うライブラリはたくさんあるが、ここではstable-baselinesを使用する。
理由は、KerasRLやChainerRLと比較して
・ 対応している強化学習アルゴリズムが多い
・ バグがない
・ 公式Documentが充実している
からだ。

#インストール前の注意
stable-baselinesは中でtensorflowを使用するが、tensorflow2には対応していないため、tensorflow1をインストールする必要がある。
最新のpip3==21.x.xではtensorflow1がインストールできないため、pip3==20.x.xを使用しなければならない。
そのためにPython3.8ではなく、Python3.7にしなければならないということだ。

ちなみにUbuntu20.04ではシステムのPythonがPython3.8になってしまっているのでpyenvやcondaなどを使用してPythonのバージョンを変更しなければならない。
またほかのプログラムでtensorflow2を使用する場合もpythonの仮想環境を作成してバージョンを分ける必要がある。

参考サイト
Pyenvを使用してUbuntuにPythonをインストールする
venv: Python 仮想環境管理

#インストール手順
Python3.7が入れられればインストールは簡単だ。

$ sudo apt install python3-pip
$ pip3 install gym tensorflow==1.14.0 stable-baselines

これでインストールは完了だ。
これらをインストールする際に、自動でnumpyなど必要なライブラリもインストールされる。

#使い方
##OpenAI Gym

import gym

#環境を作成
env = gym.make('CartPole-v0')
max_step = 200

#環境を初期状態に戻す(返り値は状態)
obs = env.reset()

#シミュレーション開始
for id_step in range(max_step):
    #環境を1ステップ進める(引数は環境で用意されたサンプルアクション)
    obs, reward, done, info = env.step(env.action_space.sample())
    #描画
    env.render()
    #終了
    if done:
        break

OpenAI gymの詳しい使い方はOpenAI Gym 入門を参照。
公式ドキュメント(英語)

##Stable Baselines 基本編
stable-baselinesはopenAIが開発したライブラリであるため、gym形式の環境にしか強化学習を行えない。
以下はCartPole環境に対しDQNで学習を行った例だ。

#!/usr/bin/env python3                                                                      
 import os
 import gym
 from stable_baselines.bench import Monitor
 from stable_baselines.deepq.policies import MlpPolicy
 from stable_baselines.common.vec_env import DummyVecEnv, SubprocVecEnv
 from stable_baselines.common.cmd_util import make_vec_env
 from stable_baselines.common.evaluation import evaluate_policy
 from stable_baselines import DQN
  
 def main():
     #ハイパーパラメータ設定
     time_steps = 25000
  
     #ログ保存先
     log_dir = './logs/'
     os.makedirs(log_dir, exist_ok=True)
     model_name = 'cartpoleDQN'
  
     #環境作成
     env = gym.make('CartPole-v0')
  
     #強化学習モデルの作成
     model = DQN(MlpPolicy, env, verbose=1, tensorboard_log=log_dir)
  
     #学習
     model.learn(total_timesteps=time_steps)
  
     #モデル評価
     eval_env = gym.make('CartPole-v0')
     mean_reward, std_reward = evaluate_policy(model, eval_env, n_eval_episodes=10)
     print('Mean reward: {} +/- {}'.format(mean_reward, std_reward))
  
     #モデルの保存
     model.save(model_name)
  
  
 if __name__ == '__main__':
     main()

実行すると警告が大量に出るがこれはstable-baselines内でtensorflow1の古いコードを用いていることが原因なので無視してよい。最終的に以下のようなコードが出れば成功だ。

--------------------------------------
| % time spent exploring  | 77       |
| episodes                | 100      |
| mean 100 episode reward | 23.6     |
| steps                   | 2332     |
--------------------------------------
--------------------------------------
| % time spent exploring  | 2        |
| episodes                | 200      |
| mean 100 episode reward | 90.2     |
| steps                   | 11349    |
--------------------------------------
Mean reward: 115.0 +/- 8.160882305241266

コードの細部について解説していく。

model = DQN(MlpPolicy, env, verbose=1, tensorboard_log=log_dir)

第一引数のMlpPolicyはDQNで用いるニューラルネットワークの定義だ。MlpPolicyはstable-baselinesで定義されている最もシンプルなニューラルネットワークである。詳細はこちら

第二引数のenvはこのモデルが対象とする環境だ。これによりMlpPolicyの入力層や出力層のノード数を決定する。

第三引数のverboseはコンソールに学習経過を出力するタイプだ。値は0, 1, 2の3つであり、大きいほど詳細に出力される。

第四引数のtensorboard_logは学習経過をtensorboardで観察するための出力ファイルだ。
学習後や学習中でもターミナルをもう一つ開き、

$ tensorboard --logdir=./logs/

とコマンドを実行し、表示されたURLをクリックするとtensorboardを開くことができる。

model.learn(total_timesteps=time_steps)

ここでtotal_timestepsは学習で実行される総ステップ数であり、総エピソード数ではない。つまり
total_timesteps = (1エピソードのステップ数)×(総エピソード数)
となる。

##Stable Baselines 環境の並列化
ここ数年で出てきたA2CやPPOなどの強化学習手法は環境を並列化して学習を行う。
ここでは環境を並列化する方法を解説する。
###1. make_vec_env
単一プロセスで複数の環境を実行するもの。最もよく使われるもの。
環境の並列数だけ設定すればよく、あとはいい感じに自動で設定してくれる。
###2. SubprocVecEnv
環境の数だけプロセスを用意し、1環境1プロセスで強化学習を行っていく。通常はプロセス間通信の遅延により、make_vec_envよりも時間がかかる。しかし、1ステップの処理が重い環境ではmake_vec_envよりも高速となる場合がある。
(ちなみに自分の場合は、カスタムgym環境を作って強化学習を行った際はSubprocVecEnvはmake_vec_envの10倍高速になった。)

サンプルコード
#!/usr/bin/env python3
import os 
import gym
from stable_baselines.bench import Monitor
from stable_baselines.common.policies import MlpPolicy
from stable_baselines.common.vec_env import DummyVecEnv, SubprocVecEnv
from stable_baselines.common.cmd_util import make_vec_env
from stable_baselines.common.evaluation import evaluate_policy
from stable_baselines import PPO2

def main():
    #ハイパーパラメータ
    n_envs = 16
    time_steps = int(1e+5)
    multiproc = False

    #ログ保存先
    log_dir = './logs/'
    os.makedirs(log_dir, exist_ok=True)
    model_name = 'ppo2'
 
    #並列環境作成
    if multiproc == False:
        env = make_vec_env('CartPole-v0',
                n_envs=n_envs,
                monitor_dir=log_dir)
    else:
        env = SubprocVecEnv([lambda: Monitor(gym.make('CartPole-v0'),
                filename=log_dir+'{}.monitor.csv'.format(i), allow_early_resets=False) for i in range(n_envs)],
                start_method='spawn')

    #強化学習モデルの作成
    model = PPO2(MlpPolicy, env, verbose=1)

    #学習
    model.learn(total_timesteps=time_steps)

    #モデルの保存
    model.save(model_name)

SubprocVecEnvで各環境に対しログ保存ファイルを作ろうとしたがうまくいかず。。。
tensorboard用のログファイルは作成できるのですが各エピソードの記録を記したcsvファイルの作成がうまくいかず...
解決策をご存じの方がいたらコメントお願いします。
[](
gym型のカスタム環境を作る方法
[番外編] カスタムgym環境の演算をC/C++で高速化
)

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?