« 前のひとこと | トップページ | 次のひとこと »

cocolog:91609276

曽我部東馬『強化学習アルゴリズム入門』と伊藤多一 他『現場で使える! Python 深層強化学習入門』を読んだ。ソースがあるのがありがたい。二冊を交互に読むことでアルファ碁ゼロが私の強化学習のイメージに近いことがわかった。一方だけではわからなかった。 (JRF 4680)

JRF 2020年1月14日 (火)

おもちゃの自動車を AI で動かしたいなどと言って、これまで何冊か本を読んできた(直近では [cocolog:91382428] など)。そういう目的なら「強化学習」を詳しく調べる必要がありそうだ…ということで、それに関する本を二冊読んだ。どちらの本も最後のほうは理解できていないが、「目を通す」以上にしっかり読めたと思う。

JRF2020/1/149658

……。

……。

『強化学習アルゴリズム入門 「平均」からはじめる基礎と応用』(曽我部 東馬 著, オーム社, 2019年5月)
https://www.amazon.co.jp/dp/427422371X
https://7net.omni7.jp/detail/1106992518

最後の章は別として、例が詳しくわかりやすい本。が、けっこう誤字・脱字がある。正誤表がないかとググったがないようだ。

JRF2020/1/143501

……。

読んでて、グリッドワールドで、↓の「負の学習」みたいなことができないかと考える。

《ニューラルネットで負の学習: 競争的な学習の実験 その2》
http://jrf.cocolog-nifty.com/software/2019/05/post-3c97df.html

JRF2020/1/140790

あるアクションの価値がマイナスになれば、別のアクションの側に逆側に倒して学習する…とか考えるが、そうすると Q が求まらない。『現場で使える! Python 深層強化学習入門』のほうで説明するが、決定的な MDP に対しては、Q の最良のところを辿っていくのが方策にならねばならず、そういう Q に関係なく辿って良いなら、わざわざ学習するほどのことではなくなる。どうも、うまくいく方法が思いつかない。

JRF2020/1/148194

……。

>X_N は N 回目に探索したサンプル値なので、定数として扱ってもかまいません。<(p.19)

これがいまいち納得できない。この次の本も含めて、全般的に定数と見なして良いところとそうでないところの差の理解が私にはできなかった。

JRF2020/1/141375

……。

>各バンディットにおける事後分布は、以下のようにベイズ理論で表現できます。<(p.57)

このあとの式の無限の片方が開いたようなマークが、この次の本でも出てくるが良くわからない。また、ベイズの定理、そのものでないので、この式自体も今いちわからなかった。私の勉強不足ということだろうが…。

JRF2020/1/148832

……。

p.63 で S = (0,0), (3,0), (3,2) のところ、S = (2,0) や (2,2) などもそうではないのか? よくわからない。

JRF2020/1/143580

……。

p.73 で γ * G(S_{t+1}, a_t) となっているところ γ * G(S_{t+1}, a_{t+1}) だろう。

JRF2020/1/146808

……。

p.96 SARSA 法のところ V() が抜けている。

JRF2020/1/144539

……。

p.158 θ(s_30,L) のところ 2.34 でなく 2.67 だろう。

JRF2020/1/144505

……。

p.165 TD(λ) 法と書いているがこれは TD(n) 法ではないか。

JRF2020/1/141799

……。

4章は、この次の本と読み比べながら読まないとほとんど理解できなかった。この本だけでもダメだし、この次の本だけでわかるほど私は頭良くなかった。

JRF2020/1/141158

……。

……。


『現場で使える! Python 深層強化学習入門』(伊藤 多一 & 今津 義充 & 須藤 広大 & 仁ノ平 将人 & 川崎 悠介 & 酒井 裕企 & 魏 崇哲 著, 翔泳社, 2019年8月)
https://www.amazon.co.jp/dp/4798159921
https://7net.omni7.jp/detail/1106999270

JRF2020/1/147731

最後の ENAS はよくわからなかったが、それ以外はかなりわかりやすく書かれていると思う。ただ、これも意外な脱字のようなものが多い。誤字は少ない気がするが。こちらは誤字脱字のメモしてなかったので指摘はしない。

JRF2020/1/141416

……。

p.4 から「教師あり学習」「教師なし学習」などの説明があるが、どうもこの二分法はやめたほうがいいのではないか。例えば、進化モデルみたいなものを作るとき、環境からは、または相手の行動から報酬を受けとる。それは教師データと呼んだら何がいけないか。そして、そもそもそういう環境を作ったというのが「教師データ」ではないのか…などという考え方も出てくる。

