I trained my customized ssd_mobilenet_v2 using TensorFlow2 Object Detection API.
After training completed, I used exporter_main_v2.py to export a saved_model of my customized model.
If I load saved_model by TensorFlow2, it seem there are two kind of output format.
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, 100) dtype=float32>,
<tf.Tensor 'Identity_3:0' shape=(1, 100, 7) dtype=float32>,
<tf.Tensor 'Identity_4:0' shape=(1, 100) dtype=float32>,
<tf.Tensor 'Identity_5:0' shape=(1,) dtype=float32>,
<tf.Tensor 'Identity_6:0' shape=(1, 1917, 4) dtype=float32>,
<tf.Tensor 'Identity_7:0' shape=(1, 1917, 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, 100), dtype=tf.float32, name='detection_scores'),
'detection_multiclass_scores': TensorSpec(shape=(1, 100, 7), dtype=tf.float32, name='detection_multiclass_scores'),
'num_detections': TensorSpec(shape=(1,), dtype=tf.float32, name='num_detections'),
'raw_detection_boxes': TensorSpec(shape=(1, 1917, 4), dtype=tf.float32, name='raw_detection_boxes'),
'detection_boxes': TensorSpec(shape=(1, 100, 4), dtype=tf.float32, name='detection_boxes'),
'detection_anchor_indices': TensorSpec(shape=(1, 100), dtype=tf.float32, name='detection_anchor_indices'),
'raw_detection_scores': TensorSpec(shape=(1, 1917, 7), dtype=tf.float32, name='raw_detection_scores')}
'''
Then, I try to convert this saved_model to onnx format using tf2onnx.
However, the outputs of onnxruntime was a list.
By the shape of result in the list, I think that the sequence is same as 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,300,3), dtype=np.uint8)})
print(pred_onx) # a list
print([i.shape for i in pred_onx])
'''
[(1, 100),
(1, 100, 4),
(1, 100),
(1, 100, 7),
(1, 100),
(1,),
(1, 1917, 4),
(1, 1917, 7)]
'''
Because there is some shape of result which is same as others, so it become hard to recognized.
Is there any document talk about this relationship that I can refer?
After I looked closely into the values in outputs. I found the mapping relationship below.