深層強化学習ライブラリChainerRL

Yasuhiro Fujita

2017-02-16 19:10:47

Chainerを使った深層強化学習ライブラリChainerRLを公開しました. https://github.com/pfnet/chainerrl

PFNエンジニアの藤田です.社内でChainerを使って実装していた深層強化学習アルゴリズムを”ChainerRL”というライブラリとしてまとめて公開しました.RLはReinforcement Learning(強化学習)の略です.以下のような最近の深層強化学習アルゴリズムを共通のインタフェースで使えるよう実装してまとめています.

A3CでAtari 2600のゲームをプレイするexampleや,

DDPGでヒューマノイドロボットの制御を学習するexampleなどがあります.

以下では簡単にChainerRLの使い方を説明します.

まず,強化学習を使って問題を解くには,解きたい問題(”環境”と呼びます)をしっかり定義する必要があります.環境の定義の仕方は,OpenAIが公開している強化学習ベンチマーク環境のGym(https://github.com/openai/gym)のインタフェースに従っています.Gymの環境で動かすこともできますし,インタフェースを揃えればオリジナルな環境で動かすこともできます.基本的にはresetとstepという2つのメソッドが実装されていれば十分です.

env = YourEnv()
# reset は環境をリセットして現在の観測を返す
obs = env.reset()
action = 0
# step は環境にアクションを送り,4つの値(次の観測,報酬,エピソード終端かどうか,追加情報)を返す
obs, r, done, info = env.step(action)

深層強化学習では,状態から行動を決める方策(Policy)や,状態や行動の価値を予測する価値関数(V-function,Q-function)をニューラルネットで表現し,そのパラメータを学習します.ChainerRLでは,これらは単に__call__を実装したChainerのLinkとして表現されます.

class CustomDiscreteQFunction(chainer.Chain):
    def __init__(self):
        super().__init__(l1=L.Linear(100, 50)
                         l2=L.Linear(50, 4))
    def __call__(self, x, test=False):
        h = F.relu(self.l1(x))
        h = self.l2(h)
        return chainerrl.action_value.DiscreteActionValue(h)

class CustomGaussianPolicy(chainer.Chain):
    def __init__(self):
        super().__init__(l1=L.Linear(100, 50)
                         mean=L.Linear(50, 4),
                         var=L.Linear(50, 4))
    def __call__(self, x, test=False):
        h = F.relu(self.l1(x))
        mean = self.mean(h)
        var = self.var(h)
        return chainerrl.distribution.GaussianDistribution(mean, var)

このように作ったモデルやChainerのOptimizer,アルゴリズムごとに必要な引数を渡して”エージェント”を作ります.エージェントは環境とのインタラクションを通じてデータを集めながらモデルの学習を行います.

q_func = CustomDiscreteQFunction()
optimizer = chainer.Adam()
optimizer.setup(q_func)
agent = chainerrl.agents.DQN(q_func, optimizer, ...)  # 残りの引数は省略

エージェントを作ったら,自分で学習ループを書いて動かすか,

# Training
obs = env.reset()
r = 0
done = False
for _ in range(10000):
    while not done:
        action = agent.act_and_train(obs, r)
        obs, r, done, info = env.step(action)
    agent.stop_episode_and_train(obs, r, done)
    obs = env.reset()
    r = 0
    done = False
agent.save('final_agent')

あるいはあらかじめ用意されている学習用関数に渡せば学習が行なえます.

chainerrl.experiments.train_agent_with_evaluation(
    agent, env, steps=100000, eval_frequency=10000, eval_n_runs=10,
    outdir='results')

とりあえず動かしてみるためのクイックスタートガイドを用意しました. https://github.com/pfnet/chainerrl/blob/master/examples/quickstart/quickstart.ipynb

ChainerRLはまだベータ版ですが,強化学習に興味がある方はぜひ試してもらってフィードバックをいただけるとありがたいです.ライブラリとしての使いやすさや,新しいアルゴリズムの追加など,今後も改善を続けていこうと思います.

実験ビルドシステムmafのv0.2をリリースしました

beam2d
リサーチャー

2014-08-04 14:12:31

こんにちは、得居です。先週末からインターンシップの3名を迎え、これからの二ヶ月間が楽しみです。

さて、昨年末に公開した実験用環境のmaf (Github)ですが、先週こっそりと v0.2 をリリースいたしました。今日は何が変わったのかをお伝えしたいと思います。

その前に、まずmafについて紹介します。mafは主に機械学習を用いた実験を書くための環境で、アルバイトの能地さん @nozyh と私の2人で開発しています。ビルドツールのwafを拡張する形で書かれていて、データセットから実験結果をビルドする過程を記述することができます。基本的な紹介は昨年末のブログ記事をご参照ください。特徴としては、学習や評価などの処理に付随するハイパーパラメータを管理する仕組みがあることです。詳細はmafのドキュメントをご参照ください。

それでは、v0.2で入った主な変更を紹介していきます。

続きを読む »

データ解析作業の救世主! 超絶☆実験ビルドシステムmafをOSS公開しました

beam2d
リサーチャー

2013-12-25 13:39:24

Photo by midiman. Used following a Creative Commons License. Taken from https://www.flickr.com/photos/midiman/90232391/
Photo by midiman under Creative Commons License (original)

メリークリスマフ!

得居です。今日はクリスマスですね。皆様昨日はいかがお過ごしでしたでしょうか?

クリスマスということで、今日は私たちから皆様に、特にデータ解析や論文執筆、手法の比較検証のために計算機上で様々な実験をしている方々に、プレゼントがあります!

Github – pfi/maf

今日、実験結果を「ビルドする」ためのツールmafを公開しました!

mafは、PFIでもよく使われているPythonベースのビルドツールwafを実験に使うための拡張です。大まかな使い方を学ぶために、ドキュメントとサンプルも公開しています。

maf — maf 0.1 documentation
サンプル

実験手順をビルドだと思って宣言的に書くこと自体はwaf等既存のビルドツールで可能です。mafはこの手順のうち、パラメータだけが違うという部分をまとめて書くための仕組みや、実験特有の手順(プロットなど)をサポートするようなライブラリを提供しています。

例えば5-foldの交差検証を行う例は以下のような雰囲気で書けます。なんとなく何をやる実験なのかわかるでしょうか? 正確な書き方はドキュメントやサンプルを参照してください。

...  # import等

def experiment(exp):
    # 5-foldの交差検証のためにデータセットを5通りに分割
    NUM_FOLD = 5
    exp(source='dataset',
        target='train test',
        # parametersを指定することで、パラメータ付けられたタスクや
        # パラメータ付けられた出力ファイルを作ることができる
        parameters=[{'fold': i} for i in range(NUM_FOLD)}],
        # 1行1データの形式のデータセットを5通りのtrain testに分割する
        # 出力されるtrain, testは'fold'パラメータでパラメータ付けられる
        rule=maflib.rules.segment_by_line(NUM_FOLD, 'fold'))

    # 分割した各foldに対して実験
    exp(source='train',
        target='model',
        parameters=maflib.util.product({  # 全組合せを実行
            'param1': [1, 2, 3, 4],
            'param2': ['a', 'b', 'c']
        }),  # 'fold'はもう指定しなくて良い (trainに紐付いている)
        rule='my-train ${SRC} ${TGT}')

    # ここにはもうfold, param1, param2などのパラメータを指定する必要はない
    # (modelとtestに紐付いているので)
    exp(source='model test',
        target='result',
        rule='my-eval ${SRC} ${TGT}')

    # 各foldにおける実験結果における'accuracy'値の最大値を取る
    exp(source='result',
        target='max_accuracy_result',
        aggregated_by('fold'),  # foldパラメータを「潰す」
        rule=maflib.rules.max('accuracy'))

    # 結果を可視化
    exp(source='max_accuracy_result',
        target='result.png',
        rule=my_plot_fun)

