先日、Googleは深層学習ライブラリTensorFlowを公開しました。すでに、多くの方が試され、感想や使い方が書かれたりしています。自分も触ってみて、思った事を書きたいと思います。
深層学習の説明を初めて読んだ時の自分
よくある深層学習の説明では次のような図を用いて
神経の仕組みを連想させるような仕組みとして紹介されます。データが神経細胞から神経細胞へシナプスを通して伝達され、データを受け取った神経細胞がそのデータを見てまた新しいデータを送信する。
深層学習の仕組みがちょっと分かった時の自分
しかし、いざこの図を見てプログラムに反映するとなると、たくさんの細胞を再現しないといけないのではないかと困ります。そこで、同じ機能を持つ神経細胞を塊だと思って、次元の高いベクトル空間を用いて図を簡略化すると分かりやすいと思います。
神経細胞がベクトル空間でシナプスで繋がれているのを何らかの写像(分からない人は関数と思って)だと思いましょう。この写像は多くの場合非線形だが、線形写像(行列で表されるもの)と簡単な形の非線形な関数の合成で表されるようなものを使うものが多いと思う。機械学習ではこの写像を学習によって性能を上げていく。線形写像と非線形な関数の合成になっているような場合なら、線形写像の部分を行列で表して、学習の度にその行列を更新していくという方法が取れます。
今ここ
このような理解のもと、TensorFlowの説明を読んでいたところ、グラフを使って深層学習をするんだということはすぐに納得がいけるのですが、「あれ?」と思うことがありました。それは、頂点に関する説明は多くても、辺に当たる部分がほとんど見当たらないことです。さっきの図だと、写像の部分、つまり、グラフの辺を学習により強化していくところなのに、その辺の説明はありません。その代わりに、Variableというのがあって、それを更新することで学習をすることになっているようです。
どうやら、自分の中での深層学習像をもう一度書き換える必要があるようです。
写像の部分は、普通、可変で学習で更新される部分(線形写像の部分)と不変な部分(非線形な関数の部分)に分けられることに注目しよう。可変な部分は数値の何らかの列で表される。これをVariableとして、辺に組み込むのではなく頂点として扱うというのがTensorFlowのスタイルと理解できるのではないだろうか。辺から頂点へ切り離すことで、データと関数を分離を実現し、入力からくるデータと学習データを同格に扱っているのだ。そうすると次の図のようなイメージになる。
学習の際に、辺を逆流して、学習データ部分を更新していく。そのようなイメージで考えると、他のアプリケーションなどの仕組みに似たものとして、深層学習が捉えられるのではないでしょうか。