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 目標識別調試筆記(二)