LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 5 years have passed since last update.

ゲームの強化学習ハンズオン -- OpenAI Gymで強化学習入門 その2(機械学習名古屋第16回勉強会)

Last updated at Posted at 2018-06-22
1 / 34

初めに


おさらい:強化学習とは


reinforcement_2.png


強化学習とは

  • 変化する 環境 下で判断・ 行動 し課題を解決する問題を扱う
  • (一連の)行動に対して得られる 報酬 を元に、ある 状態 における 次の行動学習 して獲得していく

事例:自動運転


Duckietown_self_driving_car_simulator_environments_for_OpenAI_Gym_by_hardmaru.png


事例:ゲーム

vlcsnap-2018-04-16-22h38m05s417.png


基礎概念

  • 状態:S(Observation の略で obs とすることも)
  • モデル:TT(s,a,s')
  • 行動:AA(s)
  • 報酬:RR(s)/R(s,a)/R(s,a,s')

おさらい:OpenAI Gym


OpenAI Gym

  • OpenAI Gym
  • 強化学習用ツールキット。統一インターフェースを提供
  • いくつかのシミュレーション環境(ゲーム等)を用意

OpenAI Gym の 環境 (Env)

env = gym.make(env_name)  # 環境構築(読込)
env.reset()               # 初期化 状態を取得
env.render()              # 可視化
env.step(action)          # 行動を行う 状態・報酬などを取得
env.close()               # 終了

大事なのは↓の2つ

  • 環境から状態(Sobs)を取得
  • 環境に対して行動(step) → 結果の状態(obs)と報酬(R)を返す

OpenAI Gym で強化学習

  • モデル T を構築
  • 行動 A を選択
  • Gym の環境に対して 行動 A を送り、状態 S や 報酬 R を受け取って、モデル T を学習

ハンズオン


ハンズオン環境

  • Python 3.5以上(3.6以上推奨)
  • OpenAI Gym(CartPole-v0 環境)
  • ChainerRL

ハンズオン環境補足

  • Linux / macOS:基本的に OpenAI Gym の README の手順通りに環境を作成できていればOK
  • Windows:以下のいずれかの方法
    • VirtualBox 等の仮想環境上に Linux 環境を構築
    • WSL(+ Linux) + XServer 環境を構築(補足資料
    • Docker(制限あり)

ハンズオン0:準備

  • OpenAI Gym 等の準備は省略(別資料等参照ください)
  • 今回も 勉強会用 Git リポジトリ を用意しています(↓適当なディレクトリで以下のコマンドを実行して clone してください)
$ git clone https://github.com/mlnagoya/MLN_201806

動作確認。

python -V の実行結果が Python 3.x.x と表示されるなら(その環境下に OpenAI Gym をインストールしていれば)以下の python3python と読み替えてください。

$ python3 handson_dqn.py --train-episodes=20 --outdir=_output20

エラーが起きたら後述の「トラブルシューティング」参照


ハンズオン1:パラメータ調整

$ python3 handson_dqn.py -h
usage: handson_dqn.py [-h] [--outdir OUTDIR] [--gamma GAMMA]
                      [--final-exploration-steps FINAL_EXPLORATION_STEPS]
                      [--start-epsilon START_EPSILON]
                      [--end-epsilon END_EPSILON]
                      [--replay-buffer REPLAY_BUFFER]
                      [--replay-start-size REPLAY_START_SIZE]
                      [--target-update-interval TARGET_UPDATE_INTERVAL]
                      [--update-interval UPDATE_INTERVAL]
                      [--train-episodes TRAIN_EPISODES]
                      [--max-episode-len MAX_EPISODE_LEN]
                      [--test-episodes TEST_EPISODES]

optional arguments:
  -h, --help            show this help message and exit
  --outdir OUTDIR       出力ファイル保存先ディレクトリ。 存在しなければ自動生成されます。 (default: _output)
  --gamma GAMMA         割引率 (default: 0.95)
  --final-exploration-steps FINAL_EXPLORATION_STEPS
                        探索ステップ数 (default: 10000)
  --start-epsilon START_EPSILON
                        ε-greedy法 の開始ε値 (default: 1.0)
  --end-epsilon END_EPSILON
                        ε-greedy法 の終了ε値 (default: 0.1)
  --replay-buffer REPLAY_BUFFER
                        Experience Replay のバッファサイズ (default: 1000000)
  --replay-start-size REPLAY_START_SIZE
                        replay-start-size (default: 500)
  --target-update-interval TARGET_UPDATE_INTERVAL
                        target-update-interval (default: 100)
  --update-interval UPDATE_INTERVAL
                        update-interval (default: 1)
  --train-episodes TRAIN_EPISODES
                        訓練エピソード数 (default: 200)
  --max-episode-len MAX_EPISODE_LEN
                        1回のエピソードの最大ステップ数 (default: 2000)
  --test-episodes TEST_EPISODES
                        検証エピソード数 (default: 10)

コマンドライン引数で各種パラメータを弄ってみる。

例:

  • --gamma=0.99(割引率)
  • --train-episodes=500(訓練エピソード数)

ハンズオン2:実装修正

  • handson_dqn.py(本体)
  • util
    • qfunctions.py(Q関数)
    • explorers.py(戦略)
    • replay_buffer.py(リプレイバッファ)

qfunctions.py(抜粋)

qfunctions.py(抜粋)
# :

class MyQFunction(chainer.Chain):
    """
    Q^*をDNNを使って近似する(別実装)
    """
    def __init__(self, obs_size, n_actions):
        # TODO: 必要なら引数を追加して、QFunction3LP の実装を参考にネットワークを構築する
        raise NotImplementedError

    def __call__(self, obs, test=False):
        # TODO: QFunction3LP の実装を参考にネットワーク適用を実装する
        raise NotImplementedError
  • 自分で実装してみる!

explorers.py(抜粋)

explorers.py(抜粋)
# :

class ConstantEpsilonGreedy(explorer.Explorer):
    """ε-greedy 法(ε固定)"""

    def __init__(self, epsilon, random_action_func):
        assert epsilon >= 0 and epsilon <= 1
        self.epsilon = epsilon
        self.random_action_func = random_action_func

    def select_action(self, t, greedy_action_func, action_value=None):
        return select_action_epsilon_greedily(
            self.epsilon, self.random_action_func, greedy_action_func)

    def __repr__(self):
        return 'ConstantEpsilonGreedy(epsilon={})'.format(self.epsilon)
  • 実装を弄ってみる!

replay_buffer.py(抜粋)

replay_buffer.py(抜粋)
# :

class BestReplayBuffer(SimpleReplayBuffer):
    """報酬の高いものを優先的に記憶する ReplayBuffer"""

    def __init__(self, capacity=1000):
        super().__init__(capacity)

    # TODO: より報酬の高いものを優先的に残すような実装をする
    # def append(self, state, action, reward, next_state=None, next_action=None, is_state_terminal=False):
    #     pass
  • 自分で実装してみる!

handson_dqn.py(抜粋)

from util.qfunctions import QFunction3LP as QFunction
# from util.qfunctions import MyQFunction as QFunction
# ↑ココ

# : 《中略》

def get_agent(env, args):
    # : 《中略》

    # Use epsilon-greedy for exploration
    # explorer = ConstantEpsilonGreedy(
    #     epsilon=args.start_epsilon,
    #     random_action_func=env.action_space.sample)
    explorer = LinearDecayEpsilonGreedy(
        args.start_epsilon, args.end_epsilon, args.final_exploration_steps,
        random_action_func=action_space.sample)
    # ↑ココ

    # Experience Replayの設定
    replay_buffer = SimpleReplayBuffer(capacity=args.replay_buffer)
    # replay_buffer = BestReplayBuffer(capacity=args.replay_buffer)
    # ↑ココ

# : 《後略》

  • 実装変更を反映して、学習させてみる!

ハンズオン(その後)

  • ChainerRL に用意されている他のアルゴリズム・手法等も試してみる
  • OpenAI Gym の他の環境でも試してみる
  • Gym に登録されていない環境(例:自動運転シミュレータとか)も試してみる

補足


Q関数(おさらい)

  • $Q^*(s,a)$:状態$s$で行動$a$をとったときの割引累積報酬の最大値
  • Q学習:このQ関数を機械学習で学習(≒モデルを学習)
  • DQN:Q関数をDNNで近似(して学習)

ε-greedy 法

  • 行動選択戦略:
    • $0.0 \le \varepsilon \le 1.0$
    • $\varepsilon$ の確率で行動をランダムに選択
    • $1-\varepsilon$ の確率で Q値 が最大となる(過去の)行動を選択
  • $\varepsilon$ を固定化(例:$\varepsilon=0.3$)するも良し、減衰(例:初期値$\varepsilon=1.0$、10000ステップ後に$\varepsilon=0.1$、線形に変化)するも良し
    • ConstantEpsilonGreedy/LinearDecayEpsilonGreedy

Experience Replay(経験再生)

  • データごとの相関をなくすための手法:
    • 過去の経験(≒「状態」「行動」「報酬」(など)の組合せ)を記憶しておく
    • その中からランダムに選択して学習に利用する
  • SimpleReplayBuffer:過去の経験を出来るだけ多く記憶、制限を超えたら古いものから忘却、記憶している「経験」を乱択
  • 少し賢く:
    • BestReplayBuffer:成績の良い経験を優先的に記憶、経験の乱択を従来通り
    • PrioritizedReplayBuffer:成績で優先順位を付けておき、乱択時に優先順位の高いものが高確率で選択されるようにする

トラブルシューティング


学習・テストの様子がGUIで表示されない

  • Docker 利用の場合:仕様です
  • Windows + WSL 利用時:
    • エラーが出ている:XServer との連携設定がうまくいってない可能性が高いです。DISPLAY 環境変数の値を見直してみましょう
    • 固まっている:Python と OpenGL との相性問題かも。XServer 起動時に「ネイティブの OpenGL(WinGL)を利用しない」設定にして再度試してみてください
  • Linux / macOS の場合:Python / OpenAI Gym / その他依存ライブラリの再インストールが必要かも…

学習はうまくいくがテスト開始時にエラーで落ちる

  • gym.wrappers.Monitor を利用して動画保存するために必要な ffmpeg がたぶんインストールされていません。
    • Linux(Ubuntu)の場合:sudo apt install ffmpeg(他のディストリビューションでも同様)(バージョンによっては sudo add-apt-repository ppa:〜 が必要、詳細はググってくださいm(_ _)m)
    • macOSの場合:brew install ffmpeg
    • もし Anaconda を利用していたら:conda install ffmpeg
  • ffmpeg 入ってるのにうまくいかない:ffmpeg へのパスが通っているか確認しましょう
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