<基礎学習>10/7 cartpole問題を強化学習で攻略する2 (+雑記)

強化学習を進めました。

(前回の記事:プログラムの骨組みができた)
kurupical.hatenablog.com

今日やったこ

以下を行いました。

  • プログラムの凡ミスを修正
    • 1000データあるなかの1つのデータのみを繰り返し学習させていたという痛恨の凡ミス。
  • 重みの初期化が下手だった。(平均=0、標準偏差=0.01) → (平均=0、標準偏差=1)
  • 学習率0.001→0.01

そして、(100回分を学習→10回試行)を繰り返してみました。

f:id:kurupical:20171007225112p:plain:w400

最初の100〜1000回くらいはそれなりにやってくれるようになりました。
(調子のいい時は、最初の100回の学習後の10回試行で平均80くらいになります。)
その後はずっと下手くそに戻ります。

プログラムのバグか、学習アルゴリズムが悪いっぽいので引き続き少し見てみようと思います。

雑記

フリーランス

自分は企業就職しか考えていなかったのですが、ふとしたきっかけからフリーランスという選択肢が生まれました。
今複数オファーいただいています。
フリーランスがよくわからないので、「フリーランスで生きるとは」的な本を読み漁っています。おすすめあったら教えてください。

Googleアナリティクス入れてみた

アクセス数が少し増えてきました(といっても1日10〜20くらい)。
どこから来ていただいているのか気になるので、Googleアナリティクスを入れてみました。

ニート一週間やってみて

  • 毎日好きなことを好きなリズムで勉強しまくれてすごい楽しいです。
    一方で将来がすげー心配です。
  • 貯金+投資の勉強しててよかった。
    「やりたいことができた時のためにお金を作っておく」って、いつやりたいことができるんだろう?なんて思っていましたが…

<基礎学習>10/5-6 cartpole問題を強化学習で攻略する(+雑記)

以前書いた記事の続き
kurupical.hatenablog.com
前回は、cartpoleのゲームをテスト的に動かしてみました。

前回に続いて、cartpoleのゲームを強化学習(DQN)で攻略することを目標にプログラムを作ってみました。

ソース構成の考察

ソース構成は以下です。

  • agent.py
    ゲームの操作を行う。
  • dqn.py
    DQNのネットワーク構造を定義。
  • organizer.py
    ゲーム(今回はcartpole)の進行役。
  • run.py
    学習/推論を行うプログラム。
    1000回学習→10回プレイ、を繰り返しさせています

プログラム作成

全体的に意識したこ

  • コメント多めに 自分でも何やってるかわからなくなる時があるので…。

思想

  • 探索と活用の割合(agent.pyのpolicyメソッド)
    今わかる良い方法を採用するのか、それとも更に良い方法を探すのかのバランス。
    →ε-greedy法 + Annealingを採用。 εの確率でランダムに行動(探索)し、1-εの確率で今わかっている良い方法を採用(活用)します。
    Annealingとは、試行回数に比例してεを低減させていくことです。

動かしてみた

前回の実績より
棒を立てられたフレーム数

  • ランダムに動かす:平均20フレーム
  • 棒の傾きと逆方向に動かす:平均36フレーム
  • 私が作成した強化学習プログラム:平均9フレーム

→ランダムに動かすよりヘボい性能…。どっかバグってますね。。
しばらくこいつと戯れることになりそうです。

その他

ソースコード

ソースコードは以下で公開しています。
github.com

雑記

NHKの番組

NHKがAIの番組をやっていたのですが結構おもろいです。ぜひご覧ください。
www.nhk.or.jp

第1回で気になったところ

  • 技術的要素
    • 敵対的ネットワーク(GAN)
      聞いたことはあったのですがまだ触れてないです。概要だけでも勉強しておきたいです。
  • 人工知能的要素
    • 人はなぜ人たりうるのか?
      好奇心、三大欲求、種の存続に動機付けされている?ロボットにはそれがない?
    • 言葉の意味理解に身体は必要か?
      • 小説家は自分が体験していないこと(殺人とか)も想像して書ける

とあるエンジニアさんのはなし

体重計に乗るのがめんどくさい→ベッドを体重計にしてやれ!って言ってたエンジニアの人がいた。
しかも実際にベッドにマイコンとか設置しちゃったとか。
エンジニアの鏡ですね。
「3回同じことやったら自動化ですよ」って言ってたのがすごい印象に残りました。

<その他>10/4 小ネタ(読書会/AIが演奏会)

読書会やりました

10/4 19:00-22:00に、ゼロから作るDeepLearningの読書会をやりました。
参加者6人でした。
第3章4節まで進みました。

