Logo
  • DoRubyとは
  • お問い合わせ
    • Ruby/Rails
    • Web開発
    • Webマーケティング
    • アピリッツ
    • ライフハック
    • ゲーム制作/開発
    • アプリ開発
    • Railsの小技
    • Rubyの小技
    • Gemの紹介
    • ActiveRecord
    • 初心者向け
    • Java/Scalaテク
    • Unixのあれこれ
    • データベース
    • スマホ開発
    • HTML/CSS/JavaScript
    • デザイン製作
    • インフラ
    • クラウド
    • セキュリティ
    • エディタ
    • バージョン管理
    • その他
    • python
    • アクセス解析
    • 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チュートリアル

      25db64a55190c0758dae6468e46a4f14

      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があったりするので、次はそっち使って遊んでみます。


      • 26 views

      この記事を書いた人
      F9cd312d5609e22b8636843d05b0ffb6?default=mm&size=80
      くろす
      17/OG/newbie

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


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

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

      follow us in feedly

      おすすめの記事
      • 331 views
      • 2015-10-01
      RailsのViewを自在にカスタマイズするための「Cosme」gem
      • 1,250 views
      • 2016-07-27
      リニューアルをしたDoRubyの3つの目的
      • 584 views
      • 2016-07-31
      carrierwaveとfogでRiak CSへの画像アップロードを実装する
      • 657 views
      • 2017-04-24
      アピリッツの新卒合宿2017

      カテゴリ

      Icon category 1Ruby/RailsList elementRailsの小技List elementRubyの小技List elementGemの紹介List elementActiveRecordList element初心者向けIcon category 4Web開発List elementJava/ScalaテクList elementUnixのあれこれList elementデータベースList elementスマホ開発List elementHTML/CSS/JavaScriptList elementデザイン製作List elementインフラList elementクラウドList elementセキュリティList elementエディタList elementバージョン管理List elementその他List elementpythonIcon category 5WebマーケティングList elementアクセス解析List elementGoogleアナリティクスList elementWeb広告List elementSEOList elementUI/UXList elementソーシャルメディアIcon category 6アピリッツList elementEC開発List elementWebシステム開発List elementコンサルティングList elementWebデザインList elementブロックチェーンList elementゲーム紹介List elementアプリ紹介List elementASPList element風景Icon category 7ライフハックList elementパソコンList elementツールList elementガジェットList element仕事術List element健康List element生活List element書評List elementExcel(エクセル)List elementPowerPoint(パワーポイント)List elementゲーム制作/開発List elementゲームプランニングList elementSpriteStudioList elementマスターデータ入力/作成List elementUnityList elementキャラクターデザインList elementゲームシナリオList elementレベルデザインList elementゲーム分析List element3DCGList elementイラスト制作List elementCG/アニメーションList elementアプリ開発

        人気の記事
        • 127 views
        • 2018-02-28
        新・メカニカルキーボード生活
        • 74 views
        • 2018-02-28
        Unityで画像の端に謎の線が出るときの対処法
        • 68 views
        • 2018-02-28
        Ruby黒魔術【callcc】でFiberを実装してみた
        • 52 views
        • 2018-02-28
        PhotoShopのアクションを用いて効率よく画像を処理する
        • 46 views
        • 2018-03-14
        意識しないとまずい? ActiveRecord SQLキャッシュの罠
        最近の記事
        • 26 views
        • 2018-03-28
        Ruby×PyCallでTensorflowのMNISTチュートリアル
        • 25 views
        • 2018-03-26
        よくわからないで使っている英語の意味を知っとこう
        • 25 views
        • 2018-03-26
        第12回「PUBGってなんだ!?最近流行りのバトルロワイヤルゲームとは?」
        • 18 views
        • 2018-03-26
        番外編 「食生活って意外と大事!?」
        • 17 views
        • 2018-03-26
        番外編 「筆者が物事を始めるときに気にする事柄」

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

          企業情報
          • 会社概要
          • 採用情報
          • お問い合わせ

          ソーシャルアカウント
          • Facebook
          • Twitter
          サービス製品
          • コミュニティサイト
          • Android向け ECアプリ制作パッケージ「ポケコマ」
          • レコメンドASP
          • サイト内検索ASP「Advantage Search」
          • オープンソースECサイト構築パッケージ「エレコマ」

          • 受注・在庫・商品情報一元管理「モールコネクター」
          • セキュリティ診断サービス
          • 戦略的EC画面設計・制作サービス
          • Googleアナリティクスセミナー
          • アクセス解析コンサルティング
          • SEOコンサルティング

          Copyright © Appirits All Rights Reserved.