🐙
mruby-tflite-xnnpack を作った。
はじめに
以前、MRuby から TensorFlow Lite を扱える mruby-tflite を以前作りました。
またこの mrbgem から Coral EdgeTPU の delegate を使えるプラグイン的な mruby-tflite-edgetpu を作りました。
今回は XNNPACK delegate を作りました。
これにより、Coral EdgeTPU を持ってない人でも、高速(通常よりは)な推論ができる様になります。
どんな事ができるか
EdgeTPU delegate と同じく、mruby-tflite から delegate として追加できる様になっています。
options = TfLite::InterpreterOptions.new
options.add_delegate TfLite::XNNPACK.new(4)
model = TfLite::Model.from_file 'detect.tflite'
interpreter = TfLite::Interpreter.new(model, options)
引数はスレッド数です。最近の XNNPACK は随分と速くなった様で、先日 go-tflite という Go から TensorFlow Lite を扱えるパッケージで試した所、CPU だけで 30fps 出てビックリしてしまいました。
うごく物
MRuby には現状、OpenCV で描画もできるライブラリが無いので、端末上に推論結果を出す様な物しかできません。
#! ./bin/mruby
options = TfLite::InterpreterOptions.new
options.add_delegate TfLite::XNNPACK.new(4)
model = TfLite::Model.from_file 'detect.tflite'
interpreter = TfLite::Interpreter.new(model, options)
interpreter.allocate_tensors
input = interpreter.input_tensor(0)
output2 = interpreter.output_tensor(1)
output3 = interpreter.output_tensor(2)
wanted_width = input.dim(1)
wanted_height = input.dim(2)
wanted_channel = input.dim(3)
data = Array.new(wanted_height * wanted_width * wanted_channel, 0)
labels = File.read('labelmap.txt').lines.map(&:chomp)
cam = Webcam.new(ARGV[0]||0)
cam.set_size(wanted_width, wanted_height)
cam.each(true) do |img|
decoded = GD::Image.new_from_jpeg_data(img)
(0...wanted_width).each do |x|
(0...wanted_height).each do |y|
pixel = decoded.get_pixel(x, y)
offset = (y * wanted_width + x) * wanted_channel
data[offset..offset+2] = [decoded.red(pixel), decoded.green(pixel), decoded.blue(pixel)]
end
end
decoded.destroy
input.data = data
interpreter.invoke
result = []
output3.data.each_with_index do |v, i|
next if v < 0.6
result.push([v, output2.data[i]])
end
result.sort{|a, b| b[0] <=> a[0] }.take(5).each_with_index do |v, i|
s = v[0]
i = v[1] + 1
puts "#{labels[i]} #{i} #{s}"
end
puts "---"
end
画像を読み込んで、配列に詰め直す部分が遅すぎて 15fps 程度しか出ませんが、なんとか動きます。OpenCV があれば...
おわりに
いやー、MRuby から OpenCV 扱いたいー!(自分で作れ)
Discussion