読者です 読者をやめる 読者になる 読者になる

機械学習初心者が1からChainerのコードを書き始められるまでに必要だったことをまとめた

ディープラーニングが面白そうだったので、始めたChainer。簡単という噂も聞き選びました。

ですが、いざ手をつけようと環境を用意してから早2週間超、なかなかサンプル以上のものを動かせずに悶々としていました。

そのような焦りの中、できるだけ頑張って情報を集めた結果、ようやっと自分で調べながらなにか書き始められそうなところまできたので、一度ここまでに拾い上げた知識をまとめます。

必要な知識ジャンル別にまとめました。それぞれの題目になってる目的が達成できれば全部読む必要もないかも。

長すぎるので経緯を分離しました。
機械学習初心者が1からChainerのコードを書き始められるまでの経緯を書いたら長くなりすぎた - sora_sakakiのブログ

ディープラーニングを知る

なにができるのか

人工知能は人間を超えるか (角川EPUB選書)
なにができるのか、なにができるようになる可能性があるのかなどを詳しく
Labellio
実際に試せる(ディープラーニングの使用例としてよくある画像認識)

どんなものなのか(重要)

(PDF)ディープラーニングと画像認識への応用
層の少ないNNとディープラーニング的なNNの対比、DNNの問題点や改善方法、現状の技術的なまとめなど
ディープラーニングの過去と未来 〜黒魔術からの脱却へ向けて〜
歴史とか発展とか
(PDF)脳の画像・音声処理戦略を解き明かすスパースモデリング
ディープラーニングのベースになっているスパースについて

Chainerを知る

Chainerの対比になるやつ(Chainerがなぜ作られたかを知るのに必要)

Theanoの使い方 (1) シンボルと共有変数 - 人工知能に関する断創録
Theanoの話

参考

私訳「暫定的 NumPy チュートリアル」 - naoya_t@hatenablog
Chainerで使われている数値計算ライブラリのnumpy

ディープラーニングのアルゴリズムを知る

ここは全然情報が足りていません。自分で補ってください。

Deep Learning Tutorials — DeepLearning 0.1 documentation
Theanoではあるけど、よさそう。

数学からアルゴリズムを知る、数学的に掘り下げる

深層学習 (機械学習プロフェッショナルシリーズ)
そんなに難しくなさそう

現状に対する私自身のまとめ

まとめてみたらアルゴリズムを知るという点で、すでに取り組んでいるアプローチが深層学習の本読むだけですね。まとめてよかった。
というわけで、以前勧めてもらった

Deep Learning Tutorials — DeepLearning 0.1 documentation

を掘り返して、アルゴリズムをささっと学びつつChainerのチュートリアルですかね。さっきパラパラと見た感じ、Chainerのチュートリアル上ではアルゴリズムについてのしっかりとした説明はなさそうだし。他方こっちのチュートリアルは覗いた感じよさそう。




深層学習 (機械学習プロフェッショナルシリーズ)

深層学習 (機械学習プロフェッショナルシリーズ)

機械学習初心者が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とは

資料

まずChainerとはなにかを調べました。

Chainerはディープラーニング用のライブラリというよりは、柔軟なニューラルネットワークを記述し、学習させることが可能なフレームワークです。
対抗として

  • Caffe
  • Theano/Pylearn2
  • Torch7

が挙げられています。
CaffeはNVIDIA DIGITSで触れられていたので名前だけは知っていましたが、詳細は何も知りませんでした。
他のライブラリも知らないので、Chainerの何が新しいのかがわからなかったのですが、後ほどTheanoについて調べてその違いを理解しました。

また、Chainerはnumpyなど計算用のライブラリを使っているのですが、こいつもよく知らなかったので、Chainerがなにをどこまでやっているのかなどもいまいち把握できませんでした。(学習系のアルゴリズムまで外部のライブラリが処理していて、うまいことラップしているのかなとか考えていました。)

