Terrarium

いわゆる掃き溜めの ありふれた有象無象

OpenAI Gymを動かしてみた(keras-rlを用いたDQN編)

前回OpenAI Gymのチュートリアルを使ってQ学習を試してみました. 今回はAlphaGoなどで話題のDQN(Deep Q Network)を試してみたいと思います.

1. Deep Q Network

Deep Q Networkとは,Q学習で用いられるQ関数(状態を入力にとり,各行動の価値を返す.行動価値関数)をDeep Neural Networkで表現したものです. Q学習においては,行動価値関数はテーブルを用いて表現されるのが一般的です. しかし,ゲームなどの多くの状態をもつ環境や,実世界などの連続値環境では,テーブルのサイズが大きくなりうまく学習ができません. このテーブルをニューラルネットワークで近似しようというのが基本的なアイデアです. (以上は私の定性的理解です)

DQNは学習が収束しにくいなどの欠点があり,それを回避するためにExperience Replayなどの様々な手法が取り入れられていますが,今回はkeras-rlという強化学習ライブラリを使って簡単に試してみたいと思います.

2. keras-rl

kerasは機械学習のライブラリの一つです.

https://keras.io/ja/

TheanoやTensorflowのラッパーであり,これらに比べて簡単にニューラルネットワークを記述することができます.

keras-rlはkeras向けの強化学習ライブラリで,

  • Deep Q Learning (DQN)
  • Double DQN
  • Deep Deterministic Policy Gradient (DDPG)

など様々な強化学習手法を試すことができます.

github.com

ドキュメントはこちらです.

keras-rl.readthedocs.io

3. 試してみる

まずはkerasとkeras-rlのインストールを行います. なおこの部分は以下のリンクを参考にしました. qiita.com

  • keras
pip install keras
  • keras-rl
git clone https://github.com/matthiasplappert/keras-rl.git
pip install ./keras-rl

keras-rlを展開したディレクトリに,example/dqn_cartpole.pyというファイルがあると思うので,それを実行します.

するとLayer情報が出力された後,Cartpoleの描画が始まります. しばらくすると学習され,持続時間が伸びていくことが確認できます.

私の環境では200エピソード程度でほぼ最後まで続くようになりました. (Q学習では数千エピソード程度の学習が必要だったので,それより優れているかもしれません.パラメータチューニングを行なっていないのでなんとも言えませんが…)

4. その他

自分でアルゴリズムを作りたい,などの場合は,CartPole-v0環境についてのドキュメントを確認すると良いと思います.

github.com

また,env.render()で描画される画面は,ディスプレイに見えていない時(ウィンドウの後ろにあるなど)は描画がスキップされるらしく,必要な時だけ見えるようにしておくことで学習の高速化が図れます.

今回DQNの細かい理論,アルゴリズムには触れませんでしたが,下のリンクはPythonとKeras,Tensorflowを用いてDQNの実装例があるので,このような記事を参考にすると良いと思います.

DQNをKerasとTensorFlowとOpenAI Gymで実装する

OpenAI Gym を動かしてみた

OpenAI Gym

OpenAI Gymとは,公式サイトにも"A toolkit for developing and comparing reinforcement learning algorithms.“とあるように,主に強化学習を開発,比較検討するのに使える環境が集まったサイトです.

gym.openai.com

まずは,チュートリアルを進めてみます.以下のサイトが公式のドキュメントになっています.

https://gym.openai.com/docs

上のサイトに従っていけばできますが,一応作業履歴ということでここに書いておきます. こちらのバージョンはPython3.5,anaconda3-4.0.0環境を使っています.

1. OpenGym AIのインストー

pip install gym が一番簡単でした.

2. 環境を動かしてみる

import gym

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

for 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("finished after {} timestamps".format(t+1))
            break

を実行すると,倒立振子が出てきて,20エピソード分実行され,描画されます.

3. Q学習で強化学習してみる

ここからは上のページにない内容ですが,せっかくなので強化学習を試してみます.

https://gym.openai.com/algorithms/alg_0eUHoAktRVWWM7ZoDBWQ9w

上に,どなたかが実装してくださったQ学習のコードが載っています. これをコピペして,Python3用に一部修正し(xrangeやprint)実行します. (私の環境ではenv.monitorがうまく動かなかったので(きちんと調査してはいませんが)env.monitor周りはコメントアウトして,その代わりに毎ループでenv.render()を実行しました.これにより倒立振子が学習されている様子を知ることができます)

