TensorFlow Concrete Function输出与structured_outputs对应关系及ONNX转换疑问
Great question! While there isn't a direct official document that explicitly maps detect_fn.outputs to structured_outputs, you can easily verify the correspondence with a quick test, and the order is consistent for models exported via TensorFlow Object Detection API (like your SSD MobileNet v2).
Exact Mapping for Your Model Outputs
Based on your provided output shapes and typical API behavior, here's the one-to-one correspondence:
Index in detect_fn.outputs / ONNX output list | Corresponding structured_outputs Key | Shape | Description |
|---|---|---|---|
| 0 | detection_classes | (1, 100) | Predicted class IDs for the top 100 detections |
| 1 | detection_boxes | (1, 100, 4) | Normalized bounding boxes (ymin, xmin, ymax, xmax) for the top 100 detections |
| 2 | detection_scores | (1, 100) | Confidence scores for the top 100 detections |
| 3 | detection_multiclass_scores | (1, 100, 7) | Multiclass confidence scores for each of the top 100 detections (the 7 matches your total class count plus background) |
| 4 | detection_anchor_indices | (1, 100) | Indices of the anchors used for the top 100 detections |
| 5 | num_detections | (1,) | Number of valid detections (usually ≤ 100) |
| 6 | raw_detection_boxes | (1, 1917, 4) | Bounding boxes for all generated anchors (1917 is the total anchor count for SSD MobileNet v2) |
| 7 | raw_detection_scores | (1, 1917, 7) | Raw confidence scores for all anchors |
How to Verify This Yourself
You can confirm this mapping by running inference on the same input and comparing values between the structured output dict and the raw output list:
import tensorflow as tf import numpy as np # Load your saved model saved_model = tf.saved_model.load("saved_model") detect_fn = saved_model["serving_default"] # Create a test input matching your model's expected shape test_img = np.random.randint(0, 255, (1, 300, 300, 3), dtype=np.uint8) input_tensor = tf.convert_to_tensor(test_img) # Get both structured and raw outputs structured_results = detect_fn(input_tensor) raw_output_list = list(structured_results.values()) # Compare values to confirm the mapping assert tf.equal(raw_output_list[0], structured_results["detection_classes"]).numpy().all() assert tf.equal(raw_output_list[1], structured_results["detection_boxes"]).numpy().all() # Repeat this check for other keys to be fully confident in the mapping
ONNX Runtime Output Correspondence
When you convert the SavedModel to ONNX with tf2onnx, the output list from onnxruntime follows exactly the same order as detect_fn.outputs. So the mapping table above applies directly to your ONNX inference results too.
内容的提问来源于stack exchange,提问作者Charlie Chang