# 結果をプロットする方法はmatplotlibを使って書ける
@maflib.plot.plot_by
def my_plot_fun(figure, plotdata, parameter):
    ...

my-trainとmy-evalという学習・評価コマンドさえあれば、データサイエンティストや研究者の方なら誰でもforループを使って書いたことのある面倒くさい、そして意外とややこしい交差検証が実質3行で書けます。my-trainやmy-evalのコマンド部分はpython関数で書いて指定することもできます。

maf開発の背景は、実験の複雑さです。データを解析したりアルゴリズムの比較を行う際に、実験手順をスクリプト(shell, python, ruby…)でよく書くと思います。最初は単一のデータに単一のアルゴリズムを一回適用して結果を見るだけだったりするので、直接スクリプトを書くので十分なのですが、他のデータに適用したり、他のアルゴリズムや異なる設定(パラメータ)と比べたりし始めると、実験手順と実験結果の管理に割くコストが上がっていきます。機械学習の実験だとさらにデータを複数通りに分割する必要もあったりして、データの管理も必要になります。これを最初のスクリプトの延長で書き続けると書いた本人にしか読み解けない複雑な実験スクリプトができあがったり、実験に必要な手操作が本人にしかわからなくなったりします。メンテナンス性を上げるために実験のためのドキュメントを書き始めると、管理コストはさらに上がります。

様々な設定での実験手順と実験結果、およびそれらの集約と可視化、これらを宣言的に記述して途中で生成されるファイル群の管理をうまく隠蔽することができれば、実験とそのメンテナンスにかかるコストは大幅に下がると期待できます。mafはこれらを実現することを目指して開発されました。

