TensorFlow Model Zooにある学習済みモデルをMovidiusで動かす( Inception-V3とMobileNet V1)
方法
ここに書いてある。 https://movidius.github.io/ncsdk/tf_modelzoo.html
ソースを落としてくる。
git clone https://github.com/tensorflow/tensorflow.git git clone https://github.com/tensorflow/models.git
学習済みのチェックポイントを落としてくる。
wget -nc http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz tar -xvf inception_v3_2016_08_28.tar.gz
GraphDefファイルを出力。
python3 ../models/research/slim/export_inference_graph.py \ --alsologtostderr \ --model_name=inception_v3 \ --batch_size=1 \ --dataset_name=imagenet \ --image_size=299 \ --output_file=inception_v3.pb
グラフのフリーズ。
python3 ../tensorflow/tensorflow/python/tools/freeze_graph.py \ --input_graph=inception_v3.pb \ --input_binary=true \ --input_checkpoint=inception_v3.ckpt \ --output_graph=inception_v3_frozen.pb \ --output_node_name=InceptionV3/Predictions/Reshape_1
mvNCCompile -s 12 inception_v3_frozen.pb -in=input -on=InceptionV3/Predictions/Reshape_1
やってみる
フリーズの工程にて
tokunn@tokunn-VirtualBox 16:13:16 [~/Documents/MovidiusTensorflow/use_modelzoo/inceptionV3] $ python3 ~/Documents/source/tensorflow/tensorflow/python/tools/freeze_graph.py \ > --input_graph=inception_v3.pb \ --input_binary=true \ --input_checkpoint=inception_v3.ckpt \ --output_graph=inception_v3_frozen.pb \ --output_node_name=InceptionV3/Predictions/Reshape_1 Traceback (most recent call last): File "/home/tokunn/Documents/source/tensorflow/tensorflow/python/tools/freeze_graph.py", line 58, in <module> from tensorflow.python.training import checkpoint_management ImportError: cannot import name 'checkpoint_management'
動かない。
バグらしい。 https://github.com/tensorflow/tensorflow/issues/22019
いつも通りパッチを当てる。
58d57 < from tensorflow.python.training import checkpoint_management 59a59 > import tensorflow as tf 127c127 < not checkpoint_management.checkpoint_exists(input_checkpoint)): --- > not tf.train.checkpoint_exists(input_checkpoint)):
無事にfrozenなのが出力された。
mvNCCheckで
tokunn@nanase 7:41:25 [~] $ mvNCCheck -s 12 inception_v3_frozen.pb -in=input -on=InceptionV3/Predictions/Reshape_1 2>/dev/null mvNCCheck v02.00, Copyright @ Movidius Ltd 2016 Result: (1, 1, 1001) 1) 22 0.1576 2) 93 0.1223 3) 95 0.0448 4) 23 0.03558 5) 24 0.02771 Expected: (1, 1001) 1) 22 0.1599765 2) 93 0.12189513 3) 95 0.04604088 4) 23 0.03503471 5) 24 0.02783106 ------------------------------------------------------------ Obtained values ------------------------------------------------------------ Obtained Min Pixel Accuracy: 1.4900462701916695% (max allowed=2%), Pass Obtained Average Pixel Accuracy: 0.01522512175142765% (max allowed=1%), Pass Obtained Percentage of wrong values: 0.0% (max allowed=0%), Pass Obtained Pixel-wise L2 error: 0.06495287965302322% (max allowed=1%), Pass Obtained Global Sum Difference: 0.02438097447156906 ------------------------------------------------------------
問題なく動作した。
ほかのネットワークもやってみる (Mobilent V1)
ネットワークのリスト https://github.com/tensorflow/models/tree/master/research/slim/nets
重みのリスト https://github.com/tensorflow/models/tree/master/research/slim
モデルの準備
ネットワーク名はmobilenet_v1
重みは http://download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_0.5_160.tgz
なんか重みをダウンロードしたらmobilenet_v1_0.5_160_frozen.pb
も入ってた。
あとはコンパイルするだけ。
インプット/アウトプットノードの捜索
.pbファイルからノードを探す。
コードは添付。
結果
tokunn@tokunn-VirtualBox 17:02:17 [~/Documents/MovidiusTensorflow/use_modelzoo/mobilenet_v1/getnodename_pb.py] $ python3 getnodename_pb.py | grep input input , Placeholder tokunn@tokunn-VirtualBox 17:03:10 [~/Documents/MovidiusTensorflow/use_modelzoo/mobilenet_v1/getnodename_pb.py] $ python3 getnodename_pb.py | grep Predictions MobilenetV1/Predictions/Reshape_1 , Reshape
おそらくこのinput
とMobilenetV1/Predictions/Reshape_1
であろう。
コンパイル
ここまでは素直に来たのでコンパイル。
mvNCCompile -s 12 mobilenet_v1_0.5_160_frozen.pb -in=input -on=MobilenetV1/Predictions/Reshape_1
やっぱり終わらないエラーとの闘い。
tokunn@tokunn-VirtualBox 17:10:23 [~/Documents/MovidiusTensorflow/use_modelzoo/mobilenet_v1] $ mvNCCompile -s 12 mobilenet_v1_0.5_160_frozen.pb -in=input -on=MobilenetV1/Predictions/Reshape_1 mvNCCompile v02.00, Copyright @ Movidius Ltd 2016 /home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/framework/ops.py:923: DeprecationWarning: builtin type EagerTensor has no __module__ attribute EagerTensor = c_api.TFE_Py_InitEagerTensor(_EagerTensorBase) /home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/util/tf_inspect.py:75: DeprecationWarning: inspect.getargspec() is deprecated, use inspect.signature() instead return _inspect.getargspec(target) 1 Traceback (most recent call last): File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1278, in _do_call return fn(*args) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1263, in _run_fn options, feed_dict, fetch_list, target_list, run_metadata) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1350, in _call_tf_sessionrun run_metadata) tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'input' with dtype float and shape [?,160,160,3] [[Node: input = Placeholder[dtype=DT_FLOAT, shape=[?,160,160,3], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]] During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/local/bin/mvNCCompile", line 118, in <module> create_graph(args.network, args.inputnode, args.outputnode, args.outfile, args.nshaves, args.inputsize, args.weights) File "/usr/local/bin/mvNCCompile", line 104, in create_graph net = parse_tensor(args, myriad_config) File "/usr/local/bin/ncsdk/Controllers/TensorFlowParser.py", line 1061, in parse_tensor desired_shape = node.inputs[1].eval() File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 680, in eval return _eval_using_default_session(self, feed_dict, self.graph, session) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 4951, in _eval_using_default_session return session.run(tensors, feed_dict) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 877, in run run_metadata_ptr) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1100, in _run feed_dict_tensor, options, run_metadata) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1272, in _do_run run_metadata) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1291, in _do_call raise type(e)(node_def, op, message) tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'input' with dtype float and shape [?,160,160,3] [[Node: input = Placeholder[dtype=DT_FLOAT, shape=[?,160,160,3], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]] Caused by op 'input', defined at: File "/usr/local/bin/mvNCCompile", line 118, in <module> create_graph(args.network, args.inputnode, args.outputnode, args.outfile, args.nshaves, args.inputsize, args.weights) File "/usr/local/bin/mvNCCompile", line 104, in create_graph net = parse_tensor(args, myriad_config) File "/usr/local/bin/ncsdk/Controllers/TensorFlowParser.py", line 211, in parse_tensor tf.import_graph_def(graph_def, name="") File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/util/deprecation.py", line 454, in new_func return func(*args, **kwargs) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/framework/importer.py", line 442, in import_graph_def _ProcessNewOps(graph) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/framework/importer.py", line 234, in _ProcessNewOps for new_op in graph._add_new_tf_operations(compute_devices=False): # pylint: disable=protected-access File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 3289, in _add_new_tf_operations for c_op in c_api_util.new_tf_operations(self) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 3289, in <listcomp> for c_op in c_api_util.new_tf_operations(self) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 3180, in _create_op_from_tf_operation ret = Operation(c_op, self) File "/home/tokunn/.local/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 1717, in __init__ self._traceback = tf_stack.extract_stack() InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'input' with dtype float and shape [?,160,160,3] [[Node: input = Placeholder[dtype=DT_FLOAT, shape=[?,160,160,3], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]
どうやら入力のプレースホルダに何も与えられていない模様?
それは私のせいではないのではないだろうか?
I just got exactly the same problem. Hope someone can help
かなしい
https://github.com/ardamavi/Intel-Movidius-NCS-Keras/issues/2
The project is still in construction. Stay tuned!
This project is open source. If you share your patch, let's try to fix it together.
かなしい
I have come across similar problem, solved by modifying ncsdk source. In /usr/local/bin/ncsdk/Controllers/TensorFlowParser.py line 1059, add a feed_dict to eval:
いつも通り/usr/local/bin/ncsdk/Controllers/TensorFlowParser.py
が悪さをしている説。
1061c1061 < desired_shape = node.inputs[1].eval() --- > desired_shape = node.inputs[1].eval(feed_dict={inputnode + ':0' : input_data})
今日も元気にパッチを当ててみる。
tokunn@tokunn-VirtualBox 17:25:33 [~/Documents/MovidiusTensorflow/use_modelzoo/mobilenet_v1] $ mvNCCompile -s 12 mobilenet_v1_0.5_160_frozen.pb -in=input -on=MobilenetV1/Predictions/Reshape_1 2>/dev/null mvNCCompile v02.00, Copyright @ Movidius Ltd 2016 1
無事に通った?
なんか出力が少なすぎる。
Check !
tokunn@nanase 8:32:09 [~] $ mvNCCheck -s 12 mobilenet_v1_0.5_160_frozen.pb -in=input -on=MobilenetV1/Predictions/Reshape_1 2>/dev/null mvNCCheck v02.00, Copyright @ Movidius Ltd 2016 /usr/local/bin/ncsdk/Controllers/TensorFlowParser.py line no.290 USB: Transferring Data... USB: Myriad Execution Finished USB: Myriad Connection Closing. USB: Myriad Connection Closed. Result: (1, 1, 1001) 1) 447 0.03534 2) 534 0.02742 3) 825 0.02272 4) 701 0.02151 5) 736 0.02039 Expected: (1, 1001) 1) 447 0.035791013 2) 534 0.027337724 3) 825 0.02282799 4) 701 0.021315519 5) 736 0.020063626 ------------------------------------------------------------ Obtained values ------------------------------------------------------------ Obtained Min Pixel Accuracy: 2.3404913023114204% (max allowed=2%), Fail Obtained Average Pixel Accuracy: 0.06249707657843828% (max allowed=1%), Pass Obtained Percentage of wrong values: 0.0999000999000999% (max allowed=0%), Fail Obtained Pixel-wise L2 error: 0.14634640928212883% (max allowed=1%), Pass Obtained Global Sum Difference: 0.022390704602003098 ------------------------------------------------------------
なんか2%以上ずれてるけど、まぁ正しく動いてるっぽい。
動かしてみる
実際に画像を入力して動かしてみる。
tokunn@nanase 10:41:39 [~/mobilenet] $ python3 pr_mvd_mblnet.py flower ERROR 1: libgrass_vector.7.4.0.so: cannot open shared object file: No such file or directory ERROR 1: libgrass_vector.7.4.0.so: cannot open shared object file: No such file or directory ERROR 1: libgrass_dgl.7.4.0.so: cannot open shared object file: No such file or directory ERROR 1: libgrass_dgl.7.4.0.so: cannot open shared object file: No such file or directory Image path : flower/*.jpg imgshape (508, 75, 75) Start prediting ... 534 534 534 534 534 534 534 534 534 534 534 534 540 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 825 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 540 534 534 534 540 534 742 534 869 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 534 534 751 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 869 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 869 534 534 534 534 534 534 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 869 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 534 534 534 534 534 534 540 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 869 534 534 534 534 534 540 534 534 534 534 534 534 534 540 534 534 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 534 540 534 534 534 540 534 534 534 534 534 534 534 534 534 540 534 534 534 534 534 869 534 534 534 534 534 540 534 534 534 534 534 534 534 534 534 534 534 Time : 7.718486547470093 (508 images)
無事に動いた。
結論
Model ZooにあるデータならMovodiusで使える。
ソースコード
.pbからノードを列挙するコード
#!/usr/bin/env python3 import tensorflow as tf from tensorflow.python.platform import gfile filename = '../mobilenet_v1_0.5_160_frozen.pb' node_ops = [] with tf.gfile.GFile(filename, "rb") as f: graph_def = tf.GraphDef() graph_def.ParseFromString(f.read()) for node in graph_def.node: print(str(node.name) + " , " + str(node.op))
Keras から .pbを出すコード
https://stackoverflow.com/questions/45466020/how-to-export-keras-h5-to-tensorflow-pb
def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True): """ Freezes the state of a session into a pruned computation graph. Creates a new computation graph where variable nodes are replaced by constants taking their current value in the session. The new graph will be pruned so subgraphs that are not necessary to compute the requested outputs are removed. @param session The TensorFlow session to be frozen. @param keep_var_names A list of variable names that should not be frozen, or None to freeze all the variables in the graph. @param output_names Names of the relevant graph outputs. @param clear_devices Remove the device directives from the graph for better portability. @return The frozen graph definition. """ from tensorflow.python.framework.graph_util import convert_variables_to_constants graph = session.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(session, input_graph_def, output_names, freeze_var_names) return frozen_graph from keras import backend as K # Create, compile and train model... frozen_graph = freeze_session(K.get_session(), output_names=[out.op.name for out in model.outputs]) tf.train.write_graph(frozen_graph, "some_directory", "my_model.pb", as_text=False)