Chainerを入れてexampleを走らせる

資料

Chainerの公式ページトップの3行に従って、exampleを走らせました。

CUDAをインストールして、Chainerを入れる。なんかpipでパーミッションまわりでエラーがでたけど、気にせずsudoで突っ込む。

この時、たまたま一週間だけのバグを踏んですぐには動かなかったですが、無事動きました。
また実は公式トップのサンプル実行例はCPUで走るので、GPUで走らせたい場合はオプションをつける必要があります。

MNISTってなんだ

MNISTとは、機械学習などでよく使われる試験用の大量の手書き数字画像のことです。

詰まった時に、MNISTのデータがダウンロードできません、とのことだったのですが、じゃぁMNISTってなんだと思ったわけです。
で、MNISTがなんだったかというと、機械学習パターン認識ではMNISTを始めいくつかよく使われる試験用の画像があるようで、その一つのようです。

Chainerでははじめはscikit-learnをつかってmnistのデータをダウンロードしていたようですが、今は直接ダウンロードしてるようです。

ディープラーニングってなに?

Chainerのexampleを動かしたのはいいのですが、そもそもディープラーニングがなんなのかよくわかっていないので、これからなにをさせようか、と思った時に困りました。というわけでディープラーニングを調べました。
一体なにがディープなのか。この時はよくその話をしていました。

失敗1:局所的な話にハマる

資料

shi3zさんのブログの

Googleの画像判別は、画像認識のためのコンボリューションニューラルネットワーク(CNN)を前段に、それを文章化するためのリカレントニューラルネットワーク(RNN)を後段に持ってきている。

 CNNに代表されるニューラルネットワークは内部状態を持たず、学習結果がネットワークそのものに保存される。つまり、ある時点のニューラルネットワークに同じ入力を与えれば常に同じ出力が返ってくる。

 これに対し、RNNは内部状態を持ち、同じ入力を与えても文脈によって出力が異なる。
 イメージ的にはCNNが数学上の関数に近い(同じ入力に対しては常に同じ答え)のに対し、RNNはコンピュータや動物に近い。

を読んで、CNNはざっくりいうとただの期待する関数を得る近似系という認識だったのですが、RNNはしらなかったのでこの辺が新しいのかなどと考えました。

そこでRNNを調べたのですが、どうやらRNNも結局時間軸に対して展開可能であることがわかり、結局入力が複雑になったNNには違いないということがわかり特に魔法でもなんでもなさそう。

結局この辺は瑣末な点でもちろん本質的に新しい部分ではなかったですが、とりあえず目先から当たった結果時間を使ってしまいました。

失敗2:ディープラーニングなプロダクトを使ってみる

資料


あ、これはなんか違うなと思い、ひとまずディープラーニングを触ってみようと。そこで、Labellioを触ってみました。

結果は簡単で面白いなとは思いましたが、特に簡単な部分はLabellioの凄さであってディープラーニングとは関係ないですね。Labellioは楽しかったですが、ディープラーニングを理解するという意味ではその辺のブログで得られるディープラーニングでなにができるかの例と同じ程度しかわからなかったです。

関連:ディープラーニングでなにができるのかを知る

また『人工知能は人間を超えるか』を中途半端に読んだのですが、それでなにができるのかはなんとなくつかんだつもりになっていて、しばらくはそれでGOしていました。なにができるかという意味ではあの本は良かったのですが、初めの方で機械学習の時代の遷移として書かれていたので、ディープラーニングというのはニューラルネットワークに限定される話ではなく、機械学習の任意のアルゴリズムで活用できる新しい学習の仕方なのかとか変な勘違いをしました。凄まじく無知ですね。

まとまった資料を読む

資料

