子どもが生まれる前は自由研究と称して夏休みにしょうもないことをしていたが、流石に幼い二児の父となると自由研究なんてしている余裕はない。
でも何もしないのも寂しいので、自由研究というには程遠いが前から気になっていたディープラーニングをかじってみることにした。
少し前にニューラルネットをC++で自作して、何となく分かった気になったのでフレームワークを使ってもう少し実践的にやってみることにした。
最初にgoogleのTensorFlowを試してみたが、ちょっと敷居が高いので断念。
次にH2O.aiというやつがコードなしで使えるという話を聞いたので試してみた。
しかし高次元のベクトル推定のようなことをしようと思うと不便なので、やっぱりコードは必須かな、ということでKerasを試してみることにした。
これが素晴らしい。とっても簡単にネットワークを組むことができる。
取り敢えず手書き数字のデータ(MNIST)10000個を使って、オートエンコーダ、ディープでないニューラルネット、ディープなニューラルネット(畳み込みニューラルネット)を試してみた。
ディープでないニューラルネットでは正答率64%程度だったものがディープラーニングでは98%以上まで改善した。
色々出来そうな準備は出来たので、ハイパーパラメータをいじったりして遊びたい。
勉強していて思ったことをいくつか挙げておく。ただし一週間いじっただけのにわかなので間違ったことを書いているかもしれない。
* 手書き数字認識(MNIST)は初めの一歩には敷居が高い
→手書き数字認識はディープラーニングではHello world的な位置付けらしく、どんなフレームワークでも大抵初めの一歩として取り上げられている。ただ、フレームワークのチュートリアルを効率的に進めるためか、学習データを拾ってきて一次元ベクトルにしてみたいな泥臭い作業は単純なメソッドで隠蔽されていたりする。泥臭い作業が隠蔽されているため、どういう形でデータがやりとりされているのがピンと来なかった。これでは実際に使う時困るだろうということで、学習データのダウンロード、画像化、ベクトル化を自分の手で行った。最初の一歩としては手書き数字のような高等な例ではなく、ふたつの正規分布から数値を乱数で取り出し、分類するような例の方がわかりやすいと思った。H2O.aiではまず始めにこれをやった。
* 畳み込みニューラルネットの説明がわかりづらい
→単純な全結合ネットのときはニューロン同士の接続の重みを最適化するという話だったのに、次に出て来る畳み込みニューラルネットでは急にフィルタを最適化するみたいな話になっていてわかりづらかった。フィルタとか畳み込みとかいうのはちょっと高等な理解の仕方で、低級な理解の仕方としてはある層のニューロンと次の層のニューロンを距離に依存する形で重み付けするという感じになると思う。その後にフィルタとか畳み込みという話が来ていればわかりやすい気がする。全結合ネットから話が飛びすぎている感があった。
* 学習データの用意が大変
→全く未知の問題を学習データなしで解くのは無理で、解きたい問題があったとき、既に解けているパターンを大量に用意できないと正しく学習できない。例えば、自分の好みの女の子かどうかを判定したいと思ったら、あらかじめ自分の好みの女の子とそうでない女の子の画像を大量に用意し、それぞれを好き/嫌いで分類しておく必要がある。これがキツい。シミュレーションで生成出来るようなものならいいんだけど。
*何故Python
→何故かディープラーニングではpythonが主流。普通数値計算はC/C++ or Fortranなので戸惑った。仕方ないのでpythonを勉強しながらやることにした。vim scryptもpythonで書けるらしいし覚えても損はないか。
ディープラーニングは今のところほぼブラックボックスでなんかふわふわしている技術な感じがする。ブラックボックスというのは、問題が解けたとしても何故解けたかどのようにして解いたかがわからないということだ。文字認識ならどういうところに注目すればよいのかというところが結局よくわからないまま。わからないけど分類できるという。まさに人工知能、目の前に機械仕掛けの脳があり、こちらから質問をして答えてもらうというイメージを持っている。ここが将来改善されることを期待する。今のままディープラーニングに傾倒しすぎると、地に足のついた技術が疎かになり、ディープラーニングの限界が見えてきた時に後悔することになりそう。僕はディープラーニングを研究する予定はないので、あくまでツールとして補助的に使っていければと考えている。
ディープラーニング自体の勉強はほそぼそと継続予定だが、同寺並行でビッグデータ収集の方法についても検討する予定。