HELLO CYBERNETICS

深層学習、機械学習、強化学習、信号処理、制御工学、量子計算などをテーマに扱っていきます

【ディープラーニングフレームワーク】Chainer, Keras, TensorFlow, Pytorch 【更新2018/11/11】

 

 

follow us in feedly

f:id:s0sem0y:20170515050826p:plain

 

はじめに

この記事を公開してから1年以上の月日が経っていました。

Google検索で、「TensorFlow PyTorch」という検索ワードを入れるとそれなりの上位にこの記事が表示されていたので、あまりに情報が古いということで更新することにいたしました。

 

現状、私自身はTensorFlowが主体となっており、PyTorchの動向も見ているという状況でございます。ChainerやKeras(単体)に関してはDocumentを読んでかなり久しいので、最新の状況は全く理解できていません。ご承知おきください。

 

この記事はChainerとKerasとTensorFlow全てを使っている私が、それぞれに対する使用感を自分でまとめておくために書いたものです。正直、自分自身があっち行ったりこっち行ったりしており、それぞれの使用感について忘れてしまわないために書いておくメモのようなものです。

 

ディープラーニングがテクノロジーを変えるという信念で、その拡散・教育を行っているfast.aiがPytorchを選んだことにも触れます。

 

 

Chainer

f:id:s0sem0y:20170604181105p:plain

 

 わたしがこの記事を書いた当時、Chainer v2.0となりCuPyが独立しました。現在はChainer v5.0で、かなりのスピードで発展してきていることが伺えます。

ただし中身は知らないので、「メジャーアップデート」が多いからと言って、どれほど変わったのかは把握できておりません。すいません。

 

アップデートが最近とんでもなく早い。

気概を感じる!(一方で最新の状態についていけないです)

 

利点欠点

○Define by Run

○デバッグしやすい

○Pythonでコードが完結

○cupyがほぼnumpyで馴染みやすい

○省メモリで動かせる設計となっている

○Chainer MN, Paint Chainer などの実用性あるライブラリが公式サポート

×GPUへのデータ転送を場合によっては意識する必要(⇔省メモリで動かせる)

×可視化周りが弱い(どうやらTensorBoardに繋げられるよう?要確認)

×参加者が世界的に少なめ(サードパーティの実装などほぼ無い)

 

 

感想

初めて触ったフレームワークでした。当時、TensorFlowと比べて圧倒的に使いやすかったのを覚えています。現在はほとんどのディープラーニングフレームワークが、似たようなAPIを提供しているために「書きやすさ」という点における利点は消えつつあります。

 

 

日本製だし一番頑張って欲しいですね。

 

コンピュータの分野はスタンダードが多数決で決まっていく傾向が強いのですが、参加者が増えれば間違いなくディープラーニングのフレームワークとして世界で活躍できる素質があるはずだと感じています。

Chainer(PFN)が提唱したDefine by Runの考え方に共感し、最近Torchが劇的に進化しました(PyTorchめ。やりおる)。

現在ではPyTorchがDifine by Runのフレームワークとして世界的に認知されています。その後「PyTorch」に触発されてTensorFlowもEager Exexutionを発表。触発されたの意味は、ユーザーが取られる危機感を持ったという意味だと思われます。各フレームワークとも、Define by Runであの形式のAPIを提供する発祥はChainerであると述べています。

が、ユーザーはガッツリ持っていかれてしまいました。

 

誰にオススメか 

○ディープラーニングをしたい人

○自然言語処理をしたい人(動的グラフが必要になるケースがある)

○Pythonに慣れている人(全てがPythonで解決。実装・デバッグ・テストなど全部)

○日本を応援したい人

 

最強のフレームワークになる素質を持っています(Pytorch出現でピンチか?)。

 

PyTorchに食われた形となりました。しかしDeep Learningに特化しているという点で一点集中できるため、目的・組織に応じて十分に使えるはずです(後述のTensorFlowはカバー範囲を広げすぎており、何でもできる形式を取ろうとしているあまり、APIが乱雑になっているためDeep Learningに特化していることは欠点とは言えません)

 

 

