LoginSignup
34
30

More than 3 years have passed since last update.

令和元年なのでRubyでDeep Learningする方法をリストアップしてみた。

Last updated at Posted at 2019-05-01

タイトルは釣りです。すみません。令和も2年目に突入しました。

 RubyでもDeepLearningを試してみたいなって思いませんか? そこで今までネットで見聞きした範囲でRubyでDeepLearningする手段をまとめてみました。数年前のように全く手も足も出ない状況からは少しずつ進歩しているなぁという印象です。

ruby-dnn

https://github.com/unagiootoro/ruby-dnn
ruby-dnn は Ruby + NArrayで全てのアルゴリズムが記述されています。注目すべきは、その記述法ですね。たとえばMNISTのサンプルを見てください。

model = Model.new

model << InputLayer.new([28, 28, 1])

model << Conv2D.new(16, 5)
model << BatchNormalization.new
model << ReLU.new

model << MaxPool2D.new(2)

model << Conv2D.new(32, 5)
model << BatchNormalization.new
model << ReLU.new

model << Flatten.new

model << Dense.new(256)
model << BatchNormalization.new
model << ReLU.new
model << Dropout.new(0.5)

model << Dense.new(10)
model << SoftmaxWithLoss.new

model.compile(Adam.new)

model.train(x_train, y_train, 10, batch_size: 100, test: [x_test, y_test])

なんだかワクワクしませんか? 後述するRed Chainerの弱点として、Chainerとの互換性を保っているため、どうしても記述がRubyっぽくないところがあります。その点ruby-dnnの書き方はシンプルで楽しい感じがします。またruby-dnnは完全にRubyだけで書かれた珍しいdeep learningライブラリです。なのであえて一番最初に紹介しました。

ONNX Runtime

https://github.com/ankane/onnxruntime
Microsoftの作っているONNXRuntimeのバインディングです。chartkick, searchkick, pgheroなど有名Gemを多数作成しているAndrew Kane氏が作成しています。学習済みモデルを使うことが前提で、モデルの入手やトレーニング自体は別のマシンでやります。すでにトレーニング済みのモデルがあって、Deep Learningを自分のアプリの中に組み込みたいという場合は、今回紹介したライブラリの中で一番実用性が高いと思います。ONNXファイルを読み込んで使います。

# load ONNX file
model = OnnxRuntime::Model.new("model.onnx")
# execute inference
model.predict(x: [1,2,3])

Torch-rb

https://github.com/ankane/torch-rb
本命候補。今後のライブラリの発展に期待。

ankane/tensorflow

Red Chainer

https://github.com/red-data-tools/red-chainer
ChainerをRubyで再実装したプロジェクトです。このプロジェクトのすごい点は、Deep Learningのアルゴリズムが全てRubyで記述されており、しかもGPUで動作するところです。弱点はChainerそのものが海外ユーザーへのアピールにとぼしい点でしょうか。

class MLP < Chainer::Chain
  L = Chainer::Links::Connection::Linear
  R = Chainer::Functions::Activation::Relu

  def initialize(n_units, n_out)
    super()
    init_scope do
      @l1 = L.new(nil, out_size: n_units)
      @l2 = L.new(nil, out_size: n_units)
      @l3 = L.new(nil, out_size: n_out)
    end
  end

  def call(x)
    h1 = R.relu(@l1.(x))
    h2 = R.relu(@l2.(h1))
    @l3.(h2)
  end
end

Red Chainer and Cumo: Practical Deep Learning in Ruby at RubyKaigi 2019
【Google Colab】Red Chainer を使ってみた

menoh-ruby

https://github.com/pfnet-research/menoh-ruby
MenohはChainerを作っているPreferred NetworksがC++で開発したライブラリです。インストールにはMKL-DNNが必要です。Menohはさまざまな言語にバインディングして使うことが想定されています。menoh-rubyはRubyのバインディングです。ONNX Runtimeが登場するまでMenohはRubyでONNXを動かせる唯一の方法でしたが今後の動きが注目されます。

# load ONNX file
onnx_obj = Menoh::Menoh.new './data/mnist.onnx'
# execute inference
inference_results = model.run image_set