最終的にはっきり理解したのは、『深層学習』の岡谷さんのスライドを読んだ時です。
このスライドは素晴らしくて、ディープラーニングを古いネットワークと対比して定義していて、つまり浅いNNではなく、深いNNを使う方法なのだと。この時に今となっては当たり前の認識になりましたがディープラーニングはニューラルネットワークのみで構成されるシステムなのだと初めて確信しました。
またこのスライドがさらに良かったのは、なにが良くなってなにがこのシステムの問題で、なぜそれが解決されるようになったのかなど、ディープラーニングに至る技術的なポイントもまとめられていた点です。
最後に現状のまとめもあるので良く俯瞰できます。

また、「ディープラーニングの過去と未来」では、歴史的な経緯の情報が多く、ディープラーニングの発展の流れを把握するにはすごく良かったです。dropoutなどブレイクスルーの説明もわかりやすい。

結局、初めっから素直にディープラーニングでググって資料を漁っていればもっと早く全体が見れていたという失敗談でした。

Chainerのexampleを解釈する/簡単なコードを書く

資料

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なんかはぐぐってはみたものの、日本語のいい解説がヒットしなかったので詳しく知るにはここで紹介されている論文を読むくらいしかなさそう。

ネタ

資料

これからじゃぁディープラーニングをつかってなにをやろう?と思った時に

Machine Learning Impact Challenges

6つの問題を提示している

機械学習による分析の結果によって法的判断を行うか,法案を通せ
機械学習による意思決定で100万ドル貯めろ
機械学習による高精度な翻訳で2国間の衝突を回避しろ
機械学習による防衛でネット上の不正侵入を50%減らせ
機械学習による診断,もしくは介入によって人命を救え
機械学習によってある国の人間開発指数を10%向上させろ

これは参考になるネタだなと思いました。

PRML輪読4, 5日目

ディープラーニングとのギャップを感じて深層学習に浮気しつつも予定通り輪読も進めています。
また更新忘れていたので二日分のまとめ

進捗

4日目の範囲

  • 2 : 確率分布
  • 2-1 : 二値変数
  • 2-2 : 多値変数

5日目の範囲


さすがに1回1時間の輪読では全然計算をカバーできなくなってきて、大事だとおもったところの式展開を追いかけつつ流れを追うような感じで進めています。2章が終わったくらいで一通り計算して答え合わせ回みたいな回を作るかも....

ベイズのための確率分布

この章は1章で導入したベイズ理論のためにいろいろな確率分布を紹介しています。

重要な概念として、共役事前分布があり、このような性質を持つ分布は事前分布に使った時に事後分布も同じ形をとります。つまり、この分布を使えば簡単に次々と増えた情報を確率の補正に適用でき、また逆にこのような性質を持たない分布を使ってベイズ的な確率の取り扱いは困難でしょう。

ここまでの感触

まず導入として二項分布の拡張であるベータ分布などを押さえて、ガウス分布を取り扱いました。ガウス分布については、だいぶ線形代数の知識が求められて計算が重たくなってきました。
また、それぞれの分布が具体的にどの局面で使われるのかという対比がまだうまくできていないのでそこを考察する必要を感じています。なので2章が終わった後で考察してまとめます。

PRML輪読2, 3日目

更新をサボっている間に3日目が終了しました。

進捗

2日目の範囲

  • 1-2-5:曲線フィッティング再訪
  • 1-2-6:ベイズ曲線フィッティング
  • 1-3:モデル選択
  • 1-4:次元の呪い

3日目の範囲

一章を読んで

1章通して、回帰問題やクラス分類問題に確率を導入する方法を学びました。たとえば、多項式のフィッティングなどに確率論を導入しました。

確率を導入する場合は、

  1. サンプルされたデータをもとに、ある値に対する出力の確率分布を求める
  2. 確率分布より値を決定する

という2ステップで値が決まります。

たとえば、多項式フィッティングをした場合近似関数f(x)が求まるので、
f(x=10) = 5
のように関数にxを代入してやれば答えが得られます。
確率を導入した場合は、まず確率分布p(t|x)が得られるので、
.
.
p(4|x=10) = 0.1
p(5|x=10) = 0.8
p(6|x=10) = 0.08
.
.
のように、x=10の点での値の確率分布がまず得られて、この確率をもとに
x=10のときは5
と値を決めます。

