RubyからTensorFlowを動かしてみる

October 2, 2016

やってみた系記事です。

機械学習ライブラリTensorFlowをrubyから操作するためのライブラリがリリースされました。

https://github.com/somaticio/tensorflow.rb

docker imageが提供されているので、それを使って早速試してみました。

必要なもの

docker環境

コンテナ起動

READMEにもありますが、TensorFlowなど必要なライブラリがインストールされたdocker imageが用意されています。

$ docker run -it nethsix/ruby-tensorflow-ubuntu:0.0.1 /bin/bash

コンテナが起動したら、以下を実行してrspecを通しましょう。

$ cd /repos
$ git clone https://github.com/somaticio/tensorflow.rb.git
$ cd tensorflow.rb/ext/sciruby/tensorflow_c
$ ruby extconf.rb
$ make
$ make install
$ cd ../../..
$ bundle exec rake install
$ bundle exec rspec

specでerrorが出なければ :ok:

注意点としては、あえてライブラリの最新版をcloneして再ビルドしているところです。 container内にあるtensorflow.rbは古いようで、specは確かに実行できるのですが https://medium.com/@Arafat./introducing-tensorflow-ruby-api-e77a477ff16e#.7q7o9x2nz にあるコードを実行することができませんでした。

プロジェクト作成

適当な作業フォルダを作って、以下のGemfileを用意します。

source 'https://rubygems.org'

gem 'tensorflow', path: '/repos/tensorflow.rb'

依存関係の修正

bundle installしても、実際にtensorflowをrequireして実行するとエラーになります。

/repos/tensorflow.rb/lib/tensorflow/core/framework/tensor.pb.rb:4:in `require': cannot load such file -- protocol_buffers (LoadError)

tensorflow.gemspecを見ると、gemの実行に必要なprotocol_buffersnarrayがdevelopment dependencyとして定義されています。 私の理解が間違っていなければ、実行に必要な依存ライブラリはadd_runtime_dependencyで定義されるべきです。 現在PRをこちらで出しています。

https://github.com/somaticio/tensorflow.rb/pull/73

取り急ぎは、/repos/tensorflow.rb/tensorflow.gemspecを直接書き換えた上で自分のプロジェクトでbundle installしてください。

和の計算の実行

以下のプログラムを作業フォルダにおいて実行してみましょう。 tensorflow.rbのspec/以下にあるtensorの和を計算するプログラムです。 スペースとかがガタガタだったのでちょっとだけ揃えましたが、基本的にはコピペです。 (tensorの和を計算する、って言い方であってるのだろうか。。。)

require 'tensorflow'
graph = Tensorflow::Graph.new
input1 = graph.placeholder('input1', Tensorflow::TF_DOUBLE, [2, 3])
input2 = graph.placeholder('input2', Tensorflow::TF_DOUBLE, [2, 3])
graph.define_op('Add', 'output', [input1, input2], '', nil)

session = Tensorflow::Session.new
session.extend_graph(graph)

input1 = Tensorflow::Tensor.new([[1.0, 3.0, 5.0], [2.0, 4.0, 7.0]])
input2 = Tensorflow::Tensor.new([[-5.0, 1.2, 4.5], [8.0, 2.3, 3.1]])
result = session.run(
  { 'input1' => input1.tensor, 'input2' => input2.tensor },
  ['output'],
  nil
)
print result[0], "\n"
$ bundle exec ruby sample.rb
[[-4.0, 4.2, 9.5], [10.0, 6.3, 10.1]]

と出力されればOKです。

各行の意味はまだちゃんと理解できていませんが、とりあえず動きました。 次は画像認識チュートリアルなんぞでもやってみようと思います。

comments powered by Disqus