20190307のTensorFlowに関する記事は2件です。

色々な環境でDeep Learningアプリケーション開発 (2)

この記事について

機械学習、Deep Learningの専門家ではない人が、Deep Learningを応用したアプリケーションを作れるようになるのが目的です。特に、組み込み向けアプリケーションを意識しています。
モデルそのものには言及しません。Deep Learningモデルをどうやって使うか、ということに重点を置いています。数学的な話も出てきません。

  1. Kerasで簡単にMNIST数字識別モデルを作り、Pythonで確認
  2. TensorFlowモデルに変換してPythonで使用してみる (Windows, Linux)
  3. TensorFlowモデルに変換してCで使用してみる (Windows, Linux)
  4. TensorFlow Liteモデルに変換してPythonで使用してみる (Windows, Linux)
  5. TensorFlow Liteモデルに変換してCで使用してみる (Linux)
  6. TensorFlow Liteモデルに変換してPython/Cで使用してみる (Raspberry Pi)

今回の内容

  • 前回作成したKeras用モデル(.h5)をTensorFlow用モデル(.pb)に変換する
  • 変換したTensorFlow用モデルを使って、入力画像から数字識別するアプリケーションを作る

ソースコードとサンプル入力画像: https://github.com/take-iwiw/CNN_NumberDetector/tree/master/02_Tensorflow_Python

なぜ必要? 想定するシナリオ

  • TensorFlow用モデルしかないとき
    • 社内の機械学習エンジニア様、データサイエンティスト様がTensorFlowでモデルを作成したら、それに対応したアプリケーションを作る必要があります (後述するように変換はできますが)
  • 今一番勢いがある?
    • ONNXやMMdnnを使用したら、異なるDeepLearning用フレームワーク間でのモデル変換が出来ます
    • TensorFlowに対応したアプリケーションの作り方を覚えておけば、大抵のことには対応できると思います
  • 動作環境にPython, Kerasがないとき
    • C言語用APIが用意されているので、ライブラリと一緒に配布すれば実行先での環境構築は不要です
      • お客様にPythonやAnacondaをインストールしてもらうわけにはいきません!
      • 今回はPythonで試しますが、C言語での実装の前段階ととらえてください

環境

  • OS: Windows 10 (64-bt)
  • OS(on VirtualBox): Ubuntu 16.04
  • CPU = Intel Core i7-6700@3.4GHz (物理コア=4、論理プロセッサ数=8)
  • GPU = NVIDIA GeForce GTX 1070 (← GPUは無くても大丈夫です)
  • 開発環境: Anaconda3 64-bit (Python3.6.8)

今回の内容は、WindowsとLinux(Ubuntu)のどちらでも動きますが、本記事の説明はWindowsメインで行います。

Keras用モデル(.h5)をTensorFlow用モデル(*.pb)に変換する

https://medium.com/@pipidog/how-to-convert-your-keras-models-to-tensorflow-e471400b886a のサイトを参考にさせていただき、変換用スクリプトを作りました。現在、FastGFileは非推奨とのことなので、tensorflow.gfile.GFileに置き換えています。
convert_keras_to_tensorflow 関数を呼ぶことで、Keras用モデル(.h5)をTensorFlow用モデル(*.pb)に変換できます。また、get_model_info 関数を呼ぶことで、変換したTensorFlow用モデルの情報をJSONファイルに保存します。
このスクリプトをそのまま実行すると、前回作成したKeras用モデル(conv_mnist.h5)を、TensorFlow用モデル(conv_mnist.pb)に変換してくれます。

keras_to_tensorflow.py
# -*- coding: utf-8 -*-
# Reference URL: https://medium.com/@pipidog/how-to-convert-your-keras-models-to-tensorflow-e471400b886a

import tensorflow as tf
from tensorflow.python.keras.models import load_model
from tensorflow.python.keras import backend as K
from tensorflow.python.framework.graph_util import convert_variables_to_constants
import numpy as np
import json

def freeze_session(sess, keep_var_names=None, output_names=None, clear_devices=True):
    graph = sess.graph
    with graph.as_default():
        freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
        output_names = output_names or []
        output_names += [v.op.name for v in tf.global_variables()]
        input_graph_def = graph.as_graph_def()
        if clear_devices:
            for node in input_graph_def.node:
                node.device = ''
        frozen_graph = convert_variables_to_constants(sess, input_graph_def, output_names, freeze_var_names)
        return frozen_graph