確率を導入するメリット

確率を導入する目的として、そもそも過学習などの問題を解決するという目的はあったのですが、他にも

  • 外部要求であまり間違えて欲しくない間違え方がある場合、確率に補正を加えるという簡単な方法で対応できる(リスク最小化)
  • 値決定の妥当性が確率で出ているため、決定が難しい値を決めずに判断を人力に委ねることができる(棄却オプション)
  • 識別したいデータが母集団の中で十分に少ない時、そのまま学習データとして用いると精度が全く出ない可能性があるが、確率で出すなら識別したいデータを抽出し、学習した後確率を補正する方法で精度を得ることができ、また容易に補正できる。

など、いろいろと確率という情報があることによってできることがあることを知りました。

情報理論については、各種エントロピーがどのように取り扱われているのかがわからないので理解は甘いのですが、話としては定性的な情報量の議論からそれを支えるロジックとしてミクロカノニカル分布を導入しての説明があったのでしっかりしているなという印象を受けました。情報量についても確率が小さいほど大きく、また独立な事象は足し合わせることができる、という要求のもとに一番シンプルな関数を定義しているのかな、という筋道がしっかり立っていたのでよくわかった感じがします。
内容に関しては、情報理論におけるエントロピー統計力学と異なり、1要素あたりのエントロピーエントロピーとして扱うのだということを確認しました。あとボルツマン定数も付いてない。

式展開をしっかり追うために、演習を解きたいと思いつつ、ひとまず全体の展望を見るために先に進むことにしました。

ChainerのサンプルのMNIST学習が動かなかった(修正済み)

 
追記(2015/7/3 12:10)

Twitterで@unnonounoさんからレスポンスをいただき、すぐに修正していただきました!以後は普通に

python chainer/examples/mnist/train_mnist.py

を実行すれば実行可能です!

 

また、このtrain_mnist.pyですが、デフォルトでCPUのみで計算をします。--gpu=0等のオプションをつけるとGPUで計算してくれます。

参考

cvl-robot.hateblo.jp

 

 
 
結論から先に行うと、最新のサンプルでは、データダウンロード用のコードを先に実行する必要があります。
python chainer/examples/mnist/download_convert.py
を実行してから
python chainer/examples/mnist/train_mnist.py
を実行してください。
 
 

DIGITSでぶんまわして遊んだので、そろそろ手入れて遊びたいとChainerをインストールしました。

インストールまではよかったよですが、最後、サンプルのMNISTを学習させる
chainer/examples/mnist/train_mnist.py
が動かない。どうやらmnistの画像がないらしい。
あれ?自分で用意するのかなとか思ったけど、ググっても特にそんな記述はない。
探しているうちにtrain_mnist.pyがデータのダウンロードまでしてくれるとのこと。
 
 

hi-king.hatenablog.com

mnist = fetch_mldata('MNIST original')

上のブログによると、どうやらこれがダウンロードに関係しているらしい。

ところが、手元のコードでこの記述を探すとそもそもfetch_mldataという記述がない。

あれっと思いgithub見に行くと

f:id:sora_sakaki:20150703083942j:image
 
これですね。
Remove dependency on scikit-learn's fetch_mldata
このコミットでダウンロードするスクリプトが追加されて、train_mnist.pyからダウンロードしなくなったようです。
README.mdの変更も時間の問題とは思うけど、今始める人は気をつけて。
 

学習でちょっとあそんでみた話

Juiz(先日作った我が家のディープラーニング用マシン)が無事起動して、セットアップを進める傍ら、Labellioというサービスを使って学習して遊んでみました。

Labellioで学習体験

