• DoRubyとは
  • お問い合わせ
  • Ruby/Rails
  • Web開発
  • Webマーケティング
  • アピリッツ
  • ライフハック
  • ゲーム制作/開発
  • Railsの小技
  • Rubyの小技
  • Gemの紹介
  • ActiveRecord
  • 初心者向け
  • Java/Scalaテク
  • Unixのあれこれ
  • データベース
  • スマホ開発
  • HTML/CSS/JavaScript
  • デザイン製作
  • インフラ
  • クラウド
  • セキュリティ
  • エディタ
  • バージョン管理
  • その他
  • python
  • アクセス解析
  • Googleアナリティクス
  • Googleデータスタジオ
  • Web広告
  • SEO
  • UI/UX
  • ソーシャルメディア
  • EC開発
  • Webシステム開発
  • コンサルティング
  • Webデザイン
  • ブロックチェーン
  • ゲーム紹介
  • アプリ紹介
  • ASP
  • 風景
  • パソコン
  • ツール
  • ガジェット
  • 仕事術
  • 健康
  • 生活
  • 書評
  • Excel(エクセル)
  • PowerPoint(パワーポイント)
  • ゲームプランニング
  • SpriteStudio
  • マスターデータ入力/作成
  • Unity
  • キャラクターデザイン
  • ゲームシナリオ
  • レベルデザイン
  • ゲーム分析
  • 3DCG
  • イラスト制作
  • CG/アニメーション
  1. ホーム
  2. Ruby/Rails
  3. Gemの紹介
  4. Ruby×PyCallでTensorflowのMNISTチュートリアル
  • 2018-03-28
    • カテゴリ:
    • Gemの紹介
    • タグ:
    • 機械学習
    • pycall
    • tensorflow
    • MNIST

Ruby×PyCallでTensorflowのMNISTチュートリアル

この記事は公開から1年以上が経過しています。情報が古い可能性がありますのでご注意ください。

PyCallを使ってRubyからpythonのライブラリを呼べるようにしたので、Tensorflowの昔のチュートリアルであるMNISTデータセットの画像分類をやってみました。

はじめに

みなさまお久しぶりです、くろすです。
新卒を名乗れるのもあと数日になりましたが、気持ち的にはあと3年くらい新卒扱いでひたすら勉強できる機会が欲しいなって思います。

めちゃくちゃ今更感ありますが、RubyからPyCallを使ってtensorflowを動かしてみました。
学生時代自分でガリガリ微分してMATLABのコードに起こしてDNN作っていたのがアホらしく感じてしまいます。

Rubyでデータサイエンス

かなり前どこかで読んで覚えていたのですがRubyでデータサイエンスをするためには3つほど手段があるそうです。
一つ目は「巨人の肩に乗る」
二つ目は「既存のgemを何とかする」
三つ目は「Rubyのための仕組みを作る」

今回はこの「巨人の肩に乗る」という方法でRubyから機械学習をやりたいと思います。

環境

$ ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin16]
$ gem list | grep pycall
pycall (1.0.3)

$ python3 -V
Python 3.6.4
$ pip3 freeze | grep tensorflow
tensorflow==1.6.0

Rubyのコード

今回やったチュートリアルはtensorflowのversion r1.2のチュートリアルのうちMNISTを使ったやつです。
https://www.tensorflow.org/versions/r1.2/get_started/mnist/beginners

tensorflowのバージョンが1.6.0でもちゃんと動きました。

require 'pycall'
require 'pycall/import'

module Python
  extend PyCall::Import
  class << self
    def from(path, import: nil)
      pyfrom path, import: import
      self.send import
    end

    def method_missing(method_name)
      pyimport method_name
      self.send method_name
    end
  end
end
require_relative 'python'
# Python library import
Python.from('tensorflow.examples.tutorials.mnist', import: :input_data)
tf = Python.tensorflow
input_data = Python.input_data

# Download MMIST dataset
mnist = input_data.read_data_sets('MNIST_data/', one_hot: true)

# Input, weight, bias
x = tf.placeholder(tf.float32, [nil, 784])
w = tf.Variable.new(tf.zeros([784, 10]))
b = tf.Variable.new(tf.zeros([10]))

# Output
y = tf.nn.softmax(tf.matmul(x, w) + b)
y_ = tf.placeholder(tf.float32, [nil, 10])

# Error function
cross_entropy = tf.reduce_mean(-1 * tf.reduce_sum(y_ * tf.log(y), reduction_indices: [1]))

# Train Model
train_step = tf.train.GradientDescentOptimizer.new(0.5).minimize(cross_entropy)

sess = tf.InteractiveSession.new
tf.global_variables_initializer.run

# Train start
1000.times do
  batch = mnist.train.next_batch(100)
  batch_xs, batch_ys = batch[0], batch[1]
  sess.run(train_step, feed_dict: {x => batch_xs, y_ => batch_ys})
end

# normalize
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

# Result
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
puts sess.run(accuracy, feed_dict: { x => mnist.test.images, y_ => mnist.test.labels })

わざわざPythonモジュールとして切り出しているのはmath.rbとか作って確認してた名残なので、実際はtensorflow_tutorial.rbにベタ書きしても問題ないです。

結果