あるのは「シンプルな教師あり学習」だけで、あとそれ以外は曖昧模糊としているということでいいのではないか? もちろん、「強化学習」は「それ以外」のほうになる。

JRF2020/1/141100

……。

強化学習の例をあげての説明は、『強化学習アルゴリズム入門』のほうがわかりやすいが、式のまとめ方はこの『現場で使える! Python 深層強化学習入門』のほうが良かった。

両方を読んでなのだが、ひっかかったのが、π が q に従って行動を決めないなら、q の具体的数値にいったい何の意味があるんだろう?…ということ。

JRF2020/1/141741

q がスコアなどと一致する必要はまったくないのでは? いや、どうも q は期待報酬であり、期待報酬が最良のものを辿っていけば最良の報酬が平均的には得られるという仮定がある。最後に報酬を得るというモデルの限りそれで良いのだろう。そうは得られない(途中で報酬をもらう)モデルの例を示せるか? やってみるべきか…とか考えた。

あくまで π が決まって q が決まるから、期待報酬が最大のものを π がたどるとは限らない。期待報酬が最良のものを辿っていくという π のもとでの期待報酬が q になる。

JRF2020/1/149564


同じメタ探索で、違う設定群を試し、その中で最良のメタ探索があり、最終的な探索 π があるというのはよくわかる(その後、q が決まる。q の最良探索を π が辿るとは限らない)。が、こちらはよくわからない。

p.36 のように、ある π について v = R + γ * P ・ v → v = inv(1 - γ * P) ・ R で q が求まる。その q について最良探索を π' として、また q' を求め π'' を求めると、π != π' だが π = π'' で、つまり、π と π'' の間を振動するという例が作れないか?

JRF2020/1/140717

…と頭の中でいろいろ試してみたのだが、どうも例が作れない。

そこでググったところ↓を見つけた。

《markov process - Why is there always at least one policy that is better than or equal to all other policies?》
https://stats.stackexchange.com/questions/207780/why-is-there-always-at-least-one-policy-that-is-better-than-or-equal-to-all-othe

JRF2020/1/149368

期待報酬が最良のものを辿っていく π で q を更新し、その q の期待報酬が最良のものをまた辿っていくというのを繰り返すだけで、かならず MDP (マルコフ決定過程) は、期待報酬が最大のものを π がたどるようになる…ということは言えそうだ。

JRF2020/1/146834

……。

p.54 でやっと気付いたのだが、ε greedy 法で、ε の値を変えたら Q の値が変わるのが当然なのではないか? 最良の π についてのみ Q が決まるのではなく、ε を含めた π の戦略によって得られる平均によって Q 値は変わると見るべきだろう。

JRF2020/1/148358

……。

p.64 には方策勾配定理が紹介され、その証明も載っているのはわかりやすい。

ただ、この log に q をかけたものを微分するというもの。どう使えるんだ…と思って、追っていくと、p.141 のソースなどから、q (など)は定数とみなして、log の項だけが微分されるのだとわかる。

そして、π にはソフトマックス型の関数を使うので、結局、交差エントロピー誤差に関して誤差逆伝播するときの、おなじみの差の形になるわけである。

JRF2020/1/143090

ただ、私は最初、別のことを考えた。微分を外に和を中に持ってきて log を足し合わせると考えると↓を思い出した。

《ミクロ経済学の我流シミュレーション その3 log 戦略》
http://jrf.cocolog-nifty.com/society/2019/05/post-79cdc2.html

JRF2020/1/140922

↑で、log を使ったのは、>一分野だけプラスの利益を増やすよりも、他の利益を増やすほうが増分が大きくなる。これによりある種の「弾力」が表せる。<ことで、平均からの分散がないよう保ったままその和を大きくしていくことの代わりに使えると考えたからであった。

JRF2020/1/144766

ここで逆に、log の和を使っているところについて、平均からの分散がないよう保つという「正則化」項みたいなものをつけて minimize すれば、学習結果がよくなるのではないかと予想した。…が試していない。

q や δ などの重みが付いている部分は、重み付き平均で考え、その平均からの差の二乗に再度重みの絶対値をかけたものの和を「正則化」項的に使えばいいのではないか。マイナスの扱いがやっかいだが、不可能ではないと思う。

いずれ試してみたい。

JRF2020/1/147506

……。