TensorFlow

f:id:s0sem0y:20170704010501p:plain

 

ほぼスタンダードになりつつあるGoogle製のフレームワーク。

Googleは巨大サーバーを抱えており、TensorFlowとセットでクラウドサービスを提供するということであれば、どうしても(実用的な面で)選ばれてくるところでしょう。

ここのところはTPUをGoogle Colaboratoryで誰でも使える環境を提供するなど、劇的にサービスを向上してきています。 Eager Execution や Probability、 XLA に Tensor2Tensor、 swift for TensorFlow など、環境の整備がグッと進んできた年でした。

近々TensorFlow2.0へ進化し、実用的なサービスも踏まえて洗練されることが予想できます。またKeras APIがTFで公式サポートされ、今後、高レベルAPIの主流として扱われるようです。

 

 

利点欠点

○Google(なんとなく安心できるでしょ)

×Define and Run

○Define and Run と Define by Run両方対応

○ニューラルネットに限らず、静的な計算グラフは全て実装可能

○カーネル法や周波数解析など、数値計算群も有する

×全ての操作を計算グラフで構築しなければならない(慣れが必要)

○多くの参加者(サードパーティのライブラリ、解説、利用例も多数)

○GPUでもCPUでも、コーディングが全く変わらない

○tensorboardがすごく便利

×APIが乱雑・複雑(Define and RunとDefine by Runを同時に提供するため?)

×内部が謎(処理はC++部分なので本当の中身はPythonからは分からない)。

 

感想

慣れが必要です。生テンソルフローはすごく書くのがしんどいですが、常に計算式レベルでコードを意識するので、最も納得感が強い(が一方で変なミスをしやすい)です。

現在ではKerasやTFLearnなどもTensorflowに含まれており、tensorflow.contribにも沢山の実装が既に準備されているため、高レベルでも書けます。またtensorflow.layersを使えば十分楽に実装できます(例えば隠れ層2つのFFNNは以下のように書けます)。

 

x = tf.placeholder(dtype=tf.float32, shape=[None, in_unit]) 
keep_prob = tf.placeholder(dtype=tf.float32)

h1 = tf.layers.dense(inputs=x, units=300, activation=tf.nn.relu)
h1_d = tf.nn.dropout(h1, keep_prob=keep_prob)
h2 = tf.layers.dense(h1_d, units=100, activation=tf.nn.relu)
h2_d = tf.nn.dropout(h2, keep_prob=keep_prob)
output = tf.layers.dense(h2_d, units=2, activation=tf.nn.relu)

 

また、ニューラルネットを作るだけのものではないため、もともと豊富な数学的な関数、データの操作の関数が準備されています。そもそも全ての操作を計算グラフで済まさなければならないため、多種多様なデータの操作がネイティブに含まれています(微分方程式の数値解法だって、最適化アルゴリズムそれ自体だって実装できる)。

 

現在はKeras APIが主流になっているため、上記のようなネットワークを定義する場合は、下記のコードが推奨されます。

 



in_units = 1000
drop_prob=0.3

model = tf.keras.Sequential([
    tf.keras.layers.Dense(300, activation='relu'),
    tf.keras.layers.Dropout(drop_prob),
    tf.keras.layers.Dense(100, activation='relu'),
    tf.keras.layers.Dropout(drop_prob),
    tf.keras.layers.Dense(2, activation='relu'),
])

 

 

注意点として、ドロップアウトでは「値を0にする割合」を渡すことになりました。TensorFlowでは当初、値を保持する割合を渡す形式でしたが、全てのAPIで落とす割合に統一する方向です。

 また、従来のFunctional APIもできますが、複雑なモデルを書きたい場合は`tf.keras.Model`を継承したクラスを書くのが今後は主流になります。

 

 

 

