プログラミングの世界には、どんな言語にも Hello, World! と言われる、最初のプログラムがあります。
単純に画面に Hello, World!
と表示するだけなのですが、
今まで使わされるだけだったコンピュータに、初めて自分で命令するという、
プログラミング人生において非常に重要な体験を担っています。
機械学習の世界で Hello, World! にあたるものがなにか探してみると、どうやら MNIST という手書き文字認識がそれに当たるようです。 これをやってみようと思い、Webサイト でデータをダウンロードしました。 そして絶句。
なんとすべての画像データが1つのバイナリファイルに独自形式で収められています。 そしてそれに対応する数字のデータ( ラベル )は別のバイナリファイルに収められています。 このバイナリファイルをパースして読むという作業で 完全に精神が崩壊 しました。
実は一旦ここで挫折し、欲しいアプリケーションを作ろうといろいろ実験を重ねたものの、やはり成功体験がないのでにっちもさっちも行かなくなり、数カ月後に再びMNIST入門に挑戦しました。 というより、他の人に勧められて使うことになった Keras というフレームワークが、やはりチュートリアルでMNISTを扱っていたのでした。
Kerasのチュートリアルを写経してみたところ、大変な事実を目の当たりにします。 Kerasには、なんと使いやすい形式でMNISTのデータを取得できる関数が用意されているのです。 なぜライブラリにデータを入れた・・・ Rubyistには正直この発想は理解できませんでした。
そしてその関数で取得できるデータが、やはり画像だけの配列とラベルだけの配列が別々になっていました。
何故だ・・・ 何故お前らは何故なんだ・・・
なぜ {image: binary, label: number}
の配列じゃないのか、本当に理解できません。
インデックスで配列同士を関連させるなんて、ハッシュの配列に比べたら不確かすぎます。
学習させるときも、fit
関数にデータの配列とラベルの配列を渡します。
学習の順番をシャッフルするオプションもあります。
何故だ・・・
2つの配列を関係を崩すこと無くシャッフルするのは、そんなに簡単なことではないような気がします。
一方、 {image:, label:}
の配列をシャッフルするのは、当たり前ですが非常に簡単です。
何故だ・・・何故こんな実装なんだ・・・
機械学習の人間にはデータ構造という概念がないのだろうか、と本気で頭を抱えました。
チュートリアルを写経し、99%以上の認識精度がでたものの、pythonもしくは機械学習の文化 に完全に拒否反応を起こしました。 この瞬間、次回のテーマを Rubyでやる機械学習 にしようと決意しました。