Search code examples
pythontensorflowtensorflow2.0tensorflow-lite

TensorFlow convert from .pb to .tflite failes due to ops error


Hey everyone this is my first question post. If I do something wrong or u need more information please just tell me I will try to give my best.

I tried to create a object detection for TensorFlow lite. For this I trained a model called ssd_mobilenet_v2_fpnlite_320x320_coco17_tpu-8 downloaded form here: https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_detection_zoo.md

I followed some Tutorial for that. This all worked fine. After this was done I exported my newst ckpt via

python exporter_main_v2.py 
--pipeline_config_path=training/ssd_mobilenet_v2_fpnlite_320x320_coco17_tpu-8.config
--trained_checkpoint_dir=/training 
--output_directory=/training/model

As a result i received under training/model/save_model my saved_model.pd. Now my plan was to convert this saved_model.pd to a .tflite file.

And this is where I am stuck. I tried to convert it with

tflite_convert 
--output_file=tflite/ 
--saved_model_dir=model/saved_model 
--graph_def_file=model/saved_model/saved_model.pb 
--input_arrays=input --output_arrays=TFLite_Detection_PostProcess,TFLite_Detection_PostProcess:1,TFLite_Detection_PostProcess:2,TFLite_Detection_PostProcess:3 
--input_shape=1,320,320,3 
--allow_custom_ops

and with

toco 
--saved_model_dir=model/saved_model 
--output_file=tflite/detect.tflite

but what ever I do I always receive a long error message

tflite_convert --output_file=training/tflite/ --saved_model_dir=training/model/saved_model --graph_def_file=training/model/saved_model/saved_model.pb --input_arrays=input --output_arrays=TFLite_Detection_PostProcess,TFLite_Detection_PostProcess:1,TFLite_Detection_PostProcess:2,TFLite_Detection_PostProcess:3 --
input_shape=1,320,320,3 --allow_custom_ops
2022-05-11 15:01:16.421059: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operati
ons:  AVX AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2022-05-11 15:01:16.905178: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1525] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 7445 MB memory:  -> device: 0, name: NVIDIA GeForce RTX 3080, pci bus id: 0000:02:00.
0, compute capability: 8.6
2022-05-11 15:01:25.665750: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:357] Ignored output_format.
2022-05-11 15:01:25.665982: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:360] Ignored drop_control_dependency.
2022-05-11 15:01:25.666905: I tensorflow/cc/saved_model/reader.cc:43] Reading SavedModel from: training/model/saved_model

    raise converter_error
tensorflow.lite.python.convert_phase.ConverterError: <unknown>:0: error: loc(callsite(callsite(fused["ConcatV2:", "Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/concat@__inferenc
e_call_func_11394"] at fused["StatefulPartitionedCall:", "StatefulPartitionedCall@__inference_signature_wrapper_13768"]) at fused["StatefulPartitionedCall:", "StatefulPartitionedCall"])): 'tf.ConcatV2' op is neither a custom op nor a f
lex op
<unknown>:0: note: loc(fused["StatefulPartitionedCall:", "StatefulPartitionedCall"]): called from
<unknown>:0: note: loc(callsite(callsite(fused["ConcatV2:", "Postprocessor/BatchMultiClassNonMaxSuppression/MultiClassNonMaxSuppression/ChangeCoordinateFrame/Scale/concat@__inference_call_func_11394"] at fused["StatefulPartitionedCall:
", "StatefulPartitionedCall@__inference_signature_wrapper_13768"]) at fused["StatefulPartitionedCall:", "StatefulPartitionedCall"])): Error code: ERROR_NEEDS_FLEX_OPS
<unknown>:0: error: loc(callsite(fused["StridedSlice:", "map/while/strided_slice@map_while_body_7735"] at callsite(callsite(fused["StatelessWhile:", "map/while@__inference_call_func_11394"] at fused["StatefulPartitionedCall:", "Statefu
lPartitionedCall@__inference_signature_wrapper_13768"]) at fused["StatefulPartitionedCall:", "StatefulPartitionedCall"]))): 'tf.StridedSlice' op is neither a custom op nor a flex op
<unknown>:0: note: loc(callsite(callsite(fused["StatelessWhile:", "map/while@__inference_call_func_11394"] at fused["StatefulPartitionedCall:", "StatefulPartitionedCall@__inference_signature_wrapper_13768"]) at fused["StatefulPartition
edCall:", "StatefulPartitionedCall"])): called from
<unknown>:0: note: loc(fused["StatefulPartitionedCall:", "StatefulPartitionedCall"]): called from
<unknown>:0: note: loc(callsite(fused["StridedSlice:", "map/while/strided_slice@map_while_body_7735"] at callsite(callsite(fused["StatelessWhile:", "map/while@__inference_call_func_11394"] at fused["StatefulPartitionedCall:", "Stateful
PartitionedCall@__inference_signature_wrapper_13768"]) at fused["StatefulPartitionedCall:", "StatefulPartitionedCall"]))): Error code: ERROR_NEEDS_FLEX_OPS
<unknown>:0: error: failed while converting: 'main':
Some ops are not supported by the native TFLite runtime, you can enable TF kernels fallback using TF Select. See instructions: https://www.tensorflow.org/lite/guide/ops_select
TF Select ops: ConcatV2, StridedSlice
Details:
        tf.ConcatV2(tensor<f32>, tensor<f32>, tensor<f32>, tensor<f32>, tensor<i32>) -> (tensor<4xf32>) : {device = ""}
        tf.StridedSlice(tensor<?x?x3xf32>, tensor<4xi32>, tensor<4xi32>, tensor<4xi32>) -> (tensor<1x?x?x3xf32>) : {begin_mask = 14 : i64, device = "", ellipsis_mask = 0 : i64, end_mask = 14 : i64, new_axis_mask = 1 : i64, shrink_axis_
mask = 0 : i64}

Those scripts I try to use are from here: https://github.com/tensorflow/models/tree/master/research/object_detection

As I am a beginner with TensorFlow I dont really understand the problem here. As far I can understand this problem has something todo with the ops that some features which are support in TensorFlow 2 are not supported in TensorFlow Lite.


Solution

  • Found the soloution by my selfe.

    I simply used the wrong script to convert from checkpoints to frozen graph(.pd)

    I needed to use the export_tflite_graph_tf2.py script instead of the exporter_main_v2.py. After this I could simply use the tflite_convert script to export to .tflite