Skip to content

Latest commit

 

History

History
27 lines (21 loc) · 2.68 KB

mnist.md

File metadata and controls

27 lines (21 loc) · 2.68 KB

PyCallでMNIST

もう少し実践的に、KerasでMNISTを学習させるコードをPyCallで移植してみましょう。 Python版のコードは、Kerasの公式サンプルほぼそのままです。 それをほぼ素直にRuby版に移植してみました。 気になるところを挙げていきます。

まず、Pythonでは (x_train, y_train), (x_test, y_test) = mnist.load_data() と一発で複雑な Tuple を変数に代入できます。 Rubyでも、同じような文法で RubyのArray を変数に代入できるのですが、残念ながらPyCallを使うと戻ってくるのは PyObject なので上手く動きません。 とはいえ、学習データと検証データに同じ前処理をする、という部分はRubyのほうが圧倒的に表現力が高いと思います。

もうひとつ、Sequential()Dense(512) などは、Rubyistには関数を実行しているように見えますが、これは Pythonのクラス でインスタンスを作るコードのようです。 インターネットで見つかるドキュメントでは、Pythonのコードに見た目を似せるためか Sequential.() という書き方をしている例が多くあります。 これは、 Sequential.call の糖衣構文ですが、正直見た目的にもあまり好きではありません。 むしろ Rubyらしく 堂々と Sequential.new と呼ぶほうが分かりやすいのではないでしょうか。 我々はPythonなど書きたくないのです。

さて気になるのは実行結果です。 機械学習なのでもちろん少し誤差はあるのですが、Ruby版もPython版と同じ精度が出たので、両者のコードは全く同一で、学習もきちんとできていると判断できそうです。 さらになんと、GPUを使った場合 も正しく動作しました。 速度に関しても、学習のstepあたりの実行速度を比較すると ほぼ同じ どころか環境によって Rubyのほうが速い こともありました12。 実際のアプリケーションでもPyCallは十分に実用になるということがわかりました。

それにしても、 tensorflowが最新のPython 3.7.1で動かないってホントにクソな言語だな と思いました。

Footnotes

  1. ラップトップではPythonのほうが速く デスクトップではRubyのほうが速かった

  2. GPUの場合は速すぎて誤差が可視化できなかった