【苦しみながら理解する強化学習】チュートリアルからの脱線 DQN, DDQN

いろんなサイトをランダムに読んでいたけど、仕様というかどういう流れで実装するか(論文によくかいてあるやつ)が大切ということがわかってきた。

Spinning Up以外の実装

ただ、Spinning Upの実装をみていてもそこまで理解できなかった。
ので、別のサイトをいくつかみて理解を深めようということで私の中で勝手になった。

この広大なネットの海を探していると(攻殻風)いっぱい参考になる記事があった。

このお方が書いているのが非常に参考になった。
曖昧な部分がなく、本当にこの人は理解しているんだ。

Q learning


main netのtarget net役割もコード見れば非常にわかりやすかった。
main netとtarget netの差を近似していくんだとわかる。
Q networkはelix-techのサイトに詳しく書かれています!

コードやペーパーを読むときも何か紙にメモをしながら読んだほうがよいかもしれない。(とふと思った。)

これホントに参考になるんですが、説明に無駄が全くないというか、理解しやすい。
Q learningはざっくりと、今の状態(s)と行動(a)は予めわかっているから、今回はgymの環境(つまりgymひいてはmujocoがかなり重要なのではないかと思っています)からそれぞれのaの報酬(r)を計算して、その中で最も高い価値の行動を取ったときの状態(s_t)を取得する。

その時に最も高い価値の選択方法が問題となると思うのですが、1回目は適当に選びます。
env.action_space.sample()を使え。
2回目以降はNNで計算して選択します。

メモ画像

そして、Qテーブルにsとaの組み合わせから得られる報酬をどんどんアップデートもしながら書き込んでいきます。

DQN, DDQN

QiitaのDQNの実装と、elix-techのDQNの実装を比較してみるのも一興。

実装自体は化物級な難しさではありません!(簡単に書いてくれているのだと思いますが)
ただ、正確に理解して正確に実装する。それが求められている。
いきなりここのQiitaのコードを読むのは難しいので、まずはelix-techがおすすめ。

tenserflowとkerasの組み合わせで実装する方が簡潔らしいです。
そして、dequeというのはよく使われているので使っていくべきだろう。
むしろ知らない方がアレなのかもしれないですが。

Q learningとDQNの違い

かなり丁寧にまとめてくれています。

1つ目の工夫Experience Replayは、学習内容をメモリに保存して、ランダムにとりだして学習します。
2つ目の工夫Fixed Target Q-Networkは、1step分ずつ学習するのでなく、複数ステップ分をまとめて学習(バッチ学習)します。
3つ目の工夫報酬のclippingは、各ステップでの報酬を-1から1の間にします。今回は各ステップで立っていたら報酬0、こけたら報酬-1、195 step以上立って終了したら報酬+1とクリップしました。
4つ目の誤差関数の工夫は、誤差が1以上では二乗誤差でなく絶対値誤差を使用するHuber関数を実装します。

少し時間はかかりましたが、コードを読めば理解できました。
強化学習の理解に苦しんでいるのですが、大きな分類としては行動の価値を予測する実装実施した行動から報酬を計算する実装に別れます。

行動の価値を予測する実装
Experience Replay

行動予測のNNの学習をする時にランダムに選んで学習していました。
QNetworkクラス内のreplayメソッドにありました。

ここで、

というのはMemoryクラスのメソッドなんですが、np.ramdom.choiceでミニバッチ長の配列を返しています。

Fixed Target Q-Network

本実装では32回でモデルを更新するようになっています。

ただ、32回に一度更新するのではなく、32実行分memoryに溜まったら、その後行動を1回実行するごとに溜まったmemoryの中から32個選んで更新をかけるというような流れです。
なんか無駄が多そうな気がするが…
ここに関してはペーパーで確認した方がよさそうですね。

誤差関数

誤差関数にHuber関数を使う。

実施した行動から報酬を計算する実装
clipping

強化学習では比較的多い気がするclipping。

DQNとDDQNの違い

DDQN(Double DQN)は行動価値関数Qを、価値と行動を計算するメインのQmainと、MAX[Q(s_{t+1}, a_{t+1})]を評価するQtargetに分ける方法です。
分けることで、Q関数の誤差が増大するのを防ぎます。

Qnetwork classのここの部分ですね。

価値(retmainQs)と行動(next_action)は、self.model、つまりはmainQNで、MAX[Q(s_{t+1}, a_{t+1})]を評価するのはQtargetとなっていますね。
DQNの場合はmainとtargetの重みを同じにしますが、DDQNだとmainとtargetを完全に分けます。

次回

脱線は続く。
paperから実際に実装しようと思う。
それが一番のチュートリアルとなる。

すごくまとまっていないメモみたいになってしまった…
書きながらまとめるのは難しいですね…

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です