def convert_keras_to_tensorflow(keras_model_filename, tf_model_filename):
    model = load_model(keras_model_filename)
    model.summary()
    frozen_graph = freeze_session(K.get_session(), output_names=[out.op.name for out in model.outputs])
    tf.train.write_graph(frozen_graph, './', tf_model_filename, as_text=False)


def get_model_info(tf_model_filename):
    ops = {}
    with tf.Session() as sess:
        with tf.gfile.GFile(tf_model_filename, 'rb') as f:
            graph_def = tf.GraphDef()
            graph_def.ParseFromString(f.read())
            sess.graph.as_default()
            _ = tf.import_graph_def(graph_def)
            for op in tf.get_default_graph().get_operations():
                ops[op.name] = [str(output) for output in op.outputs]
        writer = tf.summary.FileWriter('./logs')
        writer.add_graph(sess.graph)
        writer.flush()
        writer.close()

    with open(tf_model_filename+'_param.json', 'w') as f:
        f.write(json.dumps(ops))


if __name__ == '__main__':
    # convert
    keras_model_filename = 'conv_mnist.h5'
    tf_model_filename = 'conv_mnist.pb'
    convert_keras_to_tensorflow(keras_model_filename, tf_model_filename)
    get_model_info(tf_model_filename)

モデル情報を確認する

上記スクリプトを実行すると、TensorFlow用モデル(conv_mnist.pb)と共に、モデル情報を記した(conv_mnist.pb_param.json)も出力されます。
このモデル情報は非常に重要です。変換したモデルを使用する際に入出力の名前が必要になります。

前回モデル作成時に、入力にはInputを使い、出力は全結合をするDenseを使いsoftmaxを取るようにしました。また、グラフ名はデフォルトではimportになるようです。このような情報をヒントに入出力のTensorを探します。
今回は以下であることが分かります:

  • 入力: import/input_1:0
  • 出力: import/dense_1/Softmax:0
conv_mnist.pb_param.json
{
    "import/input_1": [
        "Tensor(\"import/input_1:0\", shape=(?, 28, 28, 1), dtype=float32)"
    ],
    "import/conv2d_1/kernel": [
        "Tensor(\"import/conv2d_1/kernel:0\", shape=(3, 3, 1, 8), dtype=float32)"
    ],
~略~
    "import/dense_1/Softmax": [
        "Tensor(\"import/dense_1/Softmax:0\", shape=(?, 10), dtype=float32)"
    ],
~略~
    "import_2/training_1/Adam/Variable_11": [
        "Tensor(\"import_2/training_1/Adam/Variable_11:0\", shape=(10,), dtype=float32)"
    ]
}

変換したTensorFlow用モデルを使って、入力画像から数字識別するアプリケーションを作る

Spyder上でnumber_detector_tensorflow.pyというファイルを開き、以下のようなコードを実装します。
動作仕様は前回Keras用に作成したnumber_detector.py と同じです。TensorFlow呼び出しもこの中でやっているので、少し複雑になっています。
get_tensor_by_nameに先ほど確認した入出力名を設定して、入出力Tensorを取得しています。

number_detector_tensorflow.py
# -*- coding: utf-8 -*-
import cv2
import tensorflow as tf
import numpy as np

if __name__ == '__main__':
    img = cv2.imread('resource/4.jpg')
    cv2.imshow('image', img)

    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img = cv2.resize(img, (28, 28))
    img = 255 - img
    img = img.reshape(1, img.shape[0], img.shape[1], 1)
    img = img / 255.

    with tf.Session() as sess:
        with tf.gfile.GFile('conv_mnist.pb', 'rb') as f:
            graph_def = tf.GraphDef()
            graph_def.ParseFromString(f.read())
            sess.graph.as_default()
            _ = tf.import_graph_def(graph_def)
            tensor_input = sess.graph.get_tensor_by_name('import/input_1:0')
            tensor_output = sess.graph.get_tensor_by_name('import/dense_1/Softmax:0')
            probs = sess.run(tensor_output, {tensor_input: img})

    result = np.argmax(probs[0])
    score = probs[0][result]

    print("predicted number is {} [{:.2f}]".format(result, score))

    cv2.waitKey(0)
    cv2.destroyAllWindows()

次回は、今回作成したTensorFlow用モデル(conv_mnist.pb)を、C言語から使用してみます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Deep Learningアプリケーション開発 (2) TensorFlow with Python

