daisukeの技術ブログ

AI、機械学習、最適化、Pythonなどについて、技術調査、技術書の理解した内容、ソフトウェア/ツール作成について書いていきます

ゼロから作るDeep Learning 4(強化学習編)の4章のサンプルコードにアニメーション化の機能を追加する

ゼロから作るDeep Learning 4(強化学習編)の4章のサンプルコードの「policy_iter.py」のステップごとの更新された価値関数が書かれたマップの画像ファイルをアニメーション化する機能を追加します。

参考文献

はじめに

ゼロから作るDeep Learning 4(強化学習編)の4章のサンプルコードの「policy_iter.py」は、だいたい5ステップで最適方策が見つかって終了します。

このサンプルコードを、LinuxデスクトップのGUIで実行すると、1ステップごとに、更新された価値関数が書かれたマップの画像ファイルが表示されます。

しかし、クラウドサービスのLinuxにSSHで接続した環境で、このサンプルコードを実行すると、何も出力されずに終了してしまい、価値関数の書かれたマップの画像ファイルが見れません。

Jupyter notebookで実行すれば、価値関数が書かれたマップを見ることができますが、そのためにJupyterを起動したり、Google Colaboratoryを起動するのは面倒です。

そこで、このマップの画像ファイルをアニメーション化して、mp4、もしくは、gif形式で出力できるように機能を追加します。こうすることで、気軽にマップの画像ファイルを確認することができるようになります。

また、既存の機能にはなるべく影響を与えずに、アニメーション化する機能を追加していきます。

なお、今回アニメーション化する機能を追加したソースコードは、以下のGitHubに格納しています。

github.com

使い方

クローン

$ git clone https://github.com/dk0893/deep-learning-from-scratch-4.git -b v1.0-dk0893
Cloning into 'deep-learning-from-scratch-4'...
remote: Enumerating objects: 413, done.
remote: Counting objects: 100% (27/27), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 413 (delta 12), reused 13 (delta 8), pack-reused 386
Receiving objects: 100% (413/413), 727.59 KiB | 3.51 MiB/s, done.
Resolving deltas: 100% (234/234), done.
Note: switching to 'c5d97c442a764776f967e802d084c298f17aa9dd'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

ディレクトリ移動

$ cd deep-learning-from-scratch-4/

実行

$ python ch04/policy_iter.py --animation

実行結果確認

$ ls policy_iter.gif
policy_iter.gif

アニメーション化する方法の検討(設計)

このサンプルコードでは、マップの表示に、matplotlibを使っているため、matplotlibのアニメーション化する機能を使用します。

matplotlibのアニメーション化して、ファイル出力できる機能としては、FuncAnimationと、ArtistAnimationがあります。

このサンプルコードの価値関数が書かれたマップの可視化機能は、共通で使えるように、Classとして機能がまとめられており、1ステップごとに描画関数を呼び出す形式となっています。

FuncAnimationを使って実現した場合、このClassを大幅に書き換えることになりそうです。一方、ArtistAnimationを使うと、1回ごとの描画フレームを呼び出し元に戻り値として渡してやることで、上位側でArtistを取得してまとめておき、最後にアニメーション化することができそうです。

以上より、まずは、ArtistAnimationを使って、アニメーション化を実現してみます。

実装の準備

ゼロから作るDeep Learning 4(強化学習編)のサンプルコードが格納されているGitHubのリポジトリ(deep-learning-from-scratch-4)を、自分のGitHubにフォークします。

フォークしたリポジトリ(deep-learning-from-scratch-4)を、Googleドライブにクローンします。これを作業ディレクトリとして、機能追加していきます。

具体的な変更内容(実装)

common/gridworld_render.py

Renderクラスが実装されている。今回の対象である「policy_iter.py」の可視化機能は、render_vメソッドを使用しています。

従来の機能を有効にするか、アニメーション化する機能を有効にするかを指定するため、コンストラクタにanimationという引数を追加しておきます(デフォルト:False)。

common/gridworld.py

GridWorldクラスが実装されている。今回の対象である「policy_iter.py」の可視化機能は、render_vメソッドを使用しています。

render_vメソッドでは、コールされるごとに、Renderクラスのインスタンスを生成して、Renderクラスのrender_vメソッドで描画しています。

アニメーション化するには、Figureクラスのオブジェクトを描画するたびに作り直していては実現できない(Figureクラスのオブジェクトは保持し続けなければならないため)ので、Renderクラスのインスタンス生成は1回だけに変更します。つまり、RenderクラスのインスタンスはGridWorldクラスのインスタンス変数にしてやればいいです。

一方で、既存の機能に影響を与えないようにしたいので、Figureクラスのオブジェクトは作り直す機能を維持するため、Renderクラスのインスタンスを生成し直すのではなく、Renderクラス内でFigureオブジェクトを作り直すように変更します。

Renderクラスと同様、従来の機能を有効にするか、アニメーション化する機能を有効にするかを指定するため、コンストラクタにanimationという引数を追加しておきます(デフォルト:False)。

ch04/policy_iter.py

policy_iter()で、env.render_v()しているところで、戻り値のArtistをリストに格納しておきます。

policy_iter()で、whileループが終わったところで、リストに格納したArtistを、matplotlibのArtistAnimation()を使って、アニメーション化します。

実行結果

policy_iter.pyのグリッドワールド
policy_iter.pyのグリッドワールド

おわりに

アニメーション化することで、全体の価値関数の更新の流れは分かるようになりました。

一方で、細かく見たい場合に、画像ファイルとしても見たいところです。

次回(ゼロから作るDeep Learning 4(強化学習編)の4章のサンプルコードに画像ファイルの出力機能を追加する - daisukeの技術ブログ)は、画像ファイルの出力の機能を追加していきます。

今回は以上です!

最後までお読みいただき、ありがとうございました。