強化学習のライブラリ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++で高速化
)