<基礎学習>10/1-3 強化学習 OpenAI Gymでcartpoleゲームのチュートリアル
今は強化学習を勉強しています。
AlphaGoのアルゴリズムにも使われている激アツなやつです。
強化学習を勉強する目的
- ロボットの動作を強化学習でやってみたい(知人の手伝い)
- 投資で強化学習を動かしてみたい(自分がやってるやつ)
今日書くこと
以下について、参考にしたサイトを主に紹介します。
- 私の強化学習の勉強の過程
- OpenAI Gymのチュートリアルができるまで
やったこと
1.勉強方法の考察
ちまたで流行っているDeep Q-Learning(DQN)をやりたい!
と思っていろいろ勉強したけどわけがわかりません。
以下サイトにたどり着きました。
ここから、実際にpongというゲームをDQNで学習しているという以下サイトを読み、プログラムを動かそうとしました。
postd.cc
が、Pythonのバージョンが違うのか動きません。
知人に相談したところ、「DQNDQN言うけど、お前まずQ-Learningって何かわかる?」と言われ、ちんぷんかんぷんな答えをしてしまいました。
2.理論の勉強
知人のアドバイスに基づき、Q-Learningがあって、Q-LearningのどこがDeep(ニューラルネットワーク化されてるの?)という疑問をまずは解決することにしました。
2-1.Q-Learning
「Q-Learning」のところを読んで、その場にいた別の人とディスカッションすること1時間。
よーやくなんとなくわかりました。
「状況」と「取れる行動」と「その行動をとった時の期待値」のテーブル(Q-Table)が、すべての状況・取れる行動・取った時の期待値に対して存在していて、それをチューニングするみたいです…。
テーブルの数めっちゃ膨大。
囲碁の盤面が1919、それぞれのマスが(白、黒、何もなし)の3通りだから、3**(1919)通りの状況(Q-Table)とその時に取れる行動があるわけですよね…。
AlphaGoではすべてのテーブルを用意するわけではなく、前段階である程度パターンを刈り取っているみたいですが。
2-2.Deep Q-Learning(DQN)
DQNは、Q-LearningのどこがDeepになっているの?→TD誤差を誤差逆伝播している
というのはなんとなくわかったのですが、式変形がわからない。
「まず、Q(s,a)をニューラルネットワーク化します」の下にある式変形の過程が理解できません。今、考え中です。
3.強化学習の実装
最近は理論の勉強とか業界知識の勉強ばかりで、実装をしていませんでした。
なので、手を動かします。
OpenAI Gymに前々から興味があったので、やってみます。
3-1.OpenAI Gymとは
OpenAI Gymとは、一言でいうとAIの性能テストができるところです。
いろんなゲームに対して自分が作ったAIがどれだけの性能が出るのか、試せます。
そのための基盤として、様々なゲームが用意されています。(多分)
3-2.OpenAI Gymのチュートリアル
ゲームはCartPoleをすることにしました。
小学校御用達の「指先でほうきを何秒立てられるか」ゲームのようなイメージですね。
導入にあたっては以下のサイトを参考にしました。
◆OpenAI Gymのインストール(英語)
github.com
動かしてみると以下のようなエラーがでました
OSError: /home/owner/anaconda3/bin/../lib/libstdcsi++.so.6: version `GLIBCXX_3.4.20' not found (required by /home/owner/anaconda3/lib/python3.6/site-packages/atari_py/ale_interface/build/libale_c.so)
ググったら以下サイトが出てきました。
askubuntu.com
僕はAnacondaを使っているのですが、Anacondaにlibgccを入れないとダメみたいです。pip installじゃないです。以下コマンドを打つとちゃんと動きました。
conda install libgcc
◆CartPoleの動作
futurismo.biz
CartPoleは特に問題なく動作しました。
使い方を把握するため、ちょっと応用して2通りを試してみました
パターン1:ランダムに動かす
import gym env = gym.make('CartPole-v0') observation = env.reset() count = 0 epoch_count = 0 total_count = 0 while epoch_count < 20: env.render() # 現在の状況を画面表示する # ランダムに動かす observation, reward, done, info = env.step(env.action_space.sample()) count += 1 if done: print("Episode finished after {} timesteps".format(count+1)) total_count += count count = 0 observation = env.reset() epoch_count += 1 print("試行回数:{0}, 平均:{1}".format(epoch_count, total_count/epoch_count))
結果
パターン2:棒の傾きと逆方向に動かす
import gym env = gym.make('CartPole-v0') observation = env.reset() count = 0 epoch_count = 0 total_count = 0 while epoch_count < 20: env.render() # 現在の状況を画面表示する # 傾いている方と逆に動かす if observation[1] > 0: observation, reward, done, info = env.step(0) else: observation, reward, done, info = env.step(1) count += 1 if done: print("Episode finished after {} timesteps".format(count+1)) total_count += count count = 0 observation = env.reset() epoch_count += 1 print("試行回数:{0}, 平均:{1}".format(epoch_count, total_count/epoch_count))
結果
ランダムに動かすより、ちょっと動きがよくなりました。
今後
ただ人様のサイトをペタペタはっているだけのブログになりました。
次回は、強化学習をさせてみてどうだったかをブログにアップします。