誰にオススメか

○ウェブ上に情報量が多いほうが頼りになると感じる人(英語が読めないと意味無い)

○いろんな書籍を参考にしたい人(英語の書籍は沢山ある。訳書もいつかは出る)

○宣言的言語(もちろん関数型言語でも良い)に慣れている人

○高レベルから低レベルまで、利用用途を切り替えたい人

○TensorBoardで可視化をお任せしたい人

 

圧倒的な情報量とgithubでのコード例の多さが魅力です。

 

個人的にはedwardの存在がかなり大きいです。確率的プログラミングをあんなにも簡単に実装できるのは素晴らしい。 

TensorFlow Probabilityとして統合されました。 

 

 

www.hellocybernetics.tech

 

 

Keras

f:id:s0sem0y:20170925013739j:plain

 

一番とっつきやすく、Theano、TensorFlow、MXNet、CNTKをバックエンドに選べる高レベルフレームワークです。こちらも利用者が抜群に多く、世界的に人気です。

 

現在はTensorFlowに統合されて、APIを利用できるためバックエンドをTFにしているのであれば個別に使う理由はあまりないように感じます。

 

利点欠点

○圧倒的に直感的

○Functional APIで少し複雑なネットワークにも対応

○学習ループを隠蔽(やることはデータ準備とネットワーク構築のみ)

○利用者が多い

○TensorBoard利用可能(tensorflowバックエンドで)

×Define and Runのフレームワークがバックエンドになる

×細かいことをしようとすると逆にめんどくさい(できないことは無いだろうが)

×内部は謎

 

 

感想

プロトタイプを作るという上では最も迅速に実行できるという印象です。大まかな計算グラフの構造に目処を付ける上で利用しています。複雑なネットワークを利用しないならば、ほぼ間違いなくKerasを使うのが一番ストレスフリーです。

 

とにかく群を抜いて使いやすい。

 

誰にオススメか

○とにかくすぐに試してみたい人

○必要とするものが静的グラフであると決まっている人

○コードは短ければ短いほど嬉しい人(高レベルであるほど嬉しい人)

○Web上での情報が多いと嬉しい人(英語が読めなければ意味ない)

 

 

Pytorch

f:id:s0sem0y:20170925014700j:plain

今とても勢いのあるフレームワーク(FaceBookが開発の中心)。ディープラーニングがテクノロジーを変えるという信念を持つfast.aiが選んだDefine by Runのフレームワーク。

Torch自体は歴史が長いため、もともと固定客が居たとも思われる。

 

このフレームワークは私自身触ったこと無いので、代わりにfast.aiの記事を意訳します。

元記事:Introducing Pytorch for fast.ai · fast.ai

 

以下アンダーラインがあるものが私自身のコメント。他は意訳。

 

なぜPytorchを選んだか

fast.aiはこれまでTensorFlow + Kerasを利用してきましたが、実装面での限界を感じるようになりました。例えば自然言語処理で重要な技術とされるアテンションモデル(注意機構モデル)は、Keras実装が存在せず、自分たちで実装しようとしましたが上手くいかず、TensorFlowには実装がありますが、変更が多く必要以上に複雑で、文書化もされていませんでした。

 

(※アテンションはリカレントネットに導入された非常に革新的な機構です。「Attention is All You Need」という論文が出てくるくらいです。[1706.03762] Attention Is All You Need)

 

そんな時にDefine by Run(動的計算グラフ)のフレームワークとしてPytorchがプレリリースされました。Define by Runでは通常のPythonプログラミングのように開発、デバッグが可能であり、アテンションモデルを数時間以内に実装できてしまいました。

 

 

Define by Run最高!とのことです(Chainer随分前からあったのに…!他にもDynetとか。全てタイミングの問題かも知れませんね)。

 

Pytorchがfast.aiとその受講生にもたらす利点