DPG (Deterministic Policy Gradient) (p.162) や p.186-188 に DDPG TRPO PPO について、文献の紹介がある。このあたりは結局私はわからなかった。ルービックキューブの例はこのうちのどれかを使ってそうだがよくわからない。

JRF2020/1/149362

……。

上で「メタ探索」をまずして…ということを考えた。

この本のルービックキューブ問題で、モンテカルロ木探索(MCTS)を使っているが、完全に「ポストプロセス」で学習が終ったあとに使っているだけだった。「これじゃない感」がある。

JRF2020/1/141302

が、このソースを読んだあと、『強化学習アルゴリズム入門』の 4.6 節 アルファ碁ゼロ学習法が理解できるようになって、そちらのソースを読むと、探索をまずして…ということをやっていたのだった。しかも、Q 値みたいなものはほぼ使っていない。これが私が「強化学習」でやりたかったことに近いな…と理解した。

JRF2020/1/141901

……。

……。

今回は、プログラムを読みはしたが、実行はしなかった。そのあたりのチャックは他の人に委ねたい。

JRF2020/1/145734

……。

読んでていくつか試したいことができた。

一つは、グリッドワールドで負の学習を行うこと。

一つは、ε greedy 法で ε が違えば Q が違うことを確けっること。

一つは、方策勾配法で、log の和を使っているところで、平均からの分散がないよう保つという「正則化」項みたいなものをつけて minimize すること。

もう少し時間をかけて考えてみて、場合によっては実装したい。

JRF2020/1/143698

……。

……。

追記。

『強化学習アルゴリズム入門』のアルファ碁ゼロ学習法は、例としては碁ではなく三目並べ(TicTacToe)になっている。

で、

>新しいリーフノードが展開されたら、従来の MCTS 手法では、Roll-out という手法を使って最後の勝ち負けまでシミュレーションします。アルファ碁ゼロでは、Roll-out を実行せずに新しいリーフノードが展開された時点で逆伝播が始まります。<(p.192)

JRF2020/1/161946

とあるが、ソースをみると、確かに search は途中まで展開された段階で V の値をニューラルネットの出力から得た数値を返している。しかし、execute_episode を見ると、結局、勝敗がつくまで展開しているようにみえる。

…私の読みまちがいかもしれないが…。例だから、それでいいということなのか…。

JRF2020/1/161261

typo 「確けっる」→「確かめる」。

JRF2020/1/213079

……。

……。

追記。

「方策勾配法で、log の和を使っているところで、平均からの分散がないよう保つという「正則化」項みたいなものをつけて minimize すること。」について。

JRF2020/1/211857

↓でダウンロードできるソース…

《現場で使える!Python深層強化学習入門 強化学習と深層学習による探索と制御 ダウンロード|翔泳社の本》
https://www.shoeisha.co.jp/book/download/9784798159928/detail

その RL_Book/contents/4-3_ac_pendulum/agent/actor.py の↓の部分…

JRF2020/1/210731

<pre>
def _compile_graph(self, model):
(…)
self.loss = -K.sum(
K.log(self.act_prob) * self.act_onehot,
axis=1) * self.advantage
self.loss = K.mean(self.loss)
(…)
</pre>

JRF2020/1/215437

ここを変えて、いろいろ試してみた。

まず、「正則化」項みたいなものを付ける試みはまったく成功しなかった。

例えば、上の部分を…

JRF2020/1/212487

<pre>
l1 = K.sum(
K.log(self.act_prob) * self.act_onehot,
axis=1) * self.advantage
l2 = K.exp(K.clip(l1, -100, 10))
m1 = K.mean(l1)
m2 = K.mean(l2)
self.loss = - K.log(m2) + 0.5 * K.log(K.mean(K.square(l2 - m2)))
</pre>

JRF2020/1/217863

…と変えたものをやっても、学習が早くなるということあなかったし、まともに学習されている様子もなかった。- K.log(m2) のところを - m1 にしてもダメ。「正則化」項の部分をいろいろいじってみたけど、ダメだった。ちなみに、ときどき学習の途中で、act_prob の計算で NaN があるというエラーが出て止まることがあったが、再現性がなく原因がわからなかった。

JRF2020/1/217458

これらをやっているうちに気になったのが、変える前の例でも、loss が最初増えていくということ。minimize のはずなのにこれはおかしいと思った。それは、上の l1 の部分が、マイナスになるのが問題のようなので、そこがプラスになるようまず↓に変えてみた。

JRF2020/1/215251

