Movidius NCSでTensorFlowモデルを実行する


Pocket

MovidiusNCSのSDKバージョン1.09からTensorFlowがサポートされました。
https://ncsforum.movidius.com/discussion/304/tensorflow-support-for-ncs

今回はTensorFlowモデル(ckpt)をNCSで実行してみたいと思います。
※基本的にはexamples/tensorflow/inception_v3の内容です

なお、自前の学習済みモデルを使用する場合は、”2.TensorFlow→NCS用モデルに変換”からで大丈夫です。

環境

【デスクトップPC】
・Ubuntu 16.04
・TensorFlow v1.3
・MovidiusNCS SDK 1.09

【Raspberry Pi3】
・Rasbian stretch
・MovidiusNCS SDK 1.09

環境構築は、
Movidius NCS環境構築,
Movidius NCS環境構築(RasPi3編)参照下さい。
 

1.TensorFlowモデルの用意

TensorFlowのモデルをNCS用モデルに変換するまでは、デスクトップPCで作業します。
今回はInception-v3モデルを使います。学習済みモデルはtensorflow/modelsで公開されているのでそれを使います。
詳細はhttps://github.com/tensorflow/models/tree/master/research/slim#pre-trained-models

$ wget http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz
$ tar xvf inception_v3_2016_08_28.tar.gz

inception_v3.ckptファイルが解凍されます。
ただ、inception_v3.ckptファイルはネットワークの重み情報しか含まれて以内(あと、形式が古い)ため、一旦ネットワークをレストアして、再度保存し直します。この一連の作業を行うスクリプトが、SDKインストール時にgit cloneしたリポジトリのexamples/tensorflow/inception_v3/inception-v3.pyにあるので、それを使いました。

$ cp /examples/tensorflow/inception_v3/inception-v3.py .
$ python inception-v3.py

スクリプトを実行すると、outputフォルダにいつもの(TensorFlow v1.0?以降の)ckpt一式が保存されていることが確認出来ると思います。
 

2.TensorFlow→NCS用モデルに変換

TensorFlowのckptファイルをNCS用モデルに変換します。
変換は、mvNCCompile,mvNCCheck,mvNCProfileどれを使ってもできます。
mvNCCompileは変換のみで、mvNCCheckは変換と検証、mvNCProfileは変換と実行時間確認を行うことができます。基本的には、mvNCCheckを使っておけばいいような気がしてますが…どうなんだろう
※mvNCCheck,mvNCProfileを使用する場合は、NCSがUSBポートに刺さってないといけません。

$ mvNCCheck output/inception-v3.meta -in=input -on=InceptionV3/Predictions/Reshape_1 -s 12 -o inception_v3.graph
又は、
$ mvNCCompile output/inception-v3.meta -in=input -on=InceptionV3/Predictions/Reshape_1 -s 12 -o inception_v3.graph
又は、
$ mvNCProfile output/inception-v3.meta -in=input -on=InceptionV3/Predictions/Reshape_1 -s 12 -o inception_v3.graph

オプションは、”-in”がインプットノード名、”-on”がアウトプットノード名、”-s”が最大SHAVE数、”-o”が出力ファイル名です。詳しくは“http://workpiles.com/2017/10/movidius-ncs-setup/”参照。

だだし、現状ではmvNCCheck,mvNCProfileの-oオプションが上手く動かないため、別名保存したい場合は、mvNCCompileを使うはめに…そのうち修正される?

これで変換完了です。変換後のファイルサイズは52MBでした。
なお、mvNCCheckを使用した場合は、下記のような検証結果も表示されます。

 

3.ラズパイへコピー

作成したNCS用モデル(inception_v3.graph)をラズパイへコピーします。
 

4.ラズパイで実行

最後にラズパイで実行する方法です。NCS APIを使ってモデルを実行します。APIはC++とPythonで用意されているので、お好きな方を。今回はPython APIを使用した例を示します。

#-*- coding:utf-8 -*-
import mvnc.mvncapi as ncs
import numpy as np
import cv2
import sys

def run(input_image):
    #接続されているNCSデバイスを取得
    ncs_names = ncs.EnumerateDevices()
    if (len(ncs_names) < 1):
        print("Error - no NCS devices detected.")
        quit()
    dev = ncs.Device(ncs_names[0])

    #デバイス初期化
    dev.OpenDevice()

    #学習済みモデル読み込み
    #APIドキュメントでは引数はファイルパスとなっていたが、読み込めなかった。自前でopenしたらできた
    with open('inception_v3.graph', 'rb') as f:
        graph = dev.AllocateGraph(f.read())

    #推論の実行
    if (graph.LoadTensor(input_image.astype(np.float16), 'user object')):
        output, userobj = graph.GetResult()
        print(userobj)
        print(np.argmax(output))
        print(output)

    #デバイスクローズ
    graph.DeallocateGraph()
    dev.CloseDevice()

if __name__=="__main__":
    args = sys.argv
    if len(args) != 2:
        print('Usage: python %s filename'%(args[0]))
        quit()

    image = cv2.imread(args[1])
    image = cv2.resize(image, (299, 299))
    image = np.array(image)/255.0
    run(image)

実行結果

入力:

出力:

Label:286 → Persian cat 正解!

速度

デバイスの初期化〜モデル読み込み:2.4秒
推論実行:0.4秒
 

追記(2017/10/19)速度比較

デスクトップPCとラズパイ

Y軸の単位書き忘れましたが、[sec]です。
Core i5 3.2GHzの環境では、NCS使わない方が速度がでました。
ラズパイ3では、NCS使った方が断然速いですね。
 

SHAVE数の比較

有効にするSHAVE数による推論速度の比較です。
デスクトップPC+NCSで実行しています。

増やす毎に早くなりますが、S8とS12では200ms程の速度アップに留まりました。

今回はここまで。TensorFlowで学習させたモデルをNCSで実行することができました。
では〜。
 

Leave a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です