以下、質問について回答いたします。

  • 活性化関数にReLUとかSigmoidとか出てきたけど結局何を使えばいいの?
    www.procrasist.com
    qiita.com

    結論からいうと、LeakyReLU、PReLUが強いみたいです。
    ReLUがいい理由について、2個めのサイトの「スパース性がある」という表現がいいですね!

    ReLUは、f(x)<0ならば0に押し込めるのに対して、LeakyLeRUはf(x)<0ならばf(x)に定数a(0<a<1)を乗算するみたいです。

    数式でいうと

    • ReLUは max(0, f(x))です。
    • LeakyReLUは、max(f(x)*a, f(x))です。※a:定数。任意の値を設定

    Sigmoid関数には勾配消失問題があります。(ゼロから作るDeepLearning P.180を参照。)

今、強化学習(DQN)の活性化関数で何を使うかを考察していて勉強していたので、調べたことを書いてみました。

AI関連でびっくりしたニュース

AIが演奏会!?

ニュース記事
style.nikkei.com

公式サイト DCEXPO2017 – コンテンツ技術をテーマとした国際イベント

人間がひとつの楽器を演奏すると、それを聞いたAIが即興でアンサンブルするみたいです。
この話を聞いてめっちゃ感動しました。行ってみたいけど、東京か…。

<基礎学習>10/1-3 強化学習 OpenAI Gymでcartpoleゲームのチュートリアル

今は強化学習を勉強しています。
AlphaGoのアルゴリズムにも使われている激アツなやつです。

強化学習を勉強する目的

  • ロボットの動作を強化学習でやってみたい(知人の手伝い)
  • 投資で強化学習を動かしてみたい(自分がやってるやつ)

今日書くこと

以下について、参考にしたサイトを主に紹介します。

やったこ

1.勉強方法の考察

ちまたで流行っているDeep Q-Learning(DQN)をやりたい!
と思っていろいろ勉強したけどわけがわかりません。
以下サイトにたどり着きました。

qiita.com

ここから、実際にpongというゲームをDQNで学習しているという以下サイトを読み、プログラムを動かそうとしました。
postd.cc
が、Pythonのバージョンが違うのか動きません。

知人に相談したところ、「DQNDQN言うけど、お前まずQ-Learningって何かわかる?」と言われ、ちんぷんかんぷんな答えをしてしまいました。

2.理論の勉強

知人のアドバイスに基づき、Q-Learningがあって、Q-LearningのどこがDeep(ニューラルネットワーク化されてるの?)という疑問をまずは解決することにしました。

2-1.Q-Learning

qiita.com

「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をすることにしました。
小学校御用達の「指先でほうきを何秒立てられるか」ゲームのようなイメージですね。

www.youtube.com

導入にあたっては以下のサイトを参考にしました。 ◆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))

結果
f:id:kurupical:20171004160138p:plain:w400

パターン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))

結果
f:id:kurupical:20171004160029p:plain:w400

ランダムに動かすより、ちょっと動きがよくなりました。

今後

ただ人様のサイトをペタペタはっているだけのブログになりました。
次回は、強化学習をさせてみてどうだったかをブログにアップします。

<その他>9/28 大阪pythonの会に参加+LTやってみた

退職関係でバタバタしたり卓球の試合でたりでバタバタして、全然更新できていませんでした。。

9/28に、大阪pythonの会に参加しました。
osakapython.connpass.com

LTやってみた

LT(ライトニングトーク)というものをやってみたので、スライドあげときます。
(Ubuntuに標準であるLibreOffice Impressをslideshareにアップするの結構苦労しました…)

https://www.slideshare.net/secret/JeZAP8SaIlNovc

話を聞いてみて

びっくりしたこ

  • Faas(Function As a Service)
    サーバレスコンピューティング。
    もはやサーバすら立てない。
    プログラム(function)をサーバに置いて、それを呼ぶときだけサーバが立ち上がる(?)
    Docker的な感じでしょうか?(Dockerよく知りませんが)
    初めて知って結構感動しました

その他

  • 自分と同じ投資テーマで発表している人がいて、勉強になりました。

全体的に

  • LTしてみてよかったです。技術的な話を全くせずだったとか、反省はあったけど…
  • pythonの話もさることながら、投資の話ができたのが面白かった。笑 主に仮想通貨。
  • 証券会社の人とか公務員の人とか、本業以外の人が一定数いた。
  • 読書会第2回やります
    前回は、4人に対して8人申し込み→当日来たのが一人という感じだったので定員を増やしました笑
    osaka-prg-school.connpass.com

<基礎学習>9/21-9/23 AI白書(〜1.8)の読書メモ

AIの業界についても勉強しなきゃいけないなと思い、AI白書を読んでいます。
1.1〜1.8の中で気になったところをメモ。

1.DeepLearningの分野と実用性

分野

実用性

2.AlphaGo

最近話題になった囲碁のAI。

仕組み

