问题描述
我使用 TensorFlow2对象检测API 训练了自定义的ssd_mobilenet_v2。
训练完成后,我使用exporter_main_v2.py导出了自定义模型的saved_model。
如果我通过TensorFlow2加载save_model,似乎有两种输出格式。
import tensorflow as tf
saved_model = tf.saved_model.load("saved_model")
detect_fn = saved_model["serving_default"]
print(detect_fn.outputs)
'''
[<tf.Tensor 'Identity:0' shape=(1,100) dtype=float32>,<tf.Tensor 'Identity_1:0' shape=(1,100,4) dtype=float32>,<tf.Tensor 'Identity_2:0' shape=(1,<tf.Tensor 'Identity_3:0' shape=(1,7) dtype=float32>,<tf.Tensor 'Identity_4:0' shape=(1,<tf.Tensor 'Identity_5:0' shape=(1,) dtype=float32>,<tf.Tensor 'Identity_6:0' shape=(1,1917,<tf.Tensor 'Identity_7:0' shape=(1,7) dtype=float32>]
'''
print(detect_fn.structured_outputs)
'''
{'detection_classes': TensorSpec(shape=(1,100),dtype=tf.float32,name='detection_classes'),'detection_scores': TensorSpec(shape=(1,name='detection_scores'),'detection_multiclass_scores': TensorSpec(shape=(1,7),name='detection_multiclass_scores'),'num_detections': TensorSpec(shape=(1,),name='num_detections'),'raw_detection_Boxes': TensorSpec(shape=(1,4),name='raw_detection_Boxes'),'detection_Boxes': TensorSpec(shape=(1,name='detection_Boxes'),'detection_anchor_indices': TensorSpec(shape=(1,name='detection_anchor_indices'),'raw_detection_scores': TensorSpec(shape=(1,name='raw_detection_scores')}
'''
然后,我尝试使用tf2onnx将此save_model转换为onnx格式。
但是,onnxruntime的输出是一个列表。
根据列表中结果的形状,我认为序列与detect_fn.outputs
import numpy as np
import onnxruntime as rt
sess = rt.InferenceSession("model.onnx")
input_name = sess.get_inputs()[0].name
pred_onx = sess.run(None,{input_name: np.zeros((1,300,3),dtype=np.uint8)})
print(pred_onx) # a list
print([i.shape for i in pred_onx])
'''
[(1,(1,7)]
'''
由于某种形式的结果与其他形式相同,因此变得难以识别。
我可以参考任何有关这种关系的文件吗?
解决方法
我仔细查看了输出中的值。 我在下面找到了映射关系。
def result_mapper(outputs):
result_dict = dict()
result_dict["num_detections"] = outputs[5]
result_dict["raw_detection_scores"] = outputs[7]
result_dict["raw_detection_boxes"] = outputs[6]
result_dict["detection_multiclass_scores"] = outputs[3]
result_dict["detection_boxes"] = outputs[1]
result_dict["detection_scores"] = outputs[4]
result_dict["detection_classes"] = outputs[2]
result_dict["detection_anchor_indices"] = outputs[0]
return result_dict
,
有同样的问题,经过几个小时的调试后发现它们是......按排序顺序。确定迭代顺序的方法是here。
在 dict 实例的情况下,序列由值组成,按以下顺序排序 确保确定性行为的关键。