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ファイルからノードを探す。

https://ncsforum.movidius.com/discussion/683/tensorflow-conversion-toolkit-error-output-node-not-found

コードは添付。

結果

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

おそらくこのinputMobilenetV1/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"]()]]

どうやら入力のプレースホルダに何も与えられていない模様?
それは私のせいではないのではないだろうか?

https://ncsforum.movidius.com/discussion/1010/why-is-there-an-invalidargumenterror-you-must-feed-a-value-for-placeholder-tensor-dense-1-input

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)