$ ruby tensorflow_tutorial.rb
0.9185

This should be about 92%.

確かに正答率92%くらいになりました。

詰まった所

pycallが読みに行くpythonが/usr/bin/python

環境変数PYTHONを使いたいpythonにすればいい

$ export PYTHON=path/to/python3

データセットをダウンロードしようとしてSSL関係でエラー

$ /Applications/Python\ 3.6/Install\ Certificates.command

で解決
参考( https://github.com/tensorflow/tensorflow/issues/10779 )

tf.matmul(x, w)でなんかエラーでた


Exception: PyCall::PyError: <class 'TypeError'>: _as_graph_element() missing 1 required positional argument: 'self'
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py", line 2004, in matmul
  with ops.name_scope(name, "MatMul", [a, b]) as name:
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 5616, in __enter__
  g = _get_graph_from_inputs(self._values)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 5277, in _get_graph_from_inputs
  graph_element = _as_graph_element(op_input)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 118, in _as_graph_element
  return conv_fn()


直前の部分をrubyコードに読み替えるのをミスっていた

pythonの元コード: tf.Variable(tf.zeros([10]))
間違えたrubyコード: tf.Varialbe(tf.zeros([10]))
よく見るrubyコード: tf.Variable.(tf.zeros([10]))

よくPyCall使ってrubyで…って記事には tf.Variable.(tf.zeros([10])) のように書いてありますが、これはtf.Variableクラスの()メソッドを呼んでいる、つまりコンストラクタの呼び出しなのでruby的に書くならinitializerを呼び出してあげれば良いんですね。
じゃあちょっと冗長ですがnewしましょう。

正解のrubyコード: tf.Variable.new(tf.zeros([10]))

連想配列の違いで手間取った

元のPythonコード: sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
Ruby間違いコード : sess.run(train_step, feed_dict: {x: batch_xs, y_: batch_ys})
Ruby正解コード  : sess.run(train_step, feed_dict: {x => batch_xs, y_ => batch_ys})

終わりに

PyCallを使ってRubyからtensorflowを使ってMNISTのチュートリをやった的な記事がぱっと見当たらなかったので書いてみましたが、ほぼほぼチュートリアルのコードを書き写したみたいになってあまり面白くはなかったです。
今回はわざわざPyCallを使ってRubyからtensorflowを触りましたが、実は tensorflow.rb というRubyAPIがあったりするので、次はそっち使って遊んでみます。


  • 163 views
    • Tweet
    • このエントリーをはてなブックマークに追加

この記事を書いた人
くろす
17/AG/newbie

「いいね!」するとDoRubyの最新記事を受け取ることができます。

Facebook

Twitterから最新記事を受け取るならこちら

Follow @doruby

Feedlyから最新記事を受け取るならこちら

follow us in feedly

おすすめの記事
  • 610 views
  • 2015-10-01
RailsのViewを自在にカスタマイズするための「Cosme」gem
  • 772 views
  • 2016-07-31
carrierwaveとfogでRiak CSへの画像アップロードを実装する

カテゴリ

Ruby/RailsRailsの小技Rubyの小技Gemの紹介ActiveRecord初心者向けWeb開発Java/ScalaテクUnixのあれこれデータベーススマホ開発HTML/CSS/JavaScriptデザイン製作インフラクラウドセキュリティエディタバージョン管理その他pythonWebマーケティングアクセス解析GoogleアナリティクスGoogleデータスタジオWeb広告SEOUI/UXソーシャルメディアアピリッツEC開発Webシステム開発コンサルティングWebデザインブロックチェーンゲーム紹介アプリ紹介ASP風景ライフハックパソコンツールガジェット仕事術健康生活書評Excel(エクセル)PowerPoint(パワーポイント)ゲーム制作/開発ゲームプランニングSpriteStudioマスターデータ入力/作成Unityキャラクターデザインゲームシナリオレベルデザインゲーム分析3DCGイラスト制作CG/アニメーション

    人気の記事
    • 41 views
    • 2019-12-09
    どうしようもないけどやれるだけのことはやってどうにかしよう
    最近の記事
    • 41 views
    • 2019-12-09
    どうしようもないけどやれるだけのことはやってどうにかしよう
    • 68 views
    • 2019-10-18
    カスタマーサポートの極意 2019 #3 レポート
    • 357 views
    • 2019-08-16
    Search Engineerring Tech Talk 2019 Spring レポート
    • 489 views
    • 2019-07-24
    Rails & Webpack案件でのgmo paymentのトークン決済
    • 481 views
    • 2019-07-12
    whenever で時刻を設定する際システムで設定されているのとは別のタイムゾーンを使用する
    Facebook

      サイト情報
      • DoRubyとは
      • 株式会社アピリッツ

      ソーシャルアカウント
      • Facebook
      • Twitter

      企業情報
      • 会社概要
      • 採用情報
      • お問い合わせ
      サービス製品
      • レコメンドASP
      • サイト内検索ASP「Advantage Search」
      • オープンソースECサイト構築パッケージ「エレコマ」
      • 受注・在庫・商品情報一元管理「モールコネクター」
      • セキュリティ診断サービス
      • Googleアナリティクスセミナー

      Copyright © Appirits All Rights Reserved.