この記事について

機械学習、Deep Learningの専門家ではない人が、Deep Learningを応用したアプリケーションを作れるようになるのが目的です。特に、組み込み向けアプリケーションを意識しています。
モデルそのものには言及しません。数学的な話も出てきません。Deep Learningモデルをどうやって使うか(推論)、ということに重点を置いています。

  1. Kerasで簡単にMNIST数字識別モデルを作り、Pythonで確認
  2. TensorFlowモデルに変換してPythonで使用してみる (Windows, Linux)
  3. TensorFlowモデルに変換してCで使用してみる (Windows, Linux)
  4. TensorFlow Liteモデルに変換してPythonで使用してみる (Windows, Linux)
  5. TensorFlow Liteモデルに変換してCで使用してみる (Linux)
  6. TensorFlow Liteモデルに変換してPython/Cで使用してみる (Raspberry Pi)

今回の内容

  • 前回作成したKeras用モデル(.h5)をTensorFlow用モデル(.pb)に変換する
  • 変換したTensorFlow用モデルを使って、入力画像から数字識別するアプリケーションを作る

ソースコードとサンプル入力画像: https://github.com/take-iwiw/CNN_NumberDetector/tree/master/02_Tensorflow_Python

なぜ必要? 想定するシナリオ

  • TensorFlow用モデルしかないとき
    • 社内の機械学習エンジニア様、データサイエンティスト様がTensorFlowでモデルを作成したら、それに対応したアプリケーションを作る必要があります (後述するように変換はできますが)
  • 今一番勢いがある?
    • ONNXやMMdnnを使用したら、異なるDeepLearning用フレームワーク間でのモデル変換が出来ます
    • TensorFlowに対応したアプリケーションの作り方を覚えておけば、大抵のことには対応できると思います
  • 動作環境にPython, Kerasがないとき
    • C言語用APIが用意されているので、ライブラリと一緒に配布すれば実行先での環境構築は不要です
      • お客様にPythonやAnacondaをインストールしてもらうわけにはいきません!
      • 今回はPythonで試しますが、C言語での実装の前段階ととらえてください

環境

  • OS: Windows 10 (64-bt)
  • OS(on VirtualBox): Ubuntu 16.04
  • CPU = Intel Core i7-6700@3.4GHz (物理コア=4、論理プロセッサ数=8)
  • GPU = NVIDIA GeForce GTX 1070 (← GPUは無くても大丈夫です)
  • 開発環境: Anaconda3 64-bit (Python3.6.8)
  • TensorFlow 1.12.0
  • パッケージ詳細はこちら Windows用Linux用

今回の内容は、WindowsとLinux(Ubuntu)のどちらでも動きますが、本記事の説明はWindowsメインで行います。

Keras用モデル(.h5)をTensorFlow用モデル(*.pb)に変換する

https://medium.com/@pipidog/how-to-convert-your-keras-models-to-tensorflow-e471400b886a のサイトを参考にさせていただき、変換用スクリプトを作りました。現在、FastGFileは非推奨とのことなので、tensorflow.gfile.GFileに置き換えています。
convert_keras_to_tensorflow 関数を呼ぶことで、Keras用モデル(.h5)をTensorFlow用モデル(*.pb)に変換できます。また、get_model_info 関数を呼ぶことで、変換したTensorFlow用モデルの情報をJSONファイルに保存します。
このスクリプトをそのまま実行すると、前回作成したKeras用モデル(conv_mnist.h5)を、TensorFlow用モデル(conv_mnist.pb)に変換してくれます。

keras_to_tensorflow.py
# -*- coding: utf-8 -*-
# Reference URL: https://medium.com/@pipidog/how-to-convert-your-keras-models-to-tensorflow-e471400b886a

import tensorflow as tf
from tensorflow.python.keras.models import load_model
from tensorflow.python.keras import backend as K
from tensorflow.python.framework.graph_util import convert_variables_to_constants
import numpy as np
import json

def freeze_session(sess, keep_var_names=None, output_names=None, clear_devices=True):
    graph = sess.graph
    with graph.as_default():
        freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
        output_names = output_names or []
        output_names += [v.op.name for v in tf.global_variables()]
        input_graph_def = graph.as_graph_def()
        if clear_devices:
            for node in input_graph_def.node:
                node.device = ''
        frozen_graph = convert_variables_to_constants(sess, input_graph_def, output_names, freeze_var_names)
        return frozen_graph