うまく動くと,徐々にうまくなっていくことが確認できます.

4. 少し変更

先ほどコピペしたコードを,次を目標に一部変更します.

  • 毎回の学習の様子をみる必要はないので,何回かに1回のみにする
  • 学習の結果をみるテストメソッドを追加する(学習は行われず,greedyに行われる)

これを追加したコードが次になります.

gist.github.com

まとめ

気づいた点をまとめておきます.

  • CartPole-v0は200フレームで強制的にdoneになる(うまくいっても行かなくても)
    • それ以上経ってからはactionの指示が効かない
  • 連続空間でもQ学習は有効であることがわかった
    • 連続空間では状態数が多くなりがちなので,離散化が粗すぎても細かすぎても適していないイメージだったが,すんなりと学習できた(学習タスクにもよると考えられる)

今回はせっかくQ学習までやったので,次回は流行りのDQNを試してみたいと思います(と書いていますが実はもう試してあるのでそれをまとめる時間があれば…)

それと

今後,自身がどんなことをやっているきたかの日記としての活用を考えていて,新規性のないやってみたレポートが増えそうな気がしています. 新規性がありそうなものはQiitaにもアップしたいと思っています(がそんなに新規性のある記事がポンポン浮かぶわけでもない)

AnalogDiscovery2を使ってみた

はじめに

PC接続の全部入り計測器,AnalogDiscovery2を使ってみました.

購入はDigilentから行いました.学生だと学割でだいぶ安くなります.送料が5000円近くするのが難点ですが,2万5000円程度でした.

秋月よりかは安くなった.

store.digilentinc.com

akizukidenshi.com

ツイート見ればわかりますが,買ったのが2016/7なので,半年以上眠らせてたことになります(電子回路を扱う機会がなかったのだ…)

I2C信号を観測する

I2C通信を扱う機会があり,久しぶりの電子回路なのとAnalogDiscoveryの存在を思い出し,信号を観測してみることにしました.

細かい回路は省略で.

実際に通信がうまく行かない現象に遭遇し,その原因究明にも使えました.

(原因はArduino内部でのプルアップと外付けプルアップの両方使ってしまっていたことでした)

以下はアドレス0x04に0を送った後,4バイトのデータを受け取った時の信号です.はじめに0x04すなわち0b00001000が送られていることが確認できます. 

f:id:tellusium:20170321120634p:plain

と書いたのですが,3つ目の173が怪しいですね…173 = 0x10101101なので,0が一つ足りないような.SCLも観測しておくべきだった…

はてなブログのテーマでレスポンシブが機能しなかった

前の記事に書いたように,レスポンシブなテーマをカスタマイズしていたところ,iPhone5Sでの表示が崩れる問題に遭遇しました.

TL;DR

MINIMというテーマで,レスポンシブにするための記述がiPhone5Sに対応していなかった.

まずはテーマのバニラ状態で崩れるか確認する

MINIMのサンプルサイトをiPhone5Sで表示させてみたところ,崩れることが確認できました.

PCのブラウザの幅を狭くしてみても,同様の現象が確認できました.

しかも幅を狭くしすぎると崩れることが確認できます.

正常

f:id:tellusium:20170312172831p:plain

異常(横にもスクロールできてしまう)

f:id:tellusium:20170312172818p:plain

どうやら幅が狭くなりすぎると起こる現象なので,CSSを確認してみます.

CSSの確認

デザインCSSでimportしているリンクへ飛ぶと,CSSの中身が確認できます.

レスポンシブ対応を行なっている部分は@media以降の部分なので,それを探します.

見つかりました.一番下にありました.


@media (max-width: 960px) and (min-width: 362px) {
  #content {
    margin: 0 auto;
    width: 100%;
  }
  ...

あれ…min-widthが362pxになっている…iPhone5Sの横幅は360pxなのに…

はい,これで原因がわかりました. 

解決方法

元のCSSを変えるのはできないので,一番手っ取り早い方法として,レスポンシブ対応の部分を丸々デザインCSSにコピペしてきて,min-widthの書式を消去しました.

これでどんなに小さい端末で見てもレスポンシブになるはずです.

余談

なぜmin-width: 362pxにしてあったのかが疑問です.

私はCSS入門者なのでmin-widthを指定する意味がわからないのですが,一定以下に小さくなると,表示が崩れるのでサポート外とする,といった理由でしょうか?

いずれにせよ,360pxという横幅のスマートフォンは少ないはずなので,今現在のほとんどの端末では正しく表示されそうではありますね.