mafは辛い実験生活をサポートしてくれる縁の下の力持ち的な存在です。ぜひ一度試してみてください。フィードバックやPull Reqなどもお待ちしております!

今年のSIGKDDベストペーパーを実装・公開してみました

hido
Chief Research Officer

2013-08-16 18:23:11

毎日暑いですね。比戸です。

ちょうど今週シカゴで開かれていたSIGKDD2013でBest research paperに選ばれたEdo Liberty氏 (Yahoo! Haifa Labs)の”Simple and Deterministic Matrix Sketching”のアルゴリズムを実装して公開してみました。

元論文PDFは著者サイトから、私が書いたPythonコードはGithubからそれぞれ入手できます。

続きを読む »

Compressed Permuterm Index: キーワード辞書検索のための多機能&省メモリなデータ構造

maruyama
リサーチャー

2012-11-06 14:00:23

はじめましてこんにちわ。
4月からPFIで働いているまるまる(丸山)です。最近のマイブームはスダチです。
リサーチブログの更新が再開されたので、私も流れに乗って初ブログを書いてみようと思います。

今回は社内の情報検索輪講で少し話題にあがったCompressed Permuterm Indexを紹介したいと思います。

続きを読む »

Interaction Design向けのC++ライブラリ "pocode"

祢次金 佑
エンジニア

2012-02-28 10:21:16

祢次金です。

今回はC++で書かれたオープンソースなライブラリ、pocodeを簡単にご紹介します。
pocodeはPotion社によって設計された、主にインタラクションデザインのためのライブラリであり、プラットフォームとしてはWindows、MacOS(Lion)、iOSに対応しています。オープンソースとして公開されたのは最近ですが、既にいくつかのプロジェクトで利用実績があるようです。

続きを読む »

EaselJSでインタラクティブなグラフを描こう

祢次金 佑
エンジニア

2011-12-04 23:35:36

先日、paper.jsによるグラフ描画について触れましたが、今回はflashのようにcanvasを使うことのできるJavascriptライブラリ「EaselJS」を使ったグラフ描画について少しご紹介したいと思います。

EaselJSでは、ShapeやBitmap、TextといったDisplayObjectをStageにaddChildしてディスプレイリストを作ることで、Stageに紐付けられたcanvasにその内容が描画されます。 ActionScriptに慣れている開発者には馴染みやすいやり方です。onClickなどのイベントハンドラもDisplayObjectごとに設定することができ、アニメーションも勿論可能。

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="easel.js"></script>
    <script type="text/javascript">
      window.onload = function() {
        var canvas = document.getElementById("myCanvas");
        var stage = new Stage(canvas);

        var shape = new Shape();
        shape.graphics.beginFill('#f00').drawCircle(100, 100, 100);
        stage.addChild(shape);

        var label = new Text("hoge", "30px Arial", "#000");
        label.x = 70;
        label.y = 110;
        stage.addChild(label);

        stage.update();
      };
    </script>
  </head>
  <body>
    <canvas id="myCanvas" width="300" height="300"></canvas>
  </body>
</html>

先日の記事と同様、クリックに反応する棒グラフを実装してみました。見た目にはほとんど変わりませんが、EaselJSで実装しています。

bar graph using EaselJS – jsdo.it – share JavaScript, HTML5 and CSS

paper.jsと同じく、プロジェクトサイトにはデモやAPIドキュメントが揃っています。(冒頭の画像はEaselJSによるgameデモのスクリーンショットです。)

最速の疎ベクトルはどれだ

海野 裕也
リサーチャー

2011-11-22 15:57:49

海野です。
自然言語処理などで機械学習を行おうとすると、非常に疎なベクトル表現を使いたくなります。疎、というのはほとんどの要素が0である、という意味です。前々から疎ベクトルライブラリのパフォーマンスに関して気になっていたので、幾つか調べてみました。

続きを読む »

モダン並列・並行プログラミング ~ Concurrent Revisions による実装と現実 ~

preferred

2011-10-20 14:43:49

本日社内向けのTechTalkにて、並列・並行プログラミングに関する話を行いました。

昨今、プログラムの並列化はなくてはならないものとなっています。しかし、そのプログラミング環境は依然としてロックを用いたものが主流です。今回の発表の主張を端的に申し上げますと、

続きを読む »

paper.jsでインタラクティブなグラフを描こう

祢次金 佑
エンジニア

2011-10-11 15:20:21

canvasベースのベクターグラフィクス描画用jsライブラリとして、既に各所で紹介されているpaper.jsですが、これを、ウェブに載せるグラフの描画に使ってみましょう、というお話です。

続きを読む »

12