このLabellioってサービスは、任意の画像を学習させて識別させるということを提供するクラウドです。
これがまたすごくて、何がすごいってとても簡単なんですよ。登録はgoogleアカウントでできて、その後の学習用のサンプルはなんとキーワードだけでBingから検索してきてくれる!全く知らなくても5分で遊べるサービスです。

実際昨日は昼休みに「ONEPEACE」「NARUTO」で学習させてマイナーキャラを食わせて識別できるかなどをやっていました。
たとえばこんな感じ。
f:id:sora_sakaki:20150702101222p:plain

あとニッチな話ですが絵師さんのkaroryさんとななろば華さんの絵が似てるという話があるのでそれも識別してみました。





というわけで、5分でやっつけた学習でしたが、わりと識別できました。余談ですがどちらの絵師さんも好きでタペストリとか集めてます。
ディープラーニングしようと環境を整えている自分ですが、実際に自分で画像を識別したのは初めてだったので楽しかったです。是非体験してください!

Juizの進捗

とりあえずCUDA, Caffe, DIGITSのインストールまで終わって無事MNISTの学習などができるようになりました。
それはそうと、DIGITSが落ちると再起動後すでに作成済みのモデルデータが一覧から消えて認識されないんですが、なにが原因なんですかね?

PRML輪読1日目

ディープラーニングの話と並行して、週2でPRMLの輪読を始めました。1日で用意は大変だった....


今日の分は、1章の始めから1-2の途中までです。
話の流れとしては、サンプリングデータを多項式でフィッティングし、その多項式の自由度を大きくするとうまくいかなくなるがそれをなんとか解決しよう、というものです。


まずあるサンプリングデータを多項式
{ \displaystyle

f(x) = \sum_{j=1}^M w_j x^j

}
で最小二乗法を用いてフィッティングする。サンプル数に対して項数Mが十分近い数になると本来のカーブを無視してほぼ全ての点をなぞるようなカーブになり、項数がサンプル数-1になったときに全ての点を通るようになる。これは納得できる結果で、方程式において数式の本数-1個の定数を決めることができることを考えると、この場合もデータ点の数だけ w_j の方程式が得られるから、情報量的に係数は一意に定めうるわけです。

以前、某NPOで自由落下実験の教材を作成していたとき、同じ問題に当たりました。簡易で小さい実験装置だったため、8点程度しかデータが取れなかったのですが、空気抵抗の影響を見たいと3次や4次の多項式でフィッティングするわけです。すると、3次や4次の補正項が大きくなって、重力加速度の項である2次の項は0.3とかとても小さな数になり、重力加速度は0.6m/sだった!とわけのわからない結果が出ます。
もちろんこれは期待した結果ではないので、この時は結局空気抵抗を無視して2次でフィッティングして事なきを得ました。(空気抵抗の影響がほとんどなかったため)


脱線してしまったけど、このような過学習をさける為に関数が与える出力は確率的な値を取るという仮定をして、そこに正規分布を導入する。これによりある程度誤差や正則化(この場合における過学習を避けるアプローチ)について分析するというのがこの後の流れとなる。


以上、非常においしいところで終わってしまった。さすがに1日の、始発でジョナサンにいって籠って作業した朝の時間だけで用意するにはこの辺が限界でした。
個人的に面白かった部分としては、確率を考慮しないフィッティングでも、誤差の関数に補正項として係数ベクトルの長さに関する項を導入することである程度対応できるというところでしょうか。苦い思い出があるだけに、なるほどと言わされました。
また、ベイズ確率については情報が増えればそれで確率が変化する、という考えのようですがWikipediaの情報も補足的に加えたところ、つまりこれは観測に必要な情報が足りていないから、情報が増えれば本来の正しい確率に近づく、という考え方のようですね。少し決定論的なほうこうにバランスが悪い感じもしますが、わりとよさそうです。
あとはこの辺の確率論のどれかが、集合論の拡張だ、という記述を本文中のどこかで見かけた気がしたんだけどどこだろう。それが気になる。