Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tensorflow/Keras(Python)で作ったモデルをC++で使う

OHNO
June 01, 2019

 Tensorflow/Keras(Python)で作ったモデルをC++で使う

OHNO

June 01, 2019
Tweet

More Decks by OHNO

Other Decks in Programming

Transcript

  1. from __future__ import division, print_function import os import re import

    matplotlib.pyplot as plt import numpy as np DATA_DIR = "./data" with open(os.path.join(DATA_DIR, "LD2011_2014.txt"), "r") as fld: data = [] cid = 250 for line_num, line in enumerate(fld): if line.startswith("¥"¥";"): continue if line_num % 100 == 0: print("{:d} lines read".format(line_num)) cols = [float(re.sub(",", ".", x)) for x in line.strip().split(";")[1:]] data.append(cols[cid]) NUM_ENTRIES = 1000 plt.plot(range(NUM_ENTRIES), data[0:NUM_ENTRIES]) plt.ylabel("electricity consumption") plt.xlabel("time (1pt = 15 mins)") plt.show() np.save(os.path.join(DATA_DIR, "LD_250.npy"), np.array(data)) データ準備のプログラム
  2. from __future__ import division, print_function import math import os import

    numpy as np from keras.layers import Dense, LSTM from keras.models import Sequential from sklearn.preprocessing import MinMaxScaler DATA_DIR = "./data" data = np.load(os.path.join(DATA_DIR, "LD_250.npy")) NUM_TIMESTEPS = 20 HIDDEN_SIZE = 10 BATCH_SIZE = 96 # 24 hours (15 min intervals) NUM_EPOCHS = 5 # scale the data to be in the range (0, 1) data = data.reshape(-1, 1) scaler = MinMaxScaler(feature_range=(0, 1), copy=False) data = scaler.fit_transform(data) # transform to 4 inputs -> 1 label format X = np.zeros((data.shape[0], NUM_TIMESTEPS)) Y = np.zeros((data.shape[0], 1)) for i in range(len(data) - NUM_TIMESTEPS - 1): X[i] = data[i:i + NUM_TIMESTEPS].T Y[i] = data[i + NUM_TIMESTEPS + 1] 予想値の算出プログラム1
  3. X = np.expand_dims(X, axis=2) sp = int(0.7 * len(data)) Xtrain,

    Xtest, Ytrain, Ytest = X[0:sp], X[sp:], Y[0:sp], Y[sp:] print(Xtrain.shape, Xtest.shape, Ytrain.shape, Ytest.shape) model = Sequential() model.add(LSTM(HIDDEN_SIZE, stateful=True,batch_input_shape=(BATCH_SIZE, NUM_TIMESTEPS, 1),return_sequences=False)) model.add(Dense(1)) model.compile(loss="mean_squared_error", optimizer="adam",metrics=["mean_squared_error"]) train_size = (Xtrain.shape[0] // BATCH_SIZE) * BATCH_SIZE test_size = (Xtest.shape[0] // BATCH_SIZE) * BATCH_SIZE Xtrain, Ytrain = Xtrain[0:train_size], Ytrain[0:train_size] Xtest, Ytest = Xtest[0:test_size], Ytest[0:test_size] print(Xtrain.shape, Xtest.shape, Ytrain.shape, Ytest.shape) for i in range(NUM_EPOCHS): print("Epoch {:d}/{:d}".format(i+1, NUM_EPOCHS)) model.fit(Xtrain, Ytrain, batch_size=BATCH_SIZE, epochs=1,validation_data=(Xtest, Ytest),shuffle=False) model.reset_states() score, _ = model.evaluate(Xtest, Ytest, batch_size=BATCH_SIZE) rmse = math.sqrt(score) print("¥nMSE: {:.3f}, RMSE: {:.3f}".format(score, rmse)) 予想値の算出プログラム2
  4. OpenCVを使う方法 ・OpenCV3.4.0のサンプルを使う C:¥opencv3¥sources¥samples¥dnn (Pythonのプログラムがあるものも) caffe googlenet faster_rcnn fcn_semsegm restnet_ssd_face squeezenet_halide

    ssd_mobilenet_object_detection ssd_object_detection tf_inception torch_enet yolo_object_detection → CPUプログラムなので毎秒3フレーム https://iwaki2009.blogspot.com/2017/10/opencv-dnn-inception-i-classified.html OpenCVのバージョンが異なる とサンプルプログラムも一部異 なる
  5. Ttensorflow for C を使う ・Googleのホームページからソースコードをダウンロードし 一からコンパイル(ただし時間がかかる) ・Cmake で Visual Studio

    用のプロジェクトを作成 ・サンプルプログラムあり 画像認識 音声認識 一般物体検出(複数のものを認識して領域を表示) アンドロイドでTensorflow https://iwaki2009.blogspot.com/2017/10/opencv-dnn-inception-i-classified.html
  6. 開発環境 ・OS : windows10(Ubuntu 16.04でも可) ・GPU : NVIDIA GeForce GTX

    1060 (無くてもOK) ・Anaconda3 (3.6.4) ・Tensorflow 1.12.0 ・Visual Studio 2105 ・仮想環境 conda create –n tf_test activate tf_test conda install tensorflow-gpu==1.12.0
  7. 仮想環境 ・Anacondaプロンプトを起動 仮想環境を作る conda create –n tf_test 仮想環境を削除 conda remove

    –n tf_test --all 仮想環境を起動 activate tf_test → プロンプトが変わる <tf_test> 通常時は<base> インストールする conda install tensorflow-gpu==1.12.0 一覧を見る conda list 仮想環境を抜ける deactivate tf_test 環境名 なんでもよい
  8. 実際の手順 ①KerasでMNISTを学習し、モデル作成して保存する モデルは *.h5 で保存する ②KerasのモデルをTensorflowのモデルに変換して保存 *.h5 → *.pb ③

    *.pb を読び出して画像を認識する(0~9)プログラム をCで作成する ・ソースコードとサンプル入力画像 https://github.com/iwatake2222/CNN_NumberDetector/tree/ master/03_Tensorflow_C
  9. Kerasで学習しモデルを保存 ・KerasでMNISTを学習し、モデルを作成して保存する [ConvMnist.pyの一部を抜粋] input = Input(shape=(28,28,1)) conv1 = Conv2D(filters=8,kernel_size=(3,3),strides=(1,1),padding='same', activation='relu')(input)

    pool1 = MaxPooling2D(pool_size=(2,2))(conv1) conv2 = Conv2D(filters=4,kernel_size=(3,3),strides=(1,1),padding='same', activation='relu')(pool1) dropout1 = Dropout(0.2)(conv2) flatten1 = Flatten()(dropout1) output = Dense(units=10, activation='softmax')(flatten1)
  10. Kerasで学習したモデルで認識 ・Kerasのモデルで数字の認識 [Number_detector.pyの一部を抜粋] import cv2 from ConvMnist import ConvMnist if

    __name__ == '__main__': conv_mnist = ConvMnist(filename='conv_mnist.h5') 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 result, score = conv_mnist.predict(img) print("predicted number is {} [{:.2f}]".format(result, score)) cv2.waitKey(0) cv2.destroyAllWindows()
  11. Cで認識 ・CでTensorflow用モデル(*.pb)を呼び出し認識 ・Tensorflow for C ライブラリの用意 ① ビルド済みのライブラリをダウンロードする https://www.tensorflow.org/install/lang_c ②

    自分でビルドする https://github.com/tensorflow/tensorflow/blob/master/tensorflow/ tools/lib_package/README.md 拡張命令を使用できるが、時間がかかる I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2
  12. プロジェクトの構成 ├libtensorflow/ │ └libtensorflow-cpu-windows-x86_64-1.12.0/ │ ├include/tensorflow/c/c_api.h │ └lib/tensorflow.dll, tensorflow.lib ├build/

    Vsiual Studio 2015 のプロジェクトファイル ├resource/ │ ├0.jpg, 1.jpg, 2.jpg, 3.jpg, ・・・・ │ └conv_mnist.pb ├CMakeLists.txt ├main.cpp └tf_utils.cpp,h https://github.com/iwatake2222/ CNN_NumberDetector/tree/ master/03_Tensorflow_C https://storage.googleapis.com/tens orflow/libtensorflow/libtensorflow- cpu-windows-x86_64-1.12.0.zip
  13. 注意点 ・Tensorflow(Python)とTensorflow(C)のバージョンを 合わせる ・ Tensorflow(Python)のモデルの入出力名と Tensorflow(C)のモデル設定の入出力名を合わせる input_1 dense_1/Softmax Layer (type)

    Output Shape Param # ================================================================= input_1 (InputLayer) (None, 28, 28, 1) 0 _________________________________________________________________ conv2d_1 (Conv2D) (None, 28, 28, 8) 80 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 14, 14, 8) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 14, 14, 4) 292 _________________________________________________________________ dropout_1 (Dropout) (None, 14, 14, 4) 0 _________________________________________________________________ flatten_1 (Flatten) (None, 784) 0 _________________________________________________________________ dense_1 (Dense) (None, 10) 7850 =================================================================
  14. 県内企業の状況 ・福田道路(NEC) 道路診断 ・パナソニック LED電灯の外観検査 ・システムスクエア X線検査装置 ・オーエム製作所 切り粉の判別 ・山口製作所

    部品のピッキングシステム ・カワイ精工 チャットボット ・メビウス 錦鯉の識別 ・アイビーシステム 館内行動予測