AlphaGoは以下構成で成り立っている。

大量のプロ棋士棋譜ディープラーニングで学習させ、ある程度の強さのプログラムを作る。そこから、そのプログラム同士を何度も対局させ強化学習することによって更に強く。

3.ハードウェア

主に、組み込み系のところが気になりました。

書いてあったこと

  • 計算資源の乏しいデバイスに推論をさせるために…
    • 専用チップの開発
    • 32bitではなく16bit、8bitで計算するための仕組みを構築

全体を通して思ったこと

<基礎学習>9/19-9/20 物体検出(SSD_Keras)をやってみた★9/22追記

今日書くこと

  • SSD_Kerasで、学習→推論ができるまで

SSD_Kerasを触った経緯

(「いきさつ」と打って変換すると「経緯」に変換されてびっくり。どうでもいいですね)

知人のお手伝いで物体検出をやっていて、その中でいいフレームワーク?がないかということで探していたところSSD_Kerasを見つけました。
物体検出のイメージとしてはこんな感じです。
f:id:kurupical:20170920195140p:plain:w500
ハイキューを彷彿とさせる絵面ですね

参考にしたサイト

ai-coordinator.jp

自分が詰まったところメモ

  • Trainingするソースどれやねん…
    SSD_training.ipynb。jupiterNotebookの形式らしいので、これを.pyに変換しました。
    9/22追記:ipynb→pyの変換
    以下のコマンドを叩いてください。
jupyter nbconvert --to python ファイル名.ipynb  
  • 学習終わらん…(Epoch 1/30でずっと止まる)
    →batch_size > テスト画像数になると駄目みたいで、ずっと止まります。具体的には以下。
gen = Generator(gt, bbox_util, 16, 'frames/',
                train_keys, val_keys,
                (input_shape[0], input_shape[1]), do_crop=False)

230行目あたりでGeneratorを生成する時に指定している第3引数がbatch_sizeです。
batch_sizeは、1回の学習に使うデータの数のことです。
デフォルトは16になっていますが、必要に応じて合わせる必要があります。 テストデータは1枚としていたので、ここを1に足す必要があります。

9/22追記:学習データの作り方

  • アノテーションデータの作成
    「物体検出用SSD_Kerasで使える学習モデルの作成方法」で言及されたツール(http://qiita.com/slowsingle/items/9006383145a650c84cb0)を使います。(結果がXML形式で出力されます)
    出力されたXMLファイルを、PASCAL_VOC/get_data_from_XML.pyを使ってpklファイルに書き込みます。
    同プログラムの下の方に書いてあるところを環境に合わせて変更してください。
## example on how to use it
import pickle
data = XML_preprocessor('testxml/').data
pickle.dump(data,open('gt_pascal.pkl','wb'))
  • アノテーションデータの準備①-XMLファイルの作成
    生成されたgt_pascal.pklをルートディレクトリ(SSD_training.py等プログラムがあるところ)に格納してください。
  • アノテーションデータの準備②-テストデータが格納されているパスを指定
    テストデータに使う画像のpathを、232行目あたりのpath_prefix、233行目あたりのGeneratorの4つ目の引数で指定してください。
  • 学習
    SSD_training.py(※ssd_training.pyではありません)を流してください。
    学習結果は、/checkpointsに出力されます。(※学習前にフォルダを作成しておいてください)
  • 推論の準備① - タグの編集
    SSD.py(※ssd.pyではありません)を編集します。
    デフォルトはVOC2007のタグ付けになっています。
voc_classes = ['Aeroplane', 'Bicycle', 'Bird', 'Boat', 'Bottle',
               'Bus', 'Car', 'Cat', 'Chair', 'Cow', 'Diningtable',
               'Dog', 'Horse','Motorbike', 'Person', 'Pottedplant',
               'Sheep', 'Sofa', 'Train', 'Tvmonitor']  ```
  • 推論の準備② - 読み込む画像の編集
    提供されているプログラムは、パスを直書きしています。
    手間なので、フォルダの中のすべてのファイルが読み込まれるように変更しました。
    以下は、/framesに画像を格納する場合の例です。
files = glob("frames/*.jpg")
for file in files:
    img = image.load_img(file, target_size=(300, 300))
    img = image.img_to_array(img)
    images.append(imread(file))
    inputs.append(img.copy())
inputs = preprocess_input(np.array(inputs))
  • 推論
    学習結果をSSD.pyに読み込ませることで、自分が作ったネットワークと画像で推論ができます。

動かしてみた

f:id:kurupical:20170920200622p:plain:w500

できた!
あとは、学習データを増やしてみて、実用的なレベルまで持って行きたいです。

感想

  • インターネットすごい。こんな難しいこともググればすぐ出来るようになるなんて…。

所要時間

5時間程度でした。