2017/02/11 名古屋Ruby会議03
antimon2(後藤 俊介 / 機械学習名古屋)
Sinatra + tensorflow.rb で動いていますした。
ここから本題…。
2017/02/11 名古屋Ruby会議03
antimon2(後藤 俊介 / 機械学習名古屋)
gem install tensorflow
…$ gem install tensorflow
ERROR: Could not find a valid gem 'tensorflow' (>= 0) in any repository
...
$ bundle exec rake spec
: 《中略》
dyld: lazy symbol binding failed: Symbol not found: _TF_NewStatus
Referenced from: /path/to/gems/tensorflow-0.0.1/lib/sciruby/Tensorflow.bundle
Expected in: flat namespace
dyld: Symbol not found: _TF_NewStatus
Referenced from: /path/to/gems/tensorflow-0.0.1/lib/sciruby/Tensorflow.bundle
Expected in: flat namespace
: 《後略》
$
$ docker pull nethsix/ruby-tensorflow-ubuntu:0.0.1
$ docker run --rm -it -v `pwd`:`pwd` --expose 4567 -p 8000:4567 \
nethsix/ruby-tensorflow-ubuntu:0.0.1 /bin/bash
source 'https://rubygems.org' gem 'tensorflow', path: '/repos/tensorflow.rb' gem 'sinatra' # gem 'sinatra-contrib' gem 'thin'
bundle install
$ bundle install
: #《中略》
Bundle complete! 3 Gemfile dependencies, 11 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
(ry
require 'tensorflow' sess = Tensorflow::Session.new graph = Tensorflow::Graph.new graph.read("trained_graph.pb") sess.extend_graph(graph)
.pb のフォーマットが間違っていると…
E tensorflow/core/common_runtime/executor.cc:334] Executor failed to create kernel. Invalid argument: NodeDef mentions attr 'Tshape' not in Op<name=Reshape; signature=tensor:T, shape:int32 -> output:T; attr=T:type>; NodeDef: Reshape = Reshape[T=DT_FLOAT, Tshape=DT_INT32, _device="/job:localhost/replica:0/task:0/cpu:0"](_recv_Placeholder_0, Reshape/shape)
[[Node: Reshape = Reshape[T=DT_FLOAT, Tshape=DT_INT32, _device="/job:localhost/replica:0/task:0/cpu:0"](_recv_Placeholder_0, Reshape/shape)]]
E tensorflow/core/client/tensor_c_api.cc:485] NodeDef mentions attr 'Tshape' not in Op<name=Reshape; signature=tensor:T, shape:int32 -> output:T; attr=T:type>; NodeDef: Reshape = Reshape[T=DT_FLOAT, Tshape=DT_INT32, _device="/job:localhost/replica:0/task:0/cpu:0"](_recv_Placeholder_0, Reshape/shape)
[[Node: Reshape = Reshape[T=DT_FLOAT, Tshape=DT_INT32, _device="/job:localhost/replica:0/task:0/cpu:0"](_recv_Placeholder_0, Reshape/shape)]]
/repos/tensorflow.rb/lib/tensorflow/session.rb:103: [BUG] Segmentation fault at 0x00000000000017
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-linux]
-- Control frame information -----------------------------------------------
c:0007 p:---- s:0040 e:000039 CFUNC :tensor_size
c:0006 p:0015 s:0036 e:000035 METHOD /repos/tensorflow.rb/lib/tensorflow/session.rb:103
c:0005 p:0009 s:0029 e:000028 BLOCK /repos/tensorflow.rb/lib/tensorflow/session.rb:42 [FINISH]
: (ry
# x: 要素数 784 の数値の配列(を期待) input1 = Tensorflow::Tensor.new(x, :float) res = sess.run( { 'Placeholder' => input1.tensor }, ['Softmax'], nil ) print res[0][0], "\n" # => [7.959904735344026e-09, 2.4618149532806832e-11, 9.080870950128883e-05, 1.0324711918752172e-10, 2.9449205296572245e-09, 1.312004671571998e-10, 1.6875362218726764e-09, 5.2551704307624014e-12, 0.9999091625213623, 3.465244091671593e-08]
ちょっとでも間違ったモノを渡したりすると…
E tensorflow/core/client/tensor_c_api.cc:485] Input to reshape is a tensor with 783 values, but the requested shape requires a multiple of 784
[[Node: Reshape = Reshape[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/cpu:0"](_recv_Placeholder_0, Reshape/shape)]]
/repos/tensorflow.rb/lib/tensorflow/session.rb:103: [BUG] Segmentation fault at 0x00000000000017
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-linux]
-- Control frame information -----------------------------------------------
c:0007 p:---- s:0040 e:000039 CFUNC :tensor_size
c:0006 p:0015 s:0036 e:000035 METHOD /repos/tensorflow.rb/lib/tensorflow/session.rb:103
c:0005 p:0009 s:0029 e:000028 BLOCK /repos/tensorflow.rb/lib/tensorflow/session.rb:42 [FINISH]
: (ry
# mnist.rb require 'tensorflow' class MNIST def initialize(model) sess = Tensorflow::Session.new graph = Tensorflow::Graph.new graph.read(model) sess.extend_graph(graph) @sess = sess end
def classify(x) input1 = Tensorflow::Tensor.new(x, :float) res = @sess.run( { 'Placeholder' => input1.tensor }, ['Softmax'], nil ) res[0][0] end end
# app.rb require 'sinatra' require 'thin' require 'json' require_relative 'mnist' configure do # 略:IPの設定、Thin Backend の設定
def classify(x) @@mnist ||= MNIST.new("trained_graph.pb") @@mnist.classify(x) end
post '/classify' do content_type :json begin x = JSON.parse(params["x"]) res = classify(x) res.to_json rescue Exception => e "[]" end end
<script> // (ry function classify() { var myCanvas = document.getElementById("myCanvas"); var ctx = myCanvas.getContext("2d"); var data = []; // (ry: canvas からピクセルデータを読み込む処理 jQuery.ajax("classify", { dataType: "json", data: "x=" + JSON.stringify(data), type: "POST", success: function (res) { // (ry: 整形して表示する処理 } }); } // (ry </script>
<div id="board"> <canvas id="myCanvas" width="112px" height="112px"></canvas> <p> <button id="classify" onclick="classify()">Classify</button> <button id="clear" onclick="myClear()">Clear</button> </p><p> Result: <input type="text" id="result_output" size="5" value=""><br> <textarea id="result_detail" cols="30" rows="10"></textarea> </p> </div>
ご清聴ありがとうございます。