RubyでONNXフォーマットのDNNの推論を可能にするExtensionを開発
Menohを使ってRubyでDeepLearningしてみた

Tensorflow.rb

mxnet.rb

PyCall + Pythonのライブラリ(Kerasなど)

はい、最後になりましたが、世間で最も有名で、もっとも実践されているRubyでディープラーニングする方法はこちらでしょう。欠点は、やってる途中にRubyを書いている意味がだんだんわからなくなって、直にPythonを書こうとしはじめてしまうところだと思います。

PyCallを使えばRubyでもKerasでDeep Learningができる - 洋食の日記 様より引用

require 'pycall/import'
include PyCall::Import

pyimport 'keras'
pyfrom 'keras.datasets', import: 'mnist'
pyfrom 'keras.models', import: 'Sequential'
pyfrom 'keras.layers', import: ['Dense', 'Dropout', 'Flatten']
pyfrom 'keras.layers', import: ['Conv2D', 'MaxPooling2D']

nb_classes = 10
img_rows = 28
img_cols = 28

(x_train, y_train), (x_test, y_test) = mnist.load_data.()

x_train = x_train.reshape.(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape.(x_test.shape[0], img_rows, img_cols, 1)
x_train = x_train.astype.('float32')
x_test = x_test.astype.('float32')
x_train /= 255
x_test /= 255

y_train = keras.utils.to_categorical.(y_train, nb_classes)
y_test = keras.utils.to_categorical.(y_test, nb_classes)

model = Sequential.()
model.add.(Conv2D.(32, kernel_size: [3, 3], activation: 'relu', 
                   input_shape: [img_rows, img_cols, 1]))
model.add.(Conv2D.(64, kernel_size: [3, 3], activation: 'relu'))
model.add.(MaxPooling2D.(pool_size: [2, 2]))
model.add.(Dropout.(0.25))
model.add.(Flatten.())
model.add.(Dense.(128, activation: 'relu'))
model.add.(Dropout.(0.5))
model.add.(Dense.(nb_classes, activation: 'softmax'))

model.compile.(loss: keras.losses.categorical_crossentropy,
              optimizer: keras.optimizers.Adadelta.(),
              metrics: ['accuracy'])

model.fit.(x_train, y_train,
          batch_size: 128,
          epochs: 10,
          verbose: 1,
          validation_data: [x_test, y_test])

score = model.evaluate.(x_test, y_test, verbose: 0)
print(sprintf("Test loss: %.6f\n", score[0]))
print(sprintf("Test accuracy: %.6f\n", score[1]))

番外 mruby-tflite

https://github.com/mattn/mruby-tflite
@mattnさんが作らているmrubyとTensorflow Liteのバインディングです。(mrubyなので番外としました)

番外 TensorStream

https://github.com/jedld/tensor_stream
こちらは、GitHubスター数は多いけど、内容は??な感じのライブラリです。READMEの紹介文をざっと見るとNArrayやCupyに相当する部分もすべて1人で開発しようとしている??本当にそんなことが可能なのでしょうか。詳しく見ていないですが、OpenCLを使うと書いてある部分と、マーケティングの巧みさに独自性を感じたので挙げました。

番外 ruby-cntk

残念ながら開発が止まっているみたい…
https://github.com/tamuratak/ruby-cntk

おわりに

 RubyでDeep Learningできそうなライブラリをリストアップしてみました。
 おそらく、これ以外にもRubyのディープラーニングする方法はあると思います。ライブラリを探すにしても、NMatrixやNArrayに依存しているライブラリは逆依存を調べることで発見できますが、それ以外はなかなか見つけられません。たとえば誰かがdarknetや、それよりずっと無名のCで書かれたディープラーニングライブラリに対して、Ruby用のバインディングを作っていても、Gem化していなかったり、Deep Learningといったキーワードを使っていなければ、捕捉するのは難しいです。たとえば、海外の人がmenoh-rubyを発見するのは相当むずかしいのではないでしょうか。そんな感じで埋もれているものもあると思います。なにか情報をお持ちでしたらコメント欄にお寄せください。

 この記事は以上です。令和元年おめでとうございます。ますますRubyで楽しくdeep learningできるようになるといいなと思います。

34
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
30