fast.aiのディープラーニングコース第二弾では、最新の研究論文を実装できるようにすることに焦点を当てています(これはとても重要なことです!)。アカデミックな研究の興味対象は(現実問題に比べ)非常に限られた範囲にとどまっています。

それ故、ディープラーニングを応用して実問題を解決するためには、根本的な理解と実装力を有した上で、それぞれの問題に合わせて(自分自身で)適切なカスタマイズをする必要があります。

PytorchではPythonの柔軟性と機能をフルに活用できるため、それぞれが抱える非常に広い範囲の問題に取り組むことができるというわけです。

 

Pytorch本人はもっぱら研究用途としての意識が強いようですが、プログラミングがしやすいのは間違いないでしょう。

 

Pytorchではfast.aiの受講者が(要するにPytorchを使えば)各アルゴリズムで何が起こっているのかをより深く理解することを可能にしてくれます。Define and Runでは計算グラフを構築した後はデータをGPUに渡し、その中で何が起こっているかを知ることはできません(宣言的な言語は全部そうよね)。しかし、動的なアプローチ(Pytorchの実装方法)では、全てのレベルの計算で何が起こっているのかを正確に把握することができます。

私達は、コーディングと経験を通してディープラーニングを学ぶのがベストな方法だと信じています。したがって、動的なアプローチこそ受講生に必要だと考えています。

 

更に驚いたことに、TensorFlowよりもPytorchの方が多くのモデルで学習が速かったのです(マジか)。これはこれまでの常識的な考えとは反するもので、静的グラフでは最適化がより多く行え、TensorFlowのパフォーマンスが高まるはずです。実際には、いくつかのモデルで、少し遅かったり、少し速かったりと毎月変化しているのを私達は見てきています。

 

 

 

このあとこれまで使ってきたKerasへの気持ちなどが続きますが、Pytorchについてはべた褒めで終了。

 

 

誰にオススメか(使ったこと無いので偏見)

○自然言語処理やりたい人

○Define by Runが良い人

○Pythonで最初から最後まで自由に書きたい人

○その上、ある程度の大きさのコミュニティが欲しい人(英語前提)

○要するにChainerみたいで、かつコミュニティの範囲が広いほうが良い人

 

なんと!自分に当てはまる…。けどChainerやっておけばPytorchへの移行もスムーズなのかなと思います。しばらくChainer復活しましょう。

 

その後、ずっとPyTorchを使っていました。抜群の書きやすさ、可読性高いAPI、素晴らしい使い心地でした。Eager Executionが発表されてからTensor Flowの高レベルAPIをメインに。

 

フレームワーク検索ボリューム(一新しました)

Define by Runで有名なChainerPyTorch比較

比較範囲:日本

青:Chainer 赤:PyTorch

 

f:id:s0sem0y:20181111203326p:plain

 

最近になって検索ボリュームで日本国内で見てもPyTorchがChainerを上回るようになりました。日本語文献もかなり増えていることが実感できます。

 

比較範囲:全世界 

青:Chainer 赤:PyTorch

f:id:s0sem0y:20181111203654p:plain

 

全世界だとずっとPyTorchです。

 

 

ChainerPyTorchTensorFlowKerasの比較

比較範囲:日本

f:id:s0sem0y:20181111203930p:plain

1年前はChainerとKerasが同等くらいだったようですが、現在はKerasがリードし、TensorFlowはずっと王者に君臨している様子です。

 

比較範囲:世界

f:id:s0sem0y:20181111204248p:plain

世界的にはKerasの模様。みんな楽したいんじゃ〜っと言った感じ。

TensorFlow2.0ではEager ExecutionでKerasAPIが主流になるため、周知徹底すればTensorFlowへのユーザー統合が進みそうな気がしますね。

PyTorchもじわじわと成長を続けており、相も変わらず研究界隈では真っ先に論文の実装が出てくる印象です。最新の手法を実際に試してみたいという人たちの利用を伸ばしているようです。

 

 

 

 

 

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com