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で実行することができました。
では〜。