def convert_keras_to_tensorflow(keras_model_filename, tf_model_filename):
    model = load_model(keras_model_filename)
    model.summary()
    frozen_graph = freeze_session(K.get_session(), output_names=[out.op.name for out in model.outputs])
    tf.train.write_graph(frozen_graph, './', tf_model_filename, as_text=False)


def get_model_info(tf_model_filename):
    ops = {}
    with tf.Session() as sess:
        with tf.gfile.GFile(tf_model_filename, 'rb') as f:
            graph_def = tf.GraphDef()
            graph_def.ParseFromString(f.read())
            sess.graph.as_default()
            _ = tf.import_graph_def(graph_def)
            for op in tf.get_default_graph().get_operations():
                ops[op.name] = [str(output) for output in op.outputs]
        writer = tf.summary.FileWriter('./logs')
        writer.add_graph(sess.graph)
        writer.flush()
        writer.close()

    with open(tf_model_filename+'_param.json', 'w') as f:
        f.write(json.dumps(ops))


if __name__ == '__main__':
    # convert
    keras_model_filename = 'conv_mnist.h5'
    tf_model_filename = 'conv_mnist.pb'
    convert_keras_to_tensorflow(keras_model_filename, tf_model_filename)
    get_model_info(tf_model_filename)

モデル情報を確認する

上記スクリプトを実行すると、TensorFlow用モデル(conv_mnist.pb)と共に、モデル情報を記した(conv_mnist.pb_param.json)も出力されます。
このモデル情報は非常に重要です。変換したモデルを使用する際に入出力の名前が必要になります。

前回モデル作成時に、入力にはInputを使い、出力は全結合をするDenseを使いsoftmaxを取るようにしました。また、グラフ名はデフォルトではimportになるようです。このような情報をヒントに入出力のTensorを探します。
今回は以下であることが分かります:

  • 入力: import/input_1:0
  • 出力: import/dense_1/Softmax:0
conv_mnist.pb_param.json
{
    "import/input_1": [
        "Tensor(\"import/input_1:0\", shape=(?, 28, 28, 1), dtype=float32)"
    ],
    "import/conv2d_1/kernel": [
        "Tensor(\"import/conv2d_1/kernel:0\", shape=(3, 3, 1, 8), dtype=float32)"
    ],
~略~
    "import/dense_1/Softmax": [
        "Tensor(\"import/dense_1/Softmax:0\", shape=(?, 10), dtype=float32)"
    ],
~略~
    "import_2/training_1/Adam/Variable_11": [
        "Tensor(\"import_2/training_1/Adam/Variable_11:0\", shape=(10,), dtype=float32)"
    ]
}

変換したTensorFlow用モデルを使って、入力画像から数字識別するアプリケーションを作る

Spyder上でnumber_detector_tensorflow.pyというファイルを開き、以下のようなコードを実装します。
動作仕様は前回Keras用に作成したnumber_detector.py と同じです。TensorFlow呼び出しもこの中でやっているので、少し複雑になっています。
get_tensor_by_nameに先ほど確認した入出力名を設定して、入出力Tensorを取得しています。

number_detector_tensorflow.py
# -*- coding: utf-8 -*-
import cv2
import tensorflow as tf
import numpy as np

if __name__ == '__main__':
    img = cv2.imread('resource/4.jpg')
    cv2.imshow('image', img)

    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img = cv2.resize(img, (28, 28))
    img = 255 - img
    img = img.reshape(1, img.shape[0], img.shape[1], 1)
    img = img / 255.

    with tf.Session() as sess:
        with tf.gfile.GFile('conv_mnist.pb', 'rb') as f:
            graph_def = tf.GraphDef()
            graph_def.ParseFromString(f.read())
            sess.graph.as_default()
            _ = tf.import_graph_def(graph_def)
            tensor_input = sess.graph.get_tensor_by_name('import/input_1:0')
            tensor_output = sess.graph.get_tensor_by_name('import/dense_1/Softmax:0')
            probs = sess.run(tensor_output, {tensor_input: img})

    result = np.argmax(probs[0])
    score = probs[0][result]

    print("predicted number is {} [{:.2f}]".format(result, score))

    cv2.waitKey(0)
    cv2.destroyAllWindows()

次回は、今回作成したTensorFlow用モデル(conv_mnist.pb)を、C言語から使用してみます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む