<pre>
l3 = K.sum(
K.log(1.0 + self.act_prob) * self.act_onehot,
axis=1) * self.advantage
m3 = K.mean(l3)
self.loss = - m3
</pre>

JRF2020/1/212099

最適化に Nelder-Mead 法を使っていた私は、最適化の具合は、関数形よりも増えるか減るかの問題であとは和のバランスだ…という感覚がある。log(π()) を log(1+π()) にしても本質的に問題ないのではないかと考えたのだった。

結果は、上の「正則化」項と違って、割とまともに学習は進む。loss も単調減少になってくれる。しかし、score が元の例だと -15 ぐらい行くのに、この変更をすると -20 ぐらいで貼り付き、それ以降改善が見られない様子となった。

…ということで、少し失敗。

JRF2020/1/211504

self.act_prob は 0 から 1.0 の間になり、その log はマイナスになる。これをだいたいプラスにするには、単純に 100 ぐらい足せば良いだろう…と考えたのが下の変更になる。

JRF2020/1/216337

<pre>
l5 = K.sum(
(100.0 + K.log(self.act_prob)) * self.act_onehot,
axis=1) * self.advantage
m5 = K.mean(l5)
self.loss = - m5

</pre>

JRF2020/1/210295

この場合、微分すると、100 * self.advantage の項は定数項だから消えるはずで、学習には影響がないはず…。

実際、試してみると、loss も単調減少になり、学習もほぼ遜色なく進むのであった。ただ、loss は、移動平均のグラフで見ると単調減少だが、個々の数値を見るとかなり激しく振動していた。

JRF2020/1/219553

loss は単調減少になったとはいえ、学習が良くなるほどのことはなく、あまり意味のない変更ということになった。なぜ、元の例で、loss が増えてもうまくいくのか、それは私には謎のまま残った。

JRF2020/1/212055

……。

……。

「ε greedy 法で ε が違えば Q が違うことを確かめること。」について。

実際違うことを計算および試行で確かめた。ε = 0.1 で計算および試行するプログラムが↓。(『現場で使える! Python 深層強化学習入門』のサンプル・プログラムを元にしている。)

JRF2020/1/219908

《policy_iteration_epsilon.py》
https://www.sugarsync.com/pf/D252372_79_7908952020

その結果が↓になる。

JRF2020/1/210008

<pre>
$ python policy_iteration_epsilon.py
(…)
step: 2 value: [23.86013098 24.01045186 23.55251256] policy: [0.95 0.95 0.95] value2: [23.625788676124007, 23.920355941678718, 23.231137352094546]
</pre>

JRF2020/1/214632

value: が V の計算して求めた結果で、実際、試行した結果が value2: になる。

ちなみに ε = 0 のときは最終的な step 2 の value == [25.01947209 25.14928602 24.76849849] になるので、違っていることがわかる。

JRF2020/1/215171

……。

……。

「グリッドワールドで負の学習を行うこと。」については、まだ思いついていない。グリッドワールド以外でも、強化学習で負の学習を行える例があるなら何でも良いのだが、Q の計算で結局、マイナスが必要だというのがネックになっている。

JRF2020/1/217001

……。

……。

追記。

アルファ碁ゼロ学習法の ipynb を実行しようとして一苦労。いろいろなモジュールをインストールしなければならないのはいいとして、Juptyter Notebook のバグにまずはまった(↓)。

JRF2020/1/225549

《Jupyter Notebook で venv の Python 3.6 上の TensorFlow 1.x が ImportError: DLL load failed になる。その venv でコマンドラインの .py ではちゃんと import されるのに!》
http://jrf.cocolog-nifty.com/statuses/2020/01/post-718549.html

JRF2020/1/221251

その上でさらに、numpy の仕様変更があったらしく、ソース(train_alpha_0_tic_tac_toe.ipynb と test_alpha_0_tic_tac_toe.ipynb どちらも)の以下の部分を変更する必要があった。

JRF2020/1/222637

オリジナル…
<pre>
def pos_check(bottom_left, top_right, input_pos):
(…)
check = (pos.size == 2) * (pos.dtype == np.int) * \
(bl <= pos).all() * (pos <= tr).all()
(…)
</pre>

JRF2020/1/229850

変更後…
<pre>
def pos_check(bottom_left, top_right, input_pos):
(…)
check = (pos.size == 2) * np.issubdtype(pos.dtype, np.integer) * \
(bl <= pos).all() * (pos <= tr).all()
(…)
</pre>

JRF2020/1/228349

« 前のひとこと | トップページ | 次のひとこと »