|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r"""Exports TF2 detection SavedModel for conversion to TensorFlow Lite. |
|
Link to the TF2 Detection Zoo: |
|
https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_detection_zoo.md |
|
The output folder will contain an intermediate SavedModel that can be used with |
|
the TfLite converter. |
|
NOTE: This only supports SSD meta-architectures for now. |
|
One input: |
|
image: a float32 tensor of shape[1, height, width, 3] containing the |
|
*normalized* input image. |
|
NOTE: See the `preprocess` function defined in the feature extractor class |
|
in the object_detection/models directory. |
|
Four Outputs: |
|
detection_boxes: a float32 tensor of shape [1, num_boxes, 4] with box |
|
locations |
|
detection_classes: a float32 tensor of shape [1, num_boxes] |
|
with class indices |
|
detection_scores: a float32 tensor of shape [1, num_boxes] |
|
with class scores |
|
num_boxes: a float32 tensor of size 1 containing the number of detected boxes |
|
Example Usage: |
|
-------------- |
|
python object_detection/export_tflite_graph_tf2.py \ |
|
--pipeline_config_path path/to/ssd_model/pipeline.config \ |
|
--trained_checkpoint_dir path/to/ssd_model/checkpoint \ |
|
--output_directory path/to/exported_model_directory |
|
The expected output SavedModel would be in the directory |
|
path/to/exported_model_directory (which is created if it does not exist). |
|
Config overrides (see the `config_override` flag) are text protobufs |
|
(also of type pipeline_pb2.TrainEvalPipelineConfig) which are used to override |
|
certain fields in the provided pipeline_config_path. These are useful for |
|
making small changes to the inference graph that differ from the training or |
|
eval config. |
|
Example Usage 1 (in which we change the NMS iou_threshold to be 0.5 and |
|
NMS score_threshold to be 0.0): |
|
python object_detection/export_tflite_model_tf2.py \ |
|
--pipeline_config_path path/to/ssd_model/pipeline.config \ |
|
--trained_checkpoint_dir path/to/ssd_model/checkpoint \ |
|
--output_directory path/to/exported_model_directory |
|
--config_override " \ |
|
model{ \ |
|
ssd{ \ |
|
post_processing { \ |
|
batch_non_max_suppression { \ |
|
score_threshold: 0.0 \ |
|
iou_threshold: 0.5 \ |
|
} \ |
|
} \ |
|
} \ |
|
} \ |
|
" |
|
Example Usage 2 (export CenterNet model for keypoint estimation task with fixed |
|
shape resizer and customized input resolution): |
|
python object_detection/export_tflite_model_tf2.py \ |
|
--pipeline_config_path path/to/ssd_model/pipeline.config \ |
|
--trained_checkpoint_dir path/to/ssd_model/checkpoint \ |
|
--output_directory path/to/exported_model_directory \ |
|
--keypoint_label_map_path path/to/label_map.txt \ |
|
--max_detections 10 \ |
|
--centernet_include_keypoints true \ |
|
--config_override " \ |
|
model{ \ |
|
center_net { \ |
|
image_resizer { \ |
|
fixed_shape_resizer { \ |
|
height: 320 \ |
|
width: 320 \ |
|
} \ |
|
} \ |
|
} \ |
|
}" \ |
|
""" |
|
from absl import app |
|
from absl import flags |
|
|
|
import tensorflow.compat.v2 as tf |
|
from google.protobuf import text_format |
|
from object_detection import export_tflite_graph_lib_tf2 |
|
from object_detection.protos import pipeline_pb2 |
|
|
|
tf.enable_v2_behavior() |
|
|
|
FLAGS = flags.FLAGS |
|
|
|
flags.DEFINE_string( |
|
'pipeline_config_path', None, |
|
'Path to a pipeline_pb2.TrainEvalPipelineConfig config ' |
|
'file.') |
|
flags.DEFINE_string('trained_checkpoint_dir', None, |
|
'Path to trained checkpoint directory') |
|
flags.DEFINE_string('output_directory', None, 'Path to write outputs.') |
|
flags.DEFINE_string( |
|
'config_override', '', 'pipeline_pb2.TrainEvalPipelineConfig ' |
|
'text proto to override pipeline_config_path.') |
|
flags.DEFINE_integer('max_detections', 10, |
|
'Maximum number of detections (boxes) to return.') |
|
|
|
flags.DEFINE_bool( |
|
'ssd_use_regular_nms', False, |
|
'Flag to set postprocessing op to use Regular NMS instead of Fast NMS ' |
|
'(Default false).') |
|
|
|
flags.DEFINE_bool( |
|
'centernet_include_keypoints', False, |
|
'Whether to export the predicted keypoint tensors. Only CenterNet model' |
|
' supports this flag.' |
|
) |
|
flags.DEFINE_string( |
|
'keypoint_label_map_path', None, |
|
'Path of the label map used by CenterNet keypoint estimation task. If' |
|
' provided, the label map path in the pipeline config will be replaced by' |
|
' this one. Note that it is only used when exporting CenterNet model for' |
|
' keypoint estimation task.' |
|
) |
|
|
|
|
|
def main(argv): |
|
del argv |
|
flags.mark_flag_as_required('pipeline_config_path') |
|
flags.mark_flag_as_required('trained_checkpoint_dir') |
|
flags.mark_flag_as_required('output_directory') |
|
|
|
pipeline_config = pipeline_pb2.TrainEvalPipelineConfig() |
|
|
|
with tf.io.gfile.GFile(FLAGS.pipeline_config_path, 'r') as f: |
|
text_format.Parse(f.read(), pipeline_config) |
|
override_config = pipeline_pb2.TrainEvalPipelineConfig() |
|
text_format.Parse(FLAGS.config_override, override_config) |
|
pipeline_config.MergeFrom(override_config) |
|
|
|
export_tflite_graph_lib_tf2.export_tflite_model( |
|
pipeline_config, FLAGS.trained_checkpoint_dir, FLAGS.output_directory, |
|
FLAGS.max_detections, FLAGS.ssd_use_regular_nms, |
|
FLAGS.centernet_include_keypoints, FLAGS.keypoint_label_map_path) |
|
|
|
|
|
if __name__ == '__main__': |
|
app.run(main) |
|
|