深層強化学習ライブラリであるkeras-rlを用いて、 DDPGを動かしてみます。
Open AI gym で提供されているPendulumという問題を解きます。
基本的にはkeras-rlのexmpleコードを用います。
適宜、日本語のコメントや学習結果を表示するためのコードを加えています。
ちなみに私の環境は
- ubuntu 18.04
- python 3.6.0
です。
DDPGについて
Deep Deterministic Policy Gradient(DDPG) は
モデルフリーの深層強化学習アルゴリズムです。
Actor-Critic を用いて構成されています。
https://www.tcom242242.net/entry/2019/04/02/190122
なので、ActorとCtiricの2つのニューラルネットワークを用います。
詳しくは以下の論文を参照していただければと思います。
https://arxiv.org/pdf/1509.02971v2.pdf
kears-rlのインストール
keras-rlを動かすためにいくつかインストールする必要があります。
pip install numpy pip install gym pip install tensorflow pip install keras pip install keras-rl
プログラム
Pendulumという振り子の問題を解かせます。
学習エージェントは、振り子を立たせて置くことが目的となる問題です。
問題については以下の公式サイトを確認していただければと思います。
https://github.com/openai/gym/wiki/Pendulum-v0
以下にサンプルコードを示します。
以下のコードはコピーしてそのまま実行できます。
import numpy as np import gym import matplotlib.pyplot as plt from keras.models import Sequential, Model from keras.layers import Dense, Activation, Flatten, Input, Concatenate from keras.optimizers import Adam from rl.agents import DDPGAgent from rl.memory import SequentialMemory from rl.random import OrnsteinUhlenbeckProcess # 環境(タスク)の設定 ENV_NAME = 'Pendulum-v0' env = gym.make(ENV_NAME) np.random.seed(123) env.seed(123) assert len(env.action_space.shape) == 1 nb_actions = env.action_space.shape[0] # actorの設定 actor = Sequential() actor.add(Flatten(input_shape=(1,) + env.observation_space.shape)) actor.add(Dense(16)) actor.add(Activation('relu')) actor.add(Dense(16)) actor.add(Activation('relu')) actor.add(Dense(16)) actor.add(Activation('relu')) actor.add(Dense(nb_actions)) # 出力は連続値なので、linerを使う actor.add(Activation('linear')) print(actor.summary()) # criticの設定。上記で設定したactorのinputを入力に含める action_input = Input(shape=(nb_actions,), name='action_input') observation_input = Input(shape=(1,) + env.observation_space.shape, name='observation_input') flattened_observation = Flatten()(observation_input) x = Concatenate()([action_input, flattened_observation]) x = Dense(32)(x) x = Activation('relu')(x) x = Dense(32)(x) x = Activation('relu')(x) x = Dense(32)(x) x = Activation('relu')(x) x = Dense(1)(x) x = Activation('linear')(x) critic = Model(inputs=[action_input, observation_input], outputs=x) print(critic.summary()) # Experience Bufferの設定 memory = SequentialMemory(limit=100000, window_length=1) # 行動選択時に加えるノイズ(探索のため) # 平均回帰課程を用いている。単純にノイズが、muに収束していく。 # ここでは、mu=0に設定しているので、ノイズはゼロになっていく。つまり、探索を行わなくなる。 random_process = OrnsteinUhlenbeckProcess(size=nb_actions, theta=.15, mu=0., sigma=.3) # DDPGエージェントの設定 agent = DDPGAgent(nb_actions=nb_actions, actor=actor, critic=critic, critic_action_input=action_input, memory=memory, nb_steps_warmup_critic=100, nb_steps_warmup_actor=100, random_process=random_process, gamma=.99, target_model_update=1e-3) agent.compile(Adam(lr=.001, clipnorm=1.), metrics=['mae']) # エージェントの学習 # visualizeで学習中のゲーム画面を表示するか。verboseで学習プロセスの表示をするかを設定できる history = agent.fit(env, nb_steps=50000, visualize=False, verbose=1, nb_max_episode_steps=200) # 学習曲線のプロット history = history.history plt.plot(np.arange(len(history["episode_reward"])), history["episode_reward"]) # 学習済みモデルのパラメータの読み込み # agent.load_weights('ddpg_{}_weights.h5f'.format(ENV_NAME)) # 学習したモデルのパラメータの保存 agent.save_weights('ddpg_{}_weights.h5f'.format(ENV_NAME), overwrite=True) # 評価 agent.test(env, nb_episodes=5, visualize=False, nb_max_episode_steps=200)
上述したコードを実行すると、 下記のような学習曲線をプロットします。
学習が進むにつれて、得られる報酬が向上しているのがわかります。
コメント