FC2ブログ

頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


倒立振子にDueling Networkを適用してみた

強化学習の倒立振子問題でDueling Networkなるものを使いようやく動かすことができた。

強化学習(DQN)で倒立振子で入力を変更など
↑この辺りでもやっていたんだけど、再度ざっくり概要を。

学習はKeras(バックエンドはTensorFlow)を使う(Python)。
振子を揺らす(データ取得)とかはmacOSアプリのSceneKitの物理エンジンを使い、この時には予測する必要があるのでそこはMetal Performance Shaderを使う。
Python側とmacOS側は共通の状態ファイルをみて必要な処理を交互に行う。

今回はDueling Networkを使ってみたというお話。
詳細は参考リンク(※)を。

悩んだのが出力層でlambdaを使っている部分。
{
    outputlayer = Lambda(lambda a: K.expand_dims(a[:, 0], -1) + a[:, 1:] - 0.0*K.mean(a[:, 1:], keepdims=True),
                             output_shape=(action_size,))(y)
}
↑参考リンク先にあるコードなんだけど、この出力層をMPSでどうやって記述するんだ?ってなった。係数はどうやって渡すんだ?とか悩んだんだが、、、

Kerasのサマリー表示

↑Kerasで表示してくれるsummaryによるとlambda層に係数がなかった。
あー、そういうことか、とここで気付いたよ。1つ手前の層とは全結合で繋がってるのかと思ってた。違ったのね。

ってことはMPSのために保存する必要もない。MPS側では単に出力層の1つ手前まで計算させて、最後は単純に足せば(従来の)出力層であるQ値が得られた。
{
    //mpsResult.q0 = self->qResults[0];
    //mpsResult.q1 = self->qResults[1];

    // Dueling Networkの場合
    mpsResult.q0 = self->qResults[0] + self->qResults[1];
    mpsResult.q1 = self->qResults[0] + self->qResults[2];
}
↑V値とA値を足してQ値を得てるところ。Keras側とMPS側で同じ入力値を与え、同じ出力値になることで確認した。

DQN→Dueling Networkへのコードの変更が案外少なくて、ホントこんなんで動くのか?と思いつつ動かしたらあっさり学習した。しかも従来より早く。

学習結果のグラフ

↑ある程度学習が進んだ状態。

いや、本来なら得た報酬が大きくなっていくグラフの比較があるべきなんだが、、、そこまでは作っていないのでした(このあたりはmacOS側の処理なのでTensorBoardとか使えない)。
それでも「あれ?もう結構振子が振れてる?!」と思う程度にすんなり学習していた。
考えた人、すごいわ。


(※)参考リンク
【強化学習中級者向け】実装例から学ぶDueling Network DQN 【CartPoleで棒立て:1ファイルで完結】

<< 何年もだめだったradiko.jpが復活してた  TopPage  NHK筋トレ動画を頭出しするアプリを作った >>

コメント


管理者にだけ表示を許可する
 

トラックバック

トラックバックURL
http://ringsbell.blog117.fc2.com/tb.php/1204-f48ad9e2




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.

FC2Ad