F1大好きな、インチキ技術者の日記

F1大好きなインチキ技術者が情報を発信して、自分を変えようとしている日記です

SageMaker Studio Labで強化学習を行ってみた

目標

  • SageMaker Studio Labが公開されたので使ってみる

    • Google Colabと違い、現時点ではroot権が必要なインストールをサポートしていないので、仮想ディスプレイ(xvfb)は利用できないのがつらいです stackoverflow.com
  • Keras-RLを用いてMountainCar-v0を強化学習する

    • まずは、動いて強化学習できれば目標達成とする

MountainCar-v0 について

谷底にあるAgentの車が、200ステップ以内に画面右上の旗のところにつけばクリア!

でも、車のエンジンは一気に山を登り切るパワーはありません (ホンダのPUにすれば一気に・・・)。 と言うわけで成功するには左側の山に登って、勢いよく下ってから右の山を登る必要があります。

Reward, Observation, Actions などは以下の公式ページに記載があります。 github.com

学習開始!

必要なモジュールのインストールとimportを実行します。

インストール

%pip install gym
%pip install keras-rl2

import

import gym
from gym import wrappers
from numpy.lib.function_base import average
from tensorflow.keras.models import Sequential,load_model
from tensorflow.keras.layers import Dense, Activation, Flatten
from tensorflow.keras.optimizers import Adam
from rl.agents.dqn import DQNAgent
from rl.policy import BoltzmannQPolicy, EpsGreedyQPolicy
from rl.memory import SequentialMemory

TensorFlowのバージョンを確認します。

2021/12/03 に試した時は、以下のバージョンが導入されていました。現時点での最新版ですね。

import tensorflow as tf
tf.__version__
'2.7.0'

学習時のコールバック関数

学習結果をグラフ化するために、各ステップの情報を記憶するCallbackを実装します。今回はエピソードごとの報酬をグラフにしています。

import rl.callbacks
class EpisodeLogger(rl.callbacks.Callback):
    def __init__(self):
        self.rewards = {}

    def on_episode_begin(self, episode, logs):
        self.rewards[episode] = 0.0
 
    def on_step_end(self, step, logs):
        episode = logs['episode']
        self.rewards[episode] = self.rewards[episode] + logs['reward']
cb_ep = EpisodeLogger()

パラメーターを指定

学習回数や環境(MountainCar-v0)、モデルの保存場所指定します。

limit_steps =  50000
nb_episodes = 5
env_name = 'MountainCar-v0'
notebook_root = "/home/studio-lab-user"

#ファイルやモデルの保存場所
title_name = f"{notebook_root}/{env_name}_{str(limit_steps)}"
model_path = f"{notebook_root}/{env_name}/model/"

モデルの保存ディレクトリを作成

import os
os.makedirs(model_path,exist_ok=True)

環境の作成

env = gym.make(env_name)
nb_actions = env.action_space.n #有効なaction数

モデルの定義

IN

車の速度、車の場所

OUT

車のアクション 左、何もしない、右

# モデルの定義
model = Sequential()
model.add(Flatten(input_shape=(1,) + env.observation_space.shape))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(nb_actions))
model.add(Activation('linear'))

学習環境の作成

  • ポリシーの指定
  • epsilon-greedy を指定。
  • Keras-RLには他にもポリシーがあります。
    • LinearAnnealedPolicy, SoftmaxPolicy, EpsGreedyQPolicy, GreedyQPolicy, BoltzmannQPolicy, MaxBoltzmannQPolicy, BoltzmannGumbelQPolicy
  • 学習の設定
  • DQN(Deep Q-Network)を採用、オプションでDDQNなども利用可能。 Experience Replay用のメモリ
  • DNNの学習を安定させるために用いられる仕組み。
  • DNNは時系列に相関があるデータをその順番のまま使うとうまく学習できないらしく、後でランダムにデータを読み込んで学習を行う方法。
# Experience Replay用のメモリ設定
memory = SequentialMemory(limit=limit_steps, window_length=1)

# ポリシーの作成
policy = EpsGreedyQPolicy()

# DQN Agentの作成
dqn = DQNAgent(model=model,
               nb_actions=nb_actions,
               memory=memory, 
               nb_steps_warmup=10,
               target_model_update=1e-2,
               policy=policy)

# コンパイル
dqn.compile(Adam(learning_rate=1e-3), metrics=['mae'])

学習開始!

ちなみに、visualize=False にしないとエラーになります。描画対象の画面がないからです。 (Google Clabだと、仮想ディスプレイ使えるからmp4で保存できるんですが。)

dqn.fit(env, nb_steps=limit_steps, visualize=False, verbose=2, callbacks=[cb_ep])

学習成果を確認する

matplotlibをインストールします。

%pip install matplotlib

Callbackで保持していたエピソードごとのReward(報酬)をグラフにする

import matplotlib.pyplot as plt
plt.figure(figsize=[16,9])
plt.plot(list(cb_ep.rewards.keys()), list(cb_ep.rewards.values()))
plt.xlabel("Episode")
plt.ylabel("Reword")
plt.title(title_name)
plt.show()

f:id:hanamiche:20211203225548p:plain
10万ステップ学習したときの報酬
150エピソードあたりから少しずつクリアする回数が多くなり、300エピソードくらいから安定してクリアしてくる様子が見て取れます。

学習済みモデルを用いてテスト

うまく旗までたどり着くかな・・・

# モデルをテスト
dqn.test(env, nb_episodes=nb_episodes, visualize=False, callbacks=[cb_ep])

5エピソード分テストしましたが、すべて-200以上なので、2000step以内に山を登って旗に到達しています!

Testing for 5 episodes ...
Episode 1: reward: -147.000, steps: 147
Episode 2: reward: -143.000, steps: 143
Episode 3: reward: -155.000, steps: 155
Episode 4: reward: -146.000, steps: 146
Episode 5: reward: -150.000, steps: 150

とりあえず、SageMaker Studio Labで強化学習を実施することができました。 ローカルの環境やGoogle Colabでは、以下のように実際車が山を登るところを確認できます。Google Colab版のコードは別途アップ予定です。

f:id:hanamiche:20211203230721g:plain
5,000ステップ学習後
f:id:hanamiche:20211203230809g:plain
100,000ステップ学習後

番外編

モデルの保存

うまく行ったらモデルを保存します。overwrite=Falseをつけることで、意図しない上書きを防止しています。

save_model_name = "save_test"
dqn.model.save(model_path + save_model_name,overwrite=False)

モデルの読み込み

学習済みのモデルをロードもできます。

load_model_name = "model100000"
print("モデル取得場所: {0}{1}".format(model_path,load_model_name))

# モデルの読み込み
model=load_model(model_path + load_model_name)

あとは、以下のように読み込んだmodelをDQNAgentに渡せばよいです。

# テスト動画保存先
env_test = gym.make(env_name)

# エージェントの設定
memory = SequentialMemory(limit=limit_steps, window_length=1)

dqn = DQNAgent(model=model,
               nb_actions=nb_actions,
               memory=memory)

dqn.compile(Adam(lr=1e-3), metrics=['mae'])

# モデルをテスト
dqn.test(env_test, nb_episodes=nb_episodes, visualize=False, callbacks=[cb_ep])

今後の課題

  • 動いたけど、強化学習とは何かがわかっていない。
    • Q学習からの学習だな・・・そのあとDQNか・・・道のりは長い。
  • SageMaker Studio Labの今後の発展に期待しています。Google Colabに比べて動作は早いように感じました。
  • ソースはgitにもアップする予定です。
プライバシーポリシー・問合せ