ssd_mobilenet移植到Movidius到目前为止我还没移植成功,这里记录一下遇到的一些问题,以及后续的研究方向。
首先,我们在 detection_models_zoo中把ssdlite_mobilenet_v2_coco算法模型下载下来,下载后的tar包中有如下__图二__中的几个文件:
checkpoint:这个文件是检查点文件,该文件是在网络训练过程中通过tf.train.Saver保存的当前批次训练结束后的检查点文件。
frozen_inference_graph.pb:这个文件是生成的一个可以用来导入到tflite中的计算图,我们在tensorflow中调用该模型进行目标检测时正是通过解析该文件来获取计算图和参数集。
model.ckpt.*:这三个文件和前面的__checkpoint__文件是对应出现的,model.ckpt.data*是所有weights和bias的值,model.ckpt.meta是计算图,model.ckpt.index是索引文件。
pipeline.config:是保存一些模型入参的配置文件,是用来我们训练自己的模型时进行调参用。
所以按照ncsdk/docs/tf_compile_guidance.html描述,再结合上面这几个文件作用的分析,我使用的编译命令如下:
mvNCCompile frozen_inference_graph.pb -s 12 -in input -on output -o ssd_mobilenet.graph
mvNCCompile:Ncsdk的编译工具,用来生成计算图。
-s: 使用SHAVE的个数。
-in: 网络模型中输入层node的名字。
-on: 网络模型中输出层node的名字。
-o: 编译后生成的文件名。
运行之后,问题来了:
问题一:input node找不到
$ mvNCCompile frozen_inference_graph.pb -s 12 -in input -on output -o ssd_mobilenet.graph
mvNCCompile v02.00, Copyright @ Intel Corporation 2017
/usr/local/lib/python3.5/dist-packages/tensorflow/python/util/tf_inspect.py:45: DeprecationWarning: inspect.getargspec() is deprecated, use inspect.signature() instead
Traceback (most recent call last):
File "/usr/local/bin/mvNCCompile", line 169, in <module>
create_graph(args.network, args.image, args.inputnode, args.outputnode, args.outfile, args.nshaves, args.inputsize, args.weights, args.explicit_concat, args.ma2480, args.scheduler, args.new_parser, args)
File "/usr/local/bin/mvNCCompile", line 148, in create_graph
load_ret = load_network(args, parser, myriad_config)
File "/usr/local/bin/ncsdk/Controllers/Scheduler.py", line 100, in load_network
parse_ret = parse_tensor(arguments, myriad_conf)
File "/usr/local/bin/ncsdk/Controllers/TensorFlowParser.py", line 225, in parse_tensor
inputTensor = graph.get_tensor_by_name(inputnode + ':0')
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py", line 3654, in get_tensor_by_name
return self.as_graph_element(name, allow_tensor=True, allow_operation=False)
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py", line 3478, in as_graph_element
return self._as_graph_element_locked(obj, allow_tensor, allow_operation)
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py", line 3520, in _as_graph_element_locked
"graph." % (repr(name), repr(op_name)))
KeyError: "The name 'input:0' refers to a Tensor which does not exist. The operation, 'input', does not exist in the graph."
后来经过分析和导出计算图,发现tensorflow使用的这些目标识别的计算图中,统一针对输入和输出层的张量命令如下:
type | name1 | name2 | name3 | name4 |
---|---|---|---|---|
input | image_tensor:0 | - | - | - |
output | detection_boxes:0 | detection_scores:0 | detection_classes:0 | num_detections:0 |
__原来他们的输出层有四个张量!!!__我表示哭笑不得。
问题二:不支持多个结点
于是,根据input node 和 output node的命名,我查遍了指导文档,试图找到如何在输出张量个数大于一时进行编译,mvNCCompile要怎么改,猜测是编译命令根本就不支持多个输出层结点。于是我跟踪了一下编译过程,找到 /usr/local/bin/ncsdk/Controllers/TensorFlowParser.py 这个脚本,发现如下代码:
def parse_tensor(arguments, myriad_conf, preprocess=True, debug=False):
path = arguments.net_description
image = arguments.image
output_node_name = arguments.output_node_name
input_node_name = arguments.input_node_name
filename = arguments.outputs_name
"""
a few codes
"""
try:
outputTensor = graph.get_tensor_by_name(output_node_name + ':0')
except:
throw_error(ErrorTable.NoOutputNode, output_node_name + ':0')
shape = inputTensor.get_shape()
从上面代码就可以明确地看出来:
input node 和 output node 根本就只能支持一个,不支持多个。
问题三:部分张量类型不支持
接下来,我抱着尝试一下的心态,将命令改成只输出一个张量结点,如下:
mvNCCompile frozen_inference_graph.pb -s 12 -in image_tensor -on detection_boxes -o ssd_mobilenet.graph
执行命令后,依然报错如下:
$ mvNCCompile frozen_inference_graph.pb -s 12 -in image_tensor -on detection_boxes -o ssd_mobilenet.graph
mvNCCompile v02.00, Copyright @ Intel Corporation 2017
/usr/local/lib/python3.5/dist-packages/tensorflow/python/util/tf_inspect.py:45: DeprecationWarning: inspect.getargspec() is deprecated, use inspect.signature() instead
get inputTensor: Tensor("image_tensor:0", shape=(?, ?, ?, 3), dtype=uint8)
output_node_name: detection_boxes
Input image shape [1, 300, 300, 3]
0 Placeholder image_tensor
OUT: image_tensor:0
Starting to process
1 Cast ToFloat
IN: image_tensor:0
OUT: ToFloat:0
output_item: Tensor("ToFloat:0", shape=(?, ?, ?, 3), dtype=float32)
output_item.dtype: <dtype: 'float32'>
output_item.shape: (?, ?, ?, 3)
[Error 5] Toolkit Error: Stage Details Not Supported: Cast
意思是Cast张量类型不支持,然后查看了对应的代码,并将代码和网络模型的计算图比对之后,发现不止这一个类型不支持,如果去修改,这个改动量是巨大的。
所以,上述这几个问题是很致命的,也阻挡了我移植ssdlite_mobilenet_v2_coco这个网络模型。
###参考链接
1、Tensorflow objects detection models zoo
2、ARM+Movidius VPU 目标识别调试笔记(一)
3、ARM+Movidius VPU 目标识别调试笔记(二)
3、ARM+Movidius VPU 目标识别调试笔记(三)