機械学習初心者が1からChainerのコードを書き始められるまでの経緯を書いたら長くなりすぎた
情報が増えすぎてまとめ始めたら、すごい量になったので分離しました。
目次
- 始めた時の状況
- ChainerのMNISTのexampleを動かすまで
- Chainerとは
- Chainerを入れてexampleを走らせる
- MNISTってなんだ
- ディープラーニングってなに?
- 失敗1:局所的な話にハマる
- 失敗2:ディープラーニングなプロダクトを使ってみる
- 関連:ディープラーニングでなにができるのかを知る
- まとまった資料を読む
- Chainerのexampleを解釈する/簡単なコードを書く
- Chainerの周辺知識(Theano/numpy)を知る
- Theanoを調べる
- Chainerと既存のフレームワーク(Theanoを使ったもの)との違い
- おまけ:numpyを調べる
- 数学的な背景を学ぶ
- おまけ
- MNIST以外のChainerのサンプル
- ネタ
ChainerのMNISTのexampleを動かすまで
Chainerとは
資料
- Deep Learning のフレームワーク Chainer を公開しました | Preferred Research
- Chainer: A flexible framework of neural networks
まずChainerとはなにかを調べました。
Chainerはディープラーニング用のライブラリというよりは、柔軟なニューラルネットワークを記述し、学習させることが可能なフレームワークです。
対抗として
- Caffe
- Theano/Pylearn2
- Torch7
が挙げられています。
CaffeはNVIDIA DIGITSで触れられていたので名前だけは知っていましたが、詳細は何も知りませんでした。
他のライブラリも知らないので、Chainerの何が新しいのかがわからなかったのですが、後ほどTheanoについて調べてその違いを理解しました。
また、Chainerはnumpyなど計算用のライブラリを使っているのですが、こいつもよく知らなかったので、Chainerがなにをどこまでやっているのかなどもいまいち把握できませんでした。(学習系のアルゴリズムまで外部のライブラリが処理していて、うまいことラップしているのかなとか考えていました。)
Chainerを入れてexampleを走らせる
資料
- DeepLearningライブラリのChainerがすごい、らしい - cvl-robot's diary
- Getting Started Linux :: CUDA Toolkit Documentation
- pfnet/chainer · GitHub
- PFN発のディープラーニングフレームワークchainerで画像分類をするよ(chainerでニューラルネット1) - 人工言語処理入門
Chainerの公式ページトップの3行に従って、exampleを走らせました。
CUDAをインストールして、Chainerを入れる。なんかpipでパーミッションまわりでエラーがでたけど、気にせずsudoで突っ込む。
この時、たまたま一週間だけのバグを踏んですぐには動かなかったですが、無事動きました。
また実は公式トップのサンプル実行例はCPUで走るので、GPUで走らせたい場合はオプションをつける必要があります。
ディープラーニングってなに?
Chainerのexampleを動かしたのはいいのですが、そもそもディープラーニングがなんなのかよくわかっていないので、これからなにをさせようか、と思った時に困りました。というわけでディープラーニングを調べました。
一体なにがディープなのか。この時はよくその話をしていました。
失敗1:局所的な話にハマる
資料
shi3zさんのブログの
Googleの画像判別は、画像認識のためのコンボリューションニューラルネットワーク(CNN)を前段に、それを文章化するためのリカレントニューラルネットワーク(RNN)を後段に持ってきている。
CNNに代表されるニューラルネットワークは内部状態を持たず、学習結果がネットワークそのものに保存される。つまり、ある時点のニューラルネットワークに同じ入力を与えれば常に同じ出力が返ってくる。
これに対し、RNNは内部状態を持ち、同じ入力を与えても文脈によって出力が異なる。
イメージ的にはCNNが数学上の関数に近い(同じ入力に対しては常に同じ答え)のに対し、RNNはコンピュータや動物に近い。
を読んで、CNNはざっくりいうとただの期待する関数を得る近似系という認識だったのですが、RNNはしらなかったのでこの辺が新しいのかなどと考えました。
そこでRNNを調べたのですが、どうやらRNNも結局時間軸に対して展開可能であることがわかり、結局入力が複雑になったNNには違いないということがわかり特に魔法でもなんでもなさそう。
結局この辺は瑣末な点でもちろん本質的に新しい部分ではなかったですが、とりあえず目先から当たった結果時間を使ってしまいました。
失敗2:ディープラーニングなプロダクトを使ってみる
資料
- Labellioのリリースと画像認識がどうしてDeep Learningで重要視されるのか - FutureInsight.info
- Labellio
- ご注文はDeep Learningですか? - kivantium活動日記
- 人工知能は人間を超えるか (角川EPUB選書)
あ、これはなんか違うなと思い、ひとまずディープラーニングを触ってみようと。そこで、Labellioを触ってみました。
結果は簡単で面白いなとは思いましたが、特に簡単な部分はLabellioの凄さであってディープラーニングとは関係ないですね。Labellioは楽しかったですが、ディープラーニングを理解するという意味ではその辺のブログで得られるディープラーニングでなにができるかの例と同じ程度しかわからなかったです。
関連:ディープラーニングでなにができるのかを知る
また『人工知能は人間を超えるか』を中途半端に読んだのですが、それでなにができるのかはなんとなくつかんだつもりになっていて、しばらくはそれでGOしていました。なにができるかという意味ではあの本は良かったのですが、初めの方で機械学習の時代の遷移として書かれていたので、ディープラーニングというのはニューラルネットワークに限定される話ではなく、機械学習の任意のアルゴリズムで活用できる新しい学習の仕方なのかとか変な勘違いをしました。凄まじく無知ですね。
まとまった資料を読む
資料
最終的にはっきり理解したのは、『深層学習』の岡谷さんのスライドを読んだ時です。
このスライドは素晴らしくて、ディープラーニングを古いネットワークと対比して定義していて、つまり浅いNNではなく、深いNNを使う方法なのだと。この時に今となっては当たり前の認識になりましたがディープラーニングはニューラルネットワークのみで構成されるシステムなのだと初めて確信しました。
またこのスライドがさらに良かったのは、なにが良くなってなにがこのシステムの問題で、なぜそれが解決されるようになったのかなど、ディープラーニングに至る技術的なポイントもまとめられていた点です。
最後に現状のまとめもあるので良く俯瞰できます。
また、「ディープラーニングの過去と未来」では、歴史的な経緯の情報が多く、ディープラーニングの発展の流れを把握するにはすごく良かったです。dropoutなどブレイクスルーの説明もわかりやすい。
結局、初めっから素直にディープラーニングでググって資料を漁っていればもっと早く全体が見れていたという失敗談でした。
Chainerのexampleを解釈する/簡単なコードを書く
資料
- Python - 【機械学習】ディープラーニング フレームワークChainerを試しながら解説してみる。 - Qiita
- chainerでニューラルネットを学んでみるよ(chainerでニューラルネット2) - 人工言語処理入門
- Python - 【ディープラーニング】ChainerでAutoencoderを試して結果を可視化してみる。 - Qiita
ChainerのMNISTのexampleを解釈するためには、kenmatsu4さんのQiitaを読めば1から100まで解説されています。なのでそれを読みました。
exampleの解説を読むと雰囲気と流れはわかったので、実際に何かを書こうとhi-kingさんの簡単なコードを写経し始めたのですが、SoftmaxCrossEntropyとかDropoutとか何か良くわからなくてなかなか書き進めることが難しかったです。(kenmatsu4さんのところに一応解説はあるのですが....)
この辺の知識の概要はいくらかは前節の「まとまった資料を読む」の資料を参照すると概要が把握できます。SoftmaxCrossEntropyなどはkenmatsu4さんの記事やPRMLで得た知識を元に理解しました。
また、そのようなわかりやすいキーワードではなく、たとえば
x = chainer.Variable(x_data.reshape(1,2).astype(numpy.float32), volatile=False)
のような簡単な1行でもastypeってなんだとかそんな感じでした。
もちろんChainerの公式documentを読めばある程度進むだろうというものの、英語だしそもそも当然のように使われている用語やアルゴリズムがよくわからないしでなかなか取っ付けなかったです。
これは今まさに読み進めているところです。
Chainerの周辺知識(Theano/numpy)を知る
Chainerのコードを書く上で、アルゴリズム的な知識が全然なく苦戦していました。
ところで、Twitterを見ているとサクサク試している人がわりといるので、もしかしてもっと簡単にとりあえず始められる方法があるのではないかと思い、質問したところ、Theanoのチュートリアルをやるといいと言われました。それが私とTheanoの出会いでした。(なおこの出会いからの関係は以下のTheanoを調べるという一瞬で終わった模様)
Theanoを調べる
資料
まずTheanoってなんだ、と思ったんですが数値計算ライブラリでした。学習系のライブラリではなく。
Theanoのなにが嬉しいって、自動微分ができるらしいです。
Theanoの癖としては、まず数式や変数を定義して、それに値を代入することによって計算する。つまり、数式の定義と計算が分離されています。
また、変数では型をしっかり定義する必要があるのですが、その書き方が
実数(float64)の行列→T.dmatrix()
整数(int64)のベクトル→T.lvector()
のように型の頭文字をひっつけるようなスタイルで表記するようです。
ほかにも関数の取り扱いなど、数値計算をプログラミングでする場合のコードの書き方として多分に示唆を与えてくれました。
Chainerと既存のフレームワーク(Theanoを使ったもの)との違い
ここに来て、Chainerの公開記事に書かれていた既存のものとの違いが少しわかりました。というのもTheanoとの対比が挙げられていた為です。この話はChainerドキュメントのIntroductionの"Define-and-Run"ではなく"Define-by-Run"の話につながっているのだと思います。
なので結果としてTheanoの概要を知ったことはChainerのチュートリアルを読むのに足しになったと言えます(そして初めてChainerの公開記事を読んだ時にどれだけ内容が読めていなかったかということに驚きました)
もしかするとCaffeとかもしらべるといいのかもしれないけど結局調べてないです。
おまけ:numpyを調べる
資料
Theanoでの経験を踏まえて、数値計算ではかなり書き方が違うんだということを認識したので、Chainerで使っているnumpyについても簡単に調べました。
この始めの方だけでも読むと少し前に話題になった「numpy - 0-dimension array問題 - Qiita」なんかもなんとなくわかるようになります。
数学的な背景を学ぶ
資料
マシンを買った当初から並行してPRML(資料のパターン認識と機械学習って本のこと)上巻を読み始めました。
ある程度読み進めつつ、全体をパラパラとみつつしていたのですが、読んでいると内容がディープラーニングから乖離していることに気づきました。どういうことかというと、PRMLの内容は基礎で、ディープラーニングに於いてはその基礎的内容を組み合わせた複雑なシステムが必要だということです。
これではまずいということでなんとかその間を埋めようと考えました。そこで名前が上がったのが『深層学習』です。
とはいえ、数学的にある程度しっかり思考する為にはその上をやる為にもPRMLの内容を抑えていくことは大事なので並行して読みつつ、深層学習を読み始めました。こちらは始めからディープラーニングのために書かれているという前情報を聞いていたのでこれでなんとかなるなら!という気持ちで。
読み始めてみると、これがすごくいい感じでした。何がいいかというと、まずすごく軽い。PRMLを読んでいる身としては計算としても軽いし、それぞれの章のページ数も少ない。紙がしっかりしているためか、PRMLより少し薄いくらいなのに150ページ程度しかなかったです。そういうわけでこの本はPRMLに比べればはるかにさささっと読めそうなのでさっさと読みきってしまおうと読んでいる途中です。
おまけ
MNIST以外のChainerのサンプル
資料
全然読めてないですが、MNIST以外のサンプルの解説を含む記事です。
とくにLSTMなんかはぐぐってはみたものの、日本語のいい解説がヒットしなかったので詳しく知るにはここで紹介されている論文を読むくらいしかなさそう。