ディープラーニングの大流行の中、様々なフレームワークが登場し、気軽にプログラミングができるようになりました。しかし、そんな中どのフレームワークを選べば良いかわからないという人も多いと思います。そんな人に少しでも参考になればと思い記事を書きます。
Chainer
特徴
柔軟な計算グラフの構築が可能
Define by Runによって柔軟な計算グラフの構築が可能であることが、最も大きな特徴です。Chainerを皮切りに、この方式に則ったフレームワークも登場してきています(dynetやpytorch)。
実際、Define by Runでなければ上手く扱うことのできないような計算グラフも存在し、特に入力に応じて計算グラフの変更が必要であることの多い自然言語処理の分野では重宝されている印象です。
Pythonによる実装
ChainerのコードはPythonによって実装されている点も特徴的です。従って、計算グラフの構築にしても、学習のコードにしても、Pythonでの処理を好きなように用いることができる点が魅力的です。Pythonを使い慣れている人にとっては最も扱いやすいように思いますし、逆にPythonの勉強にもなるという印象です。
Pythonはインタプリタによって動作する言語であるため、C言語のようなコンパイラを通す言語に比べて低速になります(一方で気軽にテストが行えたりするメリットもある)。
ChainerはPythonの実装といえど、計算の処理はnumpy(C言語での実装)によって行われるため、高速な計算を可能にしています。基本的に計算処理をnumpyの世界で行うように意識すれば、他の言語に比べて計算時間が落ちるということも抑えることができます。
GPUを用いる場合は、numpyのように扱うことのできるcupyを使うことになります。現在、完璧ではないにしても、基本的な計算処理はnumpyをcupyに置き換えるだけで実装できます。
直感的な計算グラフの構築が可能
ChainerはPythonの様々なクラスとメソッドで実装されているフレームワークです。クラスとメソッドを使うオブジェクト指向という考え方は、プログラミングを良くするために考案された手法であり、実際、かなりプログラミングを容易にします。
Chainerでの計算グラフの構築は、Chainerで実装されているクラスを継承することで簡単かつ直感的に記述することができます。プログラムの中身を完全に理解しなくとも、どのようなクラスがどのようなメソッドを持ち、どのような働きをするのかを把握しておきさえすれば良いという感じです。
メリット・デメリット
メリット
上記の特徴から、Chainerのメリット羅列します。
- 直感的な計算グラフの構築
- デバッグが比較的行い易い
- Pythonの勉強にもなる
- (なんとなく日本の活躍を応援できる気がする)
端的に言えば、初心者でも取っ付きやすいのはChainerであるように思います。簡単な計算グラフから複雑なものまで、幅広く扱うことができるにも関わらず、実装の負担は少なめである印象です。
デメリット
- 計算速度が遅くなりがち
- アップデートについていけるか不安
- 利用人口が少ない
やはりPythonをインタプリタで動かすことになるので、コードによっては速度は落ちるかと思います。
また後方互換性が無くなるようなアップデートも見られるため、注意が必要です。アップデートの頻度も高いため、必要性に駆られない限りは、やたらめったら最新のものにする必要は無いかもしれません。
利用人口は質問に回答できる人間の母数が変わってきます。
まとめ
軽く使ってみたい初心者にとっても優しいフレームワークです。また、複雑な計算グラフにも対応できる点で、新規のネットワークを構築したい研究者にとっても有用だと考えられます。
ただし、実業務に使うという点においては、アップデートの状況や利用人口を考えると不利かもしれません。1つのコードの利用期間が短い場合は良いのですが、長期間使う場合には問題が多いでしょう。コードの規模が膨れ上がり、アップデートに対応できず、更に利用人口の問題で改修も難しいということが起こるかもしれません。
Keras
特徴
とんでもなく簡単に計算グラフを記述可能
層をただただ積み重ねていくだけという、とんでもなく簡単な実装が可能です。Kerasの登場により、Chainerを使っていた人たちが一気に流れていった印象さえあります。
高速計算ライブラリのディープラーニング用ラッパー
Kerasは「Theano」や「TensorFlow」のようなテンソルを高速計算するライブラリのラッパーとして登場しました。記述を簡便化するのが役割であるため、簡単に計算グラフを構築できるという点は当たり前と言えば当たり前です。
計算グラフの構築が簡単なだけでなく、学習のコードも、学習回数などの条件を引数にたった一行で実装できてしまいます。
もはやプログラミングの経験すら不要
ディープラーニングを始めようというときにはプログラミングの壁が大きく立ちはだかります。しかし、Kerasの場合はプログラミングが未経験でも、(恐らく)すぐに簡単なネットワークの学習は可能になるでしょう。
それほどまでに計算処理のプログラムが隠蔽されています。「どのような層を配置して、どれくらいの数どのように学習をするか」くらい意識しておけば十分といった具合です。
メリット・デメリット
メリット
- コードを書くのがとっても簡単
- プログラミング未経験でも恐らく大丈夫
- 利用者も多い
最も初心者に優しいのはKerasで間違いないです。
デメリット
- 処理の中身はコードからは全く分からない
- オリジナルの処理をさせるのが面倒
- 計算グラフ構築後、変更不可能
コードの簡便さと表裏一体ではありますが、コードだけからは処理の中身を知ることはできません。従って、Kerasを使っていても、ディープラーニングそれ自体の理解には繋がりにくいように思います。無論、理解をしたければ一度、numpyなどで自身で簡単なものを書いてみるのが一番です。
また、オリジナルの処理をさせたい場合には、それを可能にする関数なども用意されてはいるものの、最初からTheanoやTensorFlowで書くのが早いと感じるでしょう。
まとめ
初心者には一番おすすめです。
また、研究では、まだネットワークの基本的な構造すら決まっていないようなときに、細かいチューニングはせずに数打って試したい場合に有効です。ある程度使うネットワークの構造が決まってきたならば、細かいチューニングや処理の追加、評価の方法の変更に備えて、TensorFlowに移行するというのが良いかもしれません。
一言で言えば、簡単なネットワークを試す場合に有効だということでしょう。
TensorFlow
特徴
圧倒的な利用者数
Googleが実際にプロダクトを生む際に利用しているということで、爆発的に利用者が増えました。間違いなく世界一利用者の多いディープラーニングのフレームワークでしょう。
テンソル計算を行うライブラリ
もともとはディープラーニングに限らず、テンソル計算を行うためのライブラリとして生まれてきています。従って、基本的な計算処理の記述も可能であり、ディープラーニングのフレームワークとして考えるならば、最も細かい調整ができると言えるでしょう。
実装はC++で行われており、計算も高速に行われます。とは言っても、numpyもCで実装されており、高速処理が可能です。TensorFlowはnumpyのような高速計算処理を可能にしつつ、ニューラルネットを取り扱うことを意識した計算ライブラリだと考えるのがいいかもしれません。
Define and Run
計算処理を計算グラフとして一度構築し、その後、計算処理をさせるのがDefine and Runです。TensorFlowは基本的に全ての計算処理を、計算グラフによって記述します。どんな簡単な計算でもです(例えば単なる足し算でも)。
何か普通の処理をさせたいという場合にも、必ず計算グラフで考える必要があり、ある種の慣れが必要であるとも言えるでしょう。
追加のライブラリが豊富
高速計算を可能にするライブラリというのが、TensorFlowの基本的な姿ですが、やはりニューラルネットに特化した関数が多数準備されています。
また利用者数が多いため、TensorFlowのラッパーや、TensorFlowと同時に使えることを意識したライブラリも存在しており、多方面での支援が得られるという印象です。例えば今回紹介しているKerasも、TensorFlowのラッパーというポジションです。最近ではDeepmind(Googleの子会社)から、Sonnetというライブラリも登場しています。
メリット・デメリット
メリット
- 利用者数が多く、コミュニティが大きい
- 低レベルの処理も可能
- GPUの利用も簡単
ITの分野はスタンダードが多数決で決まることが多いです。利用者が多いと、それを支援する人が増え、雪だるま式に発展していきます。そのような観点からすればTensorFlowは最も発展の可能性が高いと言えるでしょう。
また、高速計算のためのライブラリであるため低階層の処理も、計算グラフを構築しさえすれば何でも行わせることができます。
GPUの利用も、通常はCPUの計算からほとんどコードを変更する必要はありません。
デメリット
- 計算グラフ構築後の変更が不可能
- 今回紹介した中で一番とっつきづらい。(慣れが必要)
やはり計算グラフの構築後、変更ができない点はデメリットです。一旦構築したものを変更しないため、コンパイルをすることで計算を高速に動作させられることが期待できますが、なんか速度面は他のフレームワークもかなり頑張っているせいで、デメリットが大きく目立っています。
これに対しては対応作としてライブラリが追加開発されていますが、利用の話はあまり聞きません。
また、全ての計算を計算グラフで表現することは、初心者にとっては取っ付きづらさの元になっています。もちろん、計算グラフという考え方に基づいているお陰で、自動微分などの考えが容易に理解できる点はありますが、TensowFlow使うような人は誤差逆伝搬法を数式で理解できるものだと思われるのであまり関係ないかも。(もちろん、TensorFlow自体を実装する人たちにとっては計算グラフという考え方が重要かもしれませんが、ユーザーにとっては背後の思想は関係ないかもしれません)
まとめ
計算グラフの変更が学習の途中で必要ない場合には、最も有利なのはTensorFlowでしょう。TensorFlowの世界で細かい計算の調整も可能ですし、コミュニティが大きいため、疑問の解決も比較的早く済ませることができます。最新の研究がTensorFlowで実装されることも多く、新しい物をすぐに試したい場合には嬉しいことでしょう。
Googleという巨大企業が支えているため、クラウドサービスであったり、ラズベリーパイを支援したりなど、実務への転用も今後行いやすいように整備されていくかと思われます。
私自身の利用状況
Keras
プロトタイプをささっと動かすために利用。
しかし、細かい評価の仕方の変更に対応しづらいため、本当に初期段階のものを動かしてみる場合にしか使わないです。例えば、層の数いくつくらいで始めてみようとか、その程度のことを試して見るために使う感じです。
最近は最初からTensorFlowかChainerで良くないか。と思うようになりました。
TensorFlow
宣言的なプログラミングの仕方が要求されるため、普通にPythonやMatlab使ってきた私は、正直、あまり慣れていません(MatlabやPythonを普通に使うため。たぶん専念する人には関係ないです)。
Chainer
一番使います。一番最初に触ったものでもあります。Pythonの勉強と同時に開始したため、一緒に歩んできたという愛着もあります。ただ、全く同じ計算グラフ構造の場合、TensorFlowの実装に比べ、(私の環境では)動作が低速です。
今のところ、計算グラフを学習の途中で変更するような処理が無いため、TensorFlowでも良いのかなと、同時並行で実装を行っています(評価の計算をnumpyで書いているのが、TensorFlowにとっては二度手間かもしれない)。
けどなんだかんだ、やっぱChainer続けていくのだと思う。