$30 off During Our Annual Pro Sale. View Details »

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. Tensorflowで異常検知
    (Tensorflowで学習したモデルをCで実行)
    大野 宏

    View Slide

  2. ・Tensorflowで異常検知
    RNNで値を予測し実測値と大幅に違う時を異常値とする
    ・Tensorflowで学習したモデルをCで実行
    ① KerasでMNIST(手書き数字)を学習させたモデルを
    ② Tensorflow形式に変換
    ③ Cで認識を実行
    ・県内企業の取り組み
    発表内容

    View Slide

  3. ・例えばドリルを使った加工機の異常を調べる
    ① 振動を周波数に変換(FFT)し、正常時と違う周波数
    パターンが発生した時を異常とする
    ② 正常時の振動を多数測定しておき値を予測
    実測値と予測値を比較し、大幅に違う時を異常とする
    ・例題は電力消費量からRNNで値を予測し、実測値と比較
    して大幅に違う時を異常とする
    [出典]直感Deep Learning Python×Kerasでアイデアを形にするレシピ
    (オライリージャパン)
    異常検知の方法

    View Slide

  4. 再帰型ニューラルネットワーク
    ・中間層で自分自身に再帰する経路を持つ
    ・入力層→中間層→出力層の経路は通常の
    ニューラルネットワークと同じ
    入力層 中間層 出力層
    (Recurrent Neural Networks)

    View Slide

  5. ・電力消費量
    https://archives.ics.uci.edu/ml/machine-learning-databases/
    000321/LD2011_2014.txt.zip
    データの準備

    View Slide

  6. 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))
    データ準備のプログラム

    View Slide

  7. 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

    View Slide

  8. 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

    View Slide

  9. ・予想値と実測値が大きく異なる時を異常と判定
    異常値の検出
    実測値
    予測値

    View Slide

  10. ・予想値と実測値の差分を求め、閾値を超えると異常
    異常値の検出
    閾値
    差分

    View Slide

  11. 時系列データの予測(回帰)
    ・過去の気温と電力量を学習し、気温から電力量を予測
    https://qiita.com/mix_dvd/items/ecfa6f0038e39cdce57e
    日時
    実際の電力量 予想電力量

    View Slide

  12. なぜTensorflowのモデルをCで認識
    ・処理速度が速い?
    C++でも学習可能
    ・製造ラインにカメラを設置して使う場合、メーカの提供する
    開発環境がC++(C#)なので親和性が良い
    ・並列処理も容易
    画像を取得しながら認識

    View Slide

  13. キューピーの不良品検出
    ・キューピー(株)が(株)ブレインパッドと共同開発
    ダイスポテトの不良品を検出してエアで排出
    https://tech.nikkeibp.co.jp/atcl/nxt/mag/nc/18/051600049/051600001/

    View Slide

  14. CでTensorflowモデルを認識する方法
    ① OpenCV(画像処理ライブラリ)のサンプルを使う
    ② Tensorflow for C のソースコードをダウンロードし、
    一からコンパイルして使う
    不必要なプログラムを削ぎ落す
    ③ Tensorflow を C で使えるAPIの利用

    View Slide

  15. 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のバージョンが異なる
    とサンプルプログラムも一部異
    なる

    View Slide

  16. tf_inception
    ・学習済のモデルinceptionを利用
    Googleが開発したinceptionモジュールを使ったモデル
    2014年の画像認識コンペで優勝

    View Slide

  17. Ttensorflow for C を使う
    ・Googleのホームページからソースコードをダウンロードし
    一からコンパイル(ただし時間がかかる)
    ・Cmake で Visual Studio 用のプロジェクトを作成
    ・サンプルプログラムあり
    画像認識
    音声認識
    一般物体検出(複数のものを認識して領域を表示)
    アンドロイドでTensorflow
    https://iwaki2009.blogspot.com/2017/10/opencv-dnn-inception-i-classified.html

    View Slide

  18. ①KerasでMNIST認識モデルを作りPythonで使用
    ②Tensorflowモデルに変換してPythonで使用(Windows,Linux)
    ③Tensorflowモデルに変換してCで使用(Windows,Linux)
    ④Tensorflow Liteモデルに変換してPythonで使用(Windows,Linux)
    ⑤Tensorflow Liteモデルに変換してCで使用(Linux)
    ⑥Tensorflow Liteモデルに変換してC++で使用(Raspberry Pi)
    「DeepLearningアプリケーション開発」で検索
    https://qiita.com/take-iwiw/items/796ec8560563625ace34
    C の API の利用

    View Slide

  19. 開発環境
    ・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

    View Slide

  20. 仮想環境
    ・Anacondaプロンプトを起動
    仮想環境を作る conda create –n tf_test
    仮想環境を削除 conda remove –n tf_test --all
    仮想環境を起動 activate tf_test
    → プロンプトが変わる 通常時は
    インストールする conda install tensorflow-gpu==1.12.0
    一覧を見る conda list
    仮想環境を抜ける deactivate tf_test
    環境名 なんでもよい

    View Slide

  21. 実際の手順
    ①KerasでMNISTを学習し、モデル作成して保存する
    モデルは *.h5 で保存する
    ②KerasのモデルをTensorflowのモデルに変換して保存
    *.h5 → *.pb
    ③ *.pb を読び出して画像を認識する(0~9)プログラム
    をCで作成する
    ・ソースコードとサンプル入力画像
    https://github.com/iwatake2222/CNN_NumberDetector/tree/
    master/03_Tensorflow_C

    View Slide

  22. 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)

    View Slide

  23. 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()

    View Slide

  24. Tensorflow形式に変換
    ・Keras用モデル(*.h5)をTensorflow用モデル(*.pb)に変換
    ・Tensorflow用モデル(*.pb)で数字の認識
    ・より簡単な方法で、*.h5 → *.pb

    View Slide

  25. 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

    View Slide

  26. プロジェクトの構成
    ├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

    View Slide

  27. CMakeでプロジェクトの作成

    View Slide

  28. 注意点
    ・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
    =================================================================

    View Slide

  29. 実行速度の比較
    ・③のAPIを使う方法は、Tensorflow(Python版)と、認識
    の実行速度は変わらない
    ・初期設定やPRINT文による表示はCの方が高速
    ・②のソースからコンパイルする方法が少し速くなる?
    ・ Tensorflow(Python版)のGPUの有無で実行速度を比較
    すると、ネットワークモデルが軽量な場合はGPU無(CPU
    だけ)の方が速い
    ・ Tensorflow(C版) でのGPU有では試していない

    View Slide

  30. 県内企業の状況
    ・福田道路(NEC) 道路診断
    ・パナソニック LED電灯の外観検査
    ・システムスクエア X線検査装置
    ・オーエム製作所 切り粉の判別
    ・山口製作所 部品のピッキングシステム
    ・カワイ精工 チャットボット
    ・メビウス 錦鯉の識別
    ・アイビーシステム 館内行動予測

    View Slide