ChainerでやってみるDeep Q Learning - 立ち上げ編

こんにちは 本業はプログラマじゃない人です。

テレビで「ディープラーニング」というキーワードがバズっているときに、
[分散深層強化学習でロボット制御 | Preferred Research](https://research.preferred.jp/2015/06/distributed-deep-reinforcement-learning/)を見て、
試してみたいことが出てきたので、いきなりクローンとは言わず、まず簡単なものから作った。
⇒ 置き場：[DeepQNetworkTest](https://github.com/Chachay/DeepQNetworkTest)


# 狙い
Pythonも初めて！Chainerも初めて！
プログラミングの作法すら分からないのに周囲にソフト屋さんがいない！
でも、自走機械に強化学習というのをやらせてみたい！
 ⇒ とりあえず公開すれば教えてくれる人が出てくるかもしれない

慣性とか持っている機械を動かして見せてる事例が本当に少ない（気がする）
 ⇒ 次のステップで入れてみよう

# やったこと
- [ConvNetJS Deep Q Learning Reinforcement Learning with Neural Network demo](https://cs.stanford.edu/people/karpathy/convnetjs/demo/rldemo.html)のクローンみたいなものを作成
    - PythonでGUIを作ってみたぞ! 
    - Deep Q Learning(e-greedy)を実装してみたぞ！（写経したという方が近いし、ぜんぜん深くない）
![demo.png](https://qiita-image-store.s3.amazonaws.com/0/117379/99f6c859-444c-f2b4-c8dd-57bf13d24234.png)

# プログラムの概要
## 環境
外枠と内枠で囲まれた箱庭に赤リンゴと毒リングが並んでいます。
人工知能くんは赤リンゴをたくさん食べたい、毒リンゴは食べたくない、という設定。

※ 割とオリジナルの設定のまま。
　　移動体の制御という観点で解釈しなおすと
　　　赤リンゴは誘導したい行先
　　　毒リンゴは避けてほしい道

### 外枠と内壁
人工知能くんの動きと視野をさえぎる障害物。人工知能くんは視界が開けているのが好き。
![001.png](https://qiita-image-store.s3.amazonaws.com/0/117379/22595320-4c38-2089-5a4f-b5bc4015e939.png)

### 赤リンゴ・毒リンゴ
赤リンゴにぶつかると、ご褒美。毒リンゴだと、罰。
![aka.png](https://qiita-image-store.s3.amazonaws.com/0/117379/3419219b-ffe3-0e31-fd90-c336941e85bd.png)![doku.png](https://qiita-image-store.s3.amazonaws.com/0/117379/edbdc835-9218-8738-9e26-c65291c893b8.png)

### 人工知能くん
前方120°に300pxの視野を持つ青い点。
- 視野は9つの目で構成されていて、リンゴや壁でさえぎられる（一番近いものだけしか見えない）
- 等速で動き続ける
- できる動作は、右に曲がる、右にちょっと曲がる、直進する、左にちょっと曲がる、左に曲がる
- 視界が広いときは直進したい
![agent.png](https://qiita-image-store.s3.amazonaws.com/0/117379/43f9c75e-b14a-6323-2835-d4cbc614f201.png)

## 強化学習とか
### ニューラルネット
入力 59個、隠れ層 50個 x 2枚、出力 5個でRelu使ってます（オリジナル通り)
![network.png](https://qiita-image-store.s3.amazonaws.com/0/117379/4f4bd97b-0739-ee0f-7ef0-6ec57e87bada.png)

### 学習
30,000個経験をストックしてミニバッチ学習。学習の仕方はよく見かけるやつ。
Double DQNとかLSTM使うなどおしゃれなことはしていない。

# できたこと・変なところ 2016-04-20時点
- 人工知能くんがちょっとずつ学習して赤リンゴを食べるようになっていく
- なんか妙に壁にこびり付くのが好き
- 毒リンゴも積極的に食べに行っているようにもみえるけどε-greedyのεが出てしまっているのだろうか

ご褒美のあげかた、actionを調整する必要があるかも。
いかんせん学習の経過が図示できていないのがいけませんね。

# 教えてほしい・助けてほしい！ 2016/04/22
## Numpyの使い方
[Chainerメモ11 GPUで速度が出ない時 - studylog/北の雲](http://studylog.hateblo.jp/entry/2015/10/01/083625)を拝見するなどすると

> 普段からnumpyをバリバリに使っている人からすればお茶を吹くレベルのありえないコードでしょうがちょっと前までの自分はこんなコードがよく紛れ込んでました。

ということがあるのですが、こちらの記事自体はcupyのことなのですが、
numpyだけに限定しても、私も作法をよく知らないので、
こうしたら速くなるよという書き方、ここは変なんじゃない？があったら教えていただきたいです。

```py:DQN001.py
        memsize     = self.eMem.shape[0]
        batch_index = np.random.permutation(memsize)[:self.batch_num]
        batch       = np.array(self.eMem[batch_index], dtype=np.float32).reshape(self.batch_num, -1)

        x = Variable(batch[:,0:STATE_DIM])
        targets = self.model.predict(x).data.copy()

        for i in range(self.batch_num):
            #[ state..., action, reward, seq_new]
            a = int(batch[i,STATE_DIM])
            r = batch[i, STATE_DIM+1]

            new_seq= batch[i,(STATE_DIM+2):(STATE_DIM*2+2)]

            targets[i,a]=( r + self.gamma * np.max(self.get_action_value(new_seq)))

        t = Variable(np.array(targets, dtype=np.float32).reshape((self.batch_num,-1))) 
```
forループ内をベクトル演算化できるような実装を考えればよいのだろうか…

## wxPythonの使い方
FrameとPanelの親子関係やデバイスコンテキスト(dc)の扱いがよくわかっていないのですが、
画面の下方にグラフを追加したい(工事待ち）
⇒ [wxPython：アニメーションとグラフ描画を同時描画する - Qiita](http://qiita.com/chachay/items/33ec984798191c3d8961)

![voglio001.png](https://qiita-image-store.s3.amazonaws.com/0/117379/5bde0ee4-9db3-73fa-7fbb-b42801119f55.png)

# その後：分散学習とグラフはつけた
蛍が飛んでるように見えますね。
![003.gif](https://qiita-image-store.s3.amazonaws.com/0/117379/2420c27a-ed29-c879-c081-298c54aac828.gif)


# 参考
- [ConvNetJS Deep Q Learning Reinforcement Learning with Neural Network demo](https://cs.stanford.edu/people/karpathy/convnetjs/demo/rldemo.html)
- [倒立振子で学ぶ DQN (Deep Q Network) - Qiita](http://qiita.com/ashitani/items/bb393e24c20e83e54577)

## 注意
この記事は、ちょこっとずつ書き足したり書き直したりする予定