26 Jun 2017, 13:33

OpenAI Gym の CartPole 問題が Q-Learning で解けたぞ

CartPole 問題は、今までこのブログでもなんども取り上げてきた。

CartPole 問題は、今までこのブログでもなんども取り上げてきた。 - [[http://futurismo.biz/archives/6481][OpenAI Gym の CartPole-v0 を試したメモ | Futurismo]] - [[http://futurismo.biz/archives/6549][CEM で CartPole-v0 を試したメモ | Futurismo]]

今日、ついに解けたのだ。

とくに、最後のリンクは、Reinforcement Learning のチュートリアルがまとまっている良リポジトリ。 この場を借りて、紹介したい。

課題

環境から取得できる情報は次の 4 つ。(observation_space) - 横軸座標(x) - 横軸速度(x_dot) - ポール角度(theta) - ポール角速度(theta_dot)

エージェントが取れる行動は環境状態によらず次の 2 つ。(acnton_space) - 左に動く - 右に動く

課題は、環境から取得できる値が連続値であること。 Q テーブル(状態、行動)対に対して一つの値を扱う。

つまり、連続値である状態を範囲で区切って離散の値に変換して、Q テーブルのインデックスに用いることが必要。

ここでは gdb さんのコード を参考に以下のように書いた。

def build_state(features):
    """get our features and put all together converting into an integer"""
    return int("".join(map(lambda feature: str(int(feature)), features)))

def to_bin(value, bins):
    return np.digitize(x=[value], bins=bins)[0]

cart_position_bins = np.linspace(-2.4, 2.4, 2)
cart_velocity_bins = np.linspace(-2, 2, 10)
pole_angle_bins = np.linspace(-0.4, 0.4, 50)
pole_velocity_bins = np.linspace(-3.5, 3.5, 20)

def transform(observation):
    # return an int
    cart_pos, cart_vel, pole_angle, pole_vel = observation
    return build_state([
        to_bin(cart_pos, cart_position_bins),
        to_bin(cart_vel, cart_velocity_bins),
        to_bin(pole_angle, pole_angle_bins),
        to_bin(pole_vel, pole_velocity_bins)
    ])

これで、transform を呼ぶと、ovservation に対して一意な離散値が出力されるので、それを状態値として扱う。

注目すべきは、ここ。横軸座標(x)は荒く、ポール角度は細かく値を区切っている。こうすると精度がよかったのでこうしている。

cart_position_bins = np.linspace(-2.4, 2.4, 2)
cart_velocity_bins = np.linspace(-2, 2, 10)
pole_angle_bins = np.linspace(-0.4, 0.4, 50)
pole_velocity_bins = np.linspace(-3.5, 3.5, 20)

Code

このコードは、Practical RL の week2 の宿題である。

以下を参考にした。 - Berkeley’s CS188 pacman project code http://ai.berkeley.edu/ - Victor Mayoral Vilches’s RL tutorial https://github.com/vmayoral/basic_reinforcement_learning - gdb openAI https://gym.openai.com/evaluations/eval_aHf1Kmc4QIKm5oPcJJToBA

Result

14 Jun 2017, 11:36

三目並べ(tic-tac-toe) にモンテカルロ法を試した

三目並べ(tic-tac-toe) をモンテカルロ法をつかって学習させました。

元ネタは、これ。

この本のコードは Octave でかかれているのだけれども、それを Python にポーティングしてくれた人がいた。

自分はなにをしたかというと、このコードを OpenAI Gym の tic-tac-toe に対応させてみた(tic-tac-toe は非公式)

ただ移しただけだと動かなかった。それから 10 時間くらいでばっくをしていた。頭がおかしくなる。

コード

おまけ: プルリク奮戦記

じつは、OpenAI Gym の tic-tac-toe リポジトリにバグっぽいのをみつけた。

ピンチ!いやチャンス?

自分は他人の Github リポジトリにプルリクをしたことがないのだ。

まずは気さくな感じを醸し出して質問をしてみた。Hello!! :-)

1 分も立たずに返信が帰ってきたのでビビる。はえーよ!

feel free to provide a PR!!

もうこの言葉が理解できずにガクガクした。なにかへんな英語表現を使っちゃったかな??

大丈夫、PR は Pull Reqest のことだ。って、ぅえ〜〜〜〜〜。やったことないよ〜〜〜。

プルリクエストの作法を調べる。

  1. branch 経由
  2. fork repository 経由

検索上位に引っかかるのは、初心者は branch を切る方法が勧められている。

  1. 初心者向け Github への PullRequest 方法 - Qiita
  2. Pull Request の仕方 - Qiita

バカだから何を思ったのか、fork ポタンをポチリ。。。。。fork してしまったぁぁ!!!

とりあえず、バグの修正をして、fork した自分のリポジトリに push

そして、GUI 画面から PULL REQUEST !!!!

ふう、まつこと数分・・・ 10 分でレスポンスが帰ってきた。もう心臓に悪りーよ。

  • コメントの単語が適切でない
  • 冗長な for 文の回し方をしている

その通りです、なにもいうことはありません。 こっちも急いで修正して、再コミット!!

祈った。。。そうして待つこと 15 分、ついに Merge されました〜〜〜〜!!!

うらららららららららら〜〜〜〜〜〜〜!

10 Jun 2017, 07:49

実践的な強化学習のオンライン学習教材、Practical RL をはじめた

実践的な強化学習の教材、Practical RL をやりはじめた。

これはなに

HSE と Yandex SDA というロシアの大学?で教えられている強化学習のコースが、 オンライン学習のために英語とロシア語で公開されている。

教材は、オンラインで強化学習をするためのリソースのいいとこどりをしている。

各週のディレクトリに動画や pdf のリンクがかかれた README がある。

また、”実践” とつくだけに、各週の課題が Jupyter Notebook で与えられ、OpenAI Gym を活用する。

fast.ai の講座 が予想以上によかったので、実践的とかかれると期待してしまう。

強化学習のコースなのだが、最近の動向に合わせ Deep Learning(DQN) の内容も盛り込まれている。

Deep Learning のためのライブラリは、Lasagne というライブラリが推奨されている。 しかし、Tensorflow 版の課題ノートも公開されている。

シラバス

github の README から抜粋。詳しくは、元サイトへ。

前半で、強化学習の話題をカバーしている。中盤で、Deep Learning の話題が出てくる。後半はよくわからない。

week0 Welcome to the MDP
week1 Crossentropy method and monte-carlo algorithms
week2 Temporal Difference
week3 Value-based algorithms
week4 Approximate reinforcement learning
week5 Deep reinforcement learning
week6 Policy gradient methods
week6.5 RNN recap
week7 Partially observable MDPs
week 8 Case studies 1
week 9 Advanced exploration methods
week 10 Trust Region Policy Optimization.
week 11 Model-based RL: Planning

他のコースとの比較

他のコースと比較検討して Practical RL を進めようと思ったので、その理由も書いておく。

Practical RL のデメリットは、課題 の解答が公開されていないところ。

fork している人のリポジトリを覗いて自分の解答と照らし合わせようかと思ったけれども、 参考になりそうなリポジトリがあまり見つからなかった。

ということで、自分は途中で挫折する可能性が高いので、 このコースに挫折したら次にやることも考えておく。

Learning Reinforcement Learning - WildML

強化学習の主要な話題が Jupyter Notebook と共に提供されている。うれしいことに、解答付きだ。

ただいま作成中のようなのと、学ぶ方法が Sutton 本を読むことに偏っていたのでやめた。

しかし、Practical RL に行き詰まったらこっちにシフトしようかと考えている。

UCL Course on RL

ユニバーシティ・カレッジ・ロンドンの強化学習の講義資料

この動画は、Practical RL の中で何度も引用されていてみることが進められている。

なので、Practical ML を進めたらこの講義内容はカバーできるのと、 課題が見つからなかったので止めた。

追記: 2016 年のページ見つけた。課題もしたのほうにある。

CS 294: Deep Reinforcement Learning, Spring 2017

UC Barkeley の Deep Learning と強化学習を学ぶ講義資料。

強化学習に Deep Learning を使う。ライブラリは Tensorflow.

講義動画がしっかりそろっている。

課題は 4 つある。掲示板も Reddit を使っていて課題につまったときは検索できそう。

これを選ばなかった理由は、Practical RL よりも難しそうな印象を受けたから。 Deep Learning も 強化学習もわからないのに、それを合わせた内容をバンバン紹介されても消化できなさそうだ。

また 、Practical RL からもこのコースの動画や課題(hw3)が紹介されていたので、 うまくつまみぐいできるかと思ったから。

UC Barkeley CS294 Deep Reinforcement Learning

2015 年の Barkeley の Deep Reinforcement Learning

2017 年版の元になったコースだ。内容は、短くまとまっている(4つ??)

UC Berkeley CS188 Intro to AI

2014 年の Berkeley の AI コース。

レクチャー動画や課題はしっかりしている。Project もおもしろそうだ。

扱っているものは、基本的なもので Deep うんたらはでてこないので少し古さは感じる。

An introduction series to Reinforcement Learning (RL) with comprehensive step-by-step tutorials.

Git-Base のチュートリアリル。提供元団体不明。個人かな?

このチュートリアルも作成中のようだが、前半はほぼ完成している。

README とコードベースのチューとリアルなので、 それほど英語力や数学力を求められない、今までで一番やさしそうな印象を受ける。

扱っている話題は、Q-Learning, OpenAI Gym, DQN, Deep Convolutional Q-Learning, ROS などなど、おもしろそうなものばかりだ。

Udacity Reinforcement Learning

MOOC の大御所 Udacity が提供しているコース。

短い動画がたくさんある。二人の掛け合いによって動画が進んでいき、 とっつきやすい感じはある。

課題はなく、短いので、理解が足りないところを補足する目的で見てもみてもいいかも。

Reinforcement Learning: An Introduction - Richard S. Sutton and Andrew G. Barto

言わずと知れた、強化学習のバイブル。これを腰を据えて読むのがいいのかも。

第2版には、サンプルコードが提供されているようだ。ただし、解答はなし。

Udemy Artificial Intelligence A - Z

Udemy の AI コースも, 最新の話題を扱っている。セールのときに 1200 円で買った。

Module 1: "Self Driving Car"
Module 2: "Deep Convolutional Q-Learning"
Module 3: "A3C"

なんと、フレームワークは Pytouch を使う。

  • Module1 では、シミュレータ上の車のライントレースを DQN で行う。
  • Module2 では、OpenAI Gy 上で Deep Convolutional Q-Learning を学ぶ。
  • Module3 では、A3C という発展的な話題を扱う。

これで、1200 円だ。安いと思う。

Simple Reinforcement Learning with Tensorflow

TensorFlow による 強化学習の実装チュートリアル。

以下は内容。コードはここ https://github.com/awjuliani/DeepRL-Agents

  • Part 0 — Q-Learning Agents
  • Part 1 — Two-Armed Bandit
  • Part 1.5 — Contextual Bandits
  • Part 2 — Policy-Based Agents
  • Part 3 — Model-Based RL
  • Part 4 — Deep Q-Networks and Beyond
  • Part 5 — Visualizing an Agent ’ s Thoughts and Actions
  • Part 6 — Partial Observability and Deep Recurrent Q-Networks
  • Part 7 — Action-Selection Strategies for Exploration

09 Jun 2017, 23:09

OpenAI Gym FrozenLake-v0 に 遺伝的アルゴリズム(deap)を試す

タイトルのとおり、OpenAI Gym FrozenLake-v0 に遺伝的アルゴリズムを試しました。

遺伝的アルゴリズム

遺伝的アルゴリズムとは

遺伝的アルゴリズム(genetic algorithm, 略して GA)とは、 組み合わせ問題の最適解を求めるためのアルゴリズム。

具体的には、以下の 2 〜 4 を繰り返すアルゴリズム。

1. 初期設定
2. 選択
3. 交叉
4. 突然変異

詳しくは、他のサイトに説明は譲る。この記事がわかりやすかった。

Python で遺伝的アルゴリズムやるなら Deap

Python で遺伝的アルゴリズムやるなら Deap というライブラリがある。

遺伝的アルゴリズムにも、選択、交叉、突然変異にいろいろな酒類がある。

この辺の話は, Wikipedia が詳しい。

それらをうまく抽象化して扱えるのがこのライブラリ。

解説記事はネット上にたくさんあるのだが OneMax 問題を扱っているものが多い。

なので、OpenAI の FrozenLake-v0 を題材に Deap を使ってみた。

FrozenLake-v0

GA の前に乱数を発生させて、そのポリシーにしたがって進んでいく例を書く。

結果は、こちら。https://gym.openai.com/evaluations/eval_iinFj8fUSvOOYHWXwjjAw

Score が 0.56 で、基準の 0.78 をオーバーしていない。

deap を使った GA

結果は、こちら。https://gym.openai.com/evaluations/eval_uU3CIG5yTgOhOXVM8EG3wA

Score が 0.81 と、基準値をなんとかクリアした。

deap をつかわない GA

結果は、こちら。https://gym.openai.com/evaluations/eval_YpHI9YmhQoSGcKMI1dFsw

なんと Score は 0.91 だ。

ということは、自分の deap をつかった実装はどこかバグってるなぁ?!

09 Jun 2017, 07:18

OpenAI Gym の CartPole-v0 を試したメモ

OpenAI Gym を試してみたメモです。

CartPole-v0 というゲームを動かしてみました。

OpenAI Gym

OpenAI Gym とは

OpenAI Gym is a toolkit for developing and comparing reinforcement learning algorithms.

OpenAI Gym は、強化学習アルゴリズムを開発し評価するためのツールキット。

  • gym … python テスト環境ライブラリ.
  • OpenAI Gym service … エージェントのパフォーマンスを評価するサービス。

ちょっとわかりにくいが、自分の解釈では、 いろんなゲームをプレイする環境が提供されていて、 自分の AI エージェントをつくってゲームをプレイして遊べるツール。

どんなゲーム(環境)があるの?

三目並べからシューティングゲーム、囲碁まである。詳しくは、以下。

Open AI Gym ライブラリのインストール

OpenAI Gym を pip でいれる。

pip install gym

以下のジャンルのゲームができるようになる。

  • algorithmic
  • toy_text
  • classic_control

CartPole で遊ぼう

公式のチュートリアルで紹介されている CartPole というゲームを触ってみる。

CartPole 問題

CartPole 問題は、強化学習の古典的問題らしい。

棒(pole)が動く台車(cart)の上に立っている。 棒は倒れるので、台車を右か左に動かして倒れないようにする。 より長く棒を直立させることが目的。

以下は、ルールの Google 日本語翻訳。

ポールは、作動していないジョイントによって、摩擦のないトラックに沿って動くカートに取り付けられる。システムは、カートに+1 または-1 の力を加えることによって制御される。振り子が起立して、それが転倒するのを防ぐことが目標です。ポールが直立したままのタイムステップごとに+1 の報酬が与えられます。エピソードは、ポールが垂直から 15 度を超えると終了するか、またはカートが中心から 2.4 ユニット以上移動すると終了します。
  • 1step の間に直立 h していれ報酬を 1 もらえる
  • 右(+1) or 左(-1)の行動を選択できる
  • 棒が 15 度傾くとゲームオーバー
  • 台車が中心から一定距離(2.4unit???) とゲームオーバー

コードを調べる

公式ドキュメントに乗っているコードを見ていく。

import gym
env = gym.make('CartPole-v0')
for i_episode in range(20):
    observation = env.reset()
    for t in range(100):
        env.render()
        print(observation)
        action = env.action_space.sample()
        observation, reward, done, info = env.step(action)
        if done:
            print("Episode finished after {} timesteps".format(t+1))
            break

まずは、gym というライブラリをインポートする。

gym.make(“環境名”) で動かす環境(env)を生成する。ここでは、CartPole-v0 を指定。

import gym
env = gym.make('CartPole-v0')

env の 3 つの主なメソッドは、

  • reset() - 環境(environment)をリセットする。最初の 観測(observation) を返す。
  • render() - 現在の環境の状態をレンダリングする。
  • step(a) - 行動(action)を実行し、以下を返す(new observation, reward, is done, info)
    • new observation - 行動を実行したあとの観測
    • reward - 報酬
    • is done - ゲームが終了したら True, 続いているなら False
    • info - 詳細情報

for 文で 20 エピソード分を実行する。

env.render()で以下のような図を表示する。

env.reset()を実行すると、以下の numpy 配列が帰ってくる。

# [position of cart, velocity of cart, angle of pole, rotation rate of pole]
array([-0.01717682,  0.00789496,  0.03295495, -0.0202679 ])

env.observation_space で、観測状態、env.action_space で、行動がそれぞれ帰ってくる。

Box は、n-次元の Box を、Discrete は固定された範囲の非負の数をそれぞれ表す。

print("observations:", env.observation_space)
print("actions:", env.action_space)
observations: Box(4,)
actions: Discrete(2)

CartPole-v0 では、observation は 4 次元の配列, action は 0 or 1 の数。

以下で、observation_space の上限、下限が分かる。

print(env.observation_space.high)
#> array([ 2.4       ,         inf,  0.20943951,         inf])
print(env.observation_space.low)
#> array([-2.4       ,        -inf, -0.20943951,        -inf])

以下で、action_space の数が分かる。

print(env.action_space.n)
#> 2

env.action_space.sample()で、action をランダムに選択できる。

env.action_space.sample()
#> 0
env.action_space.sample()
#> 1
env.action_space.sample()
#> 1

step()関数に action を渡すことで、action を実行できる。

done が True になるまで繰り返す。reward には、1.0 が入る。

結果を記録、アップロード

以下のように、wrappers.Monitor(env, ‘/tmp/cartpole-experiment-1’)を使うと、 実行結果を記録することができる。

import gym
from gym import wrappers
env = gym.make('CartPole-v0')
env = wrappers.Monitor(env, '/tmp/cartpole-experiment-1')
for i_episode in range(20):
    observation = env.reset()
    for t in range(100):
        env.render()
        print(observation)
        action = env.action_space.sample()
        observation, reward, done, info = env.step(action)
        if done:
            print("Episode finished after {} timesteps".format(t+1))
            break

以下のような mp4 の動画と meta 情報の json がディレクトリに作成される。

$ ll /tmp/cartpole-experiment-1
合計 32K
-rw-rw-r-- 1 tsu-nera tsu-nera  817  6 月  9 15:59 openaigym.episode_batch.0.13181.stats.json
-rw-rw-r-- 1 tsu-nera tsu-nera  412  6 月  9 15:59 openaigym.manifest.0.13181.manifest.json
-rw-rw-r-- 1 tsu-nera tsu-nera 2.0K  6 月  9 15:58 openaigym.video.0.13181.video000000.meta.json
-rw-rw-r-- 1 tsu-nera tsu-nera 4.0K  6 月  9 15:58 openaigym.video.0.13181.video000000.mp4
-rw-rw-r-- 1 tsu-nera tsu-nera 2.0K  6 月  9 15:58 openaigym.video.0.13181.video000001.meta.json
-rw-rw-r-- 1 tsu-nera tsu-nera 3.9K  6 月  9 15:58 openaigym.video.0.13181.video000001.mp4
-rw-rw-r-- 1 tsu-nera tsu-nera 2.0K  6 月  9 15:58 openaigym.video.0.13181.video000008.meta.json
-rw-rw-r-- 1 tsu-nera tsu-nera 3.8K  6 月  9 15:58 openaigym.video.0.13181.video000008.mp4

以下のようなスクリプトを実行すると、OpenAI Gym に結果をアップロードできる。

import gym
gym.upload('/tmp/cartpole-experiment-1',api_key='<api key>')

api_key は、OpenAI Gym にログインすると得られる。

$ python carpole_upload.py
[2017-06-09 16:09:39,697] [CartPole-v0] Uploading 20 episodes of training data
[2017-06-09 16:09:48,712] [CartPole-v0] Uploading videos of 3 training episodes (9058 bytes)
[2017-06-09 16:09:49,232] [CartPole-v0] Creating evaluation object from /tmp/cartpole-experiment-1 with learning curve and training video
[2017-06-09 16:09:49,618] 
****************************************************
You successfully uploaded your evaluation on CartPole-v0 to
OpenAI Gym! You can find it at:

    https://gym.openai.com/evaluations/eval_7fz1aflRO6alkzRRfWhQ

****************************************************

gist にコードをあげて、URL を取得する。

評価ページにいき、gist を貼り付ける。以下のリンクが今回の評価ページ。

追記

長い間プログラムを動作させると、manifest.json ファイルが生成されなかった。 そういう場合は、念のため env.close()を終了時に呼び出すことで、manifest.jssn が生成されるようだ。 参考にしたコードはここ.