Problem converting a saved_model.pb file to .tflite file with custom shapes - tensorflow2.0

I am using Tensorflow 2 on Windows 10 and I download a model from TensorFlow Detection Model Zoo.
The model I am using is ssd.mobilenetv2.oid4
The model details are:
[<tf.Tensor 'image_tensor:0' shape=(None, None, None, 3) dtype=uint8>]
Note: I also have the frozen_inference_graph.pb available along with config file and checkpoint.
I used the TensorFlowLiteConverter Snippet to convert a saved_model.pb file to .tflite with custom shape:
import tensorflow as tf
input_dir = "D:\\Models\\ssd_mobilenet_v2_oid_v4_2018_12_12\\saved_model"
model = tf.saved_model.load(input_dir)
concrete_func = model.signatures[
tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY]
concrete_func.inputs[0].set_shape([None, None, None, 3])
converter = tf.lite.TFLiteConverter.from_concrete_functions([concrete_func])
tflite_model = converter.convert()
I get the following error:
Traceback (most recent call last):
File "C:\Users\Bhavin\Desktop\TensorFlow_pb_converter.py", line 10, in <module>
tflite_model = converter.convert()
File "C:\Users\Bhavin\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow_core\lite\python\lite.py", line 428, in convert
"invalid shape '{1}'.".format(_get_tensor_name(tensor), shape_list))
ValueError: None is only supported in the 1st dimension. Tensor 'image_tensor' has invalid shape '[None, None, None, 3]'
I tried using toco and tflite_convert but I got the same error.
What am I doing wrong and how do I convert this pb file to tflite file?

Currently tensorflow Lite doesn't support converting dynamic shape except for first dimension.
Consider setting the exact shape instead of 'None'

Related

Tensorflow lite Error :Cannot convert a Tensor of dtype resource to a NumPy array

I'm working on the classification problem. The dataset is a .csv file that I created myself. Keras model is working and I want to convert the model to tensorflow lite as keras model.
# Convert the model.
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
# Save the model.
with open('model.tflite', 'wb') as f:
f.write(tflite_model)
the error code is as follows. Where am I making a mistake?
WARNING:absl:Function `_wrapped_model` contains input name(s) Mesafe, Derece, Yas, Irk with unsupported characters which will be renamed to mesafe, derece, yas, irk in the SavedModel.
INFO:tensorflow:Assets written to: /tmp/tmp70uq2yx2/assets
INFO:tensorflow:Assets written to: /tmp/tmp70uq2yx2/assets
---------------------------------------------------------------------------
InvalidArgumentError Traceback (most recent call last)
<ipython-input-36-cdc4a5509c9a> in <module>()
1 # Convert the model.
2 converter = tf.lite.TFLiteConverter.from_keras_model(model)
----> 3 tflite_model = converter.convert()
4
5 # Save the model.
6 frames
/usr/local/lib/python3.7/dist-packages/six.py in raise_from(value, from_value)
InvalidArgumentError: Cannot convert a Tensor of dtype resource to a NumPy array.

ERROR! Converting Keras model to Tensorflow lite

I have a simple classification model built with feature columns. I want to convert it to Tensorflow lite format. I'm using the Keras conversion code. But it gives the following error;
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
# Save the model.
with open('model.tflite', 'wb') as f:
f.write(tflite_model)
error message;
InvalidArgumentError: Cannot convert a Tensor of dtype resource to a NumPy array.
Why am I getting this error message?
Thank you.

Converting a SavedModel to TFLite

I've downloaded a FasterRCNN SavedModel from here. I'd like to convert it to a TFLite model. This seems like something simple to do with the tflite_convert cli.
tflite_convert --output_file model.tflite --saved_model_dir faster_rcnn_resnet101_coco_2018_01_28/saved_model
However, I'm receiving some issues regarding the input dimensions not being specified
ValueError: None is only supported in the 1st dimension. Tensor 'image_tensor' has invalid shape '[None, None, None, 3]'
Does anyone know a way around this? If it's not possible to use arbitrarily sized images in TFLite, I'm guessing there must be a away to overwrite image_tensor dimensions.
You can use the following code snippet to do that.
saved_model_dir = 'Path_to_saved_model_dir'
# Convert the model.
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
tflite_model = converter.convert()
# Save the TF Lite model.
with tf.io.gfile.GFile('model.tflite', 'wb') as f:
f.write(tflite_model)
NOTE: This function doesn't allow you to specify the input shape, so to do that you can use from_concrete_functions
model = tf.saved_model.load(saved_model_dir)
concrete_func = model.signatures[
tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY]
concrete_func.inputs[0].set_shape([1, 256, 256, 3])
converter = TFLiteConverter.from_concrete_functions([concrete_func])

Tensorflow - h5 model to tflite conversion error

I've made a learning transfer using a pre-trained InceptionV3 model, and I saved the h5 model file. After that, I am able to make predictions.
Now, I want to convert the h5 model to tflite file, using TFLiteConverter.convert() method, like this:
converter = lite.TFLiteConverter.from_keras_model_file('keras.model.h5')
tflite_model = converter.convert()
but I get this error:
File "from_saved_model.py", line 28, in <module>
tflite_model = converter.convert()
File "C:\Anaconda3\lib\site-packages\tensorflow\contrib\lite\python\lite.py", line 409, in convert
"invalid shape '{1}'.".format(_tensor_name(tensor), shape))
ValueError: None is only supported in the 1st dimension. Tensor 'input_1' has invalid shape '[None, None, None, 3]'
I am running Anaconda Python 3.6.8 on Windows 10 64 bits. Thank you in advance for your help!
Only the batch size (index 0) is allowed to be None when converting the model from TensorFlow to TensorFlow Lite. You should be able to use the input_shapes argument when calling from_keras_model_file to get the input array shape to be valid. For an InceptionV3 model, the input_shapes argument is often {'Mul' : [1,299,299,3]}.
The documentation for TFLiteConverter.from_keras_model_file is available here. The accepted parameters are as follows (copied from the documentation):
from_keras_model_file(
cls,
model_file,
input_arrays=None,
input_shapes=None,
output_arrays=None
)
load the keras.model.h5
set the input_shape, just avoid [None, None, None, 3]
save it as a new model.
Convert it just using the code you post in the question.
The batch_size is the only dimension that can be given as none.
The first dimension in the input_shape is the batch_size, the second and third dimensions indicate the input size of the image while the last one indicates the number of channels (RGB).
To avoid the error you get, specify the dimensions beforehand.
This can be achieved using toco (a tool which directly converts the acquired keras model into .tflite without converting it first to a .pb model and then to a .tflite model).
Using input_shape argument in toco you can specify the dimensions of the input_shape of your keras model.
Install toco for python and then run the following command,
toco --output_file = output_model.tflite --keras_model_file = keras.model.h5 --input_arrays input_1 --input_shape 1,299,299,3
Here the batch_size dimension might differ according to your model. As for the input size dimensions, 299x299 is the default input size for InceptionV3 models.

Input shape issue when using Keras LSTM with Tensorflow

I have been using Keras (version 1.1.1) LSTM with Theano as backend without any problem. Now I would like to switch to Tensorflow (version 0.8.0) and could not get a simple example to work. The problem can be boiled down to following code snippet copied from this Keras-Tensorflow interface tutorial.
from keras.layers import LSTM
import tensorflow as tf
my_graph = tf.Graph()
with my_graph.as_default():
x = tf.placeholder(tf.float32, shape=(None, 20, 64))
y = LSTM(32)(x)
And I got following error when last line is executed:
File "/home/xxx/local/lib/python2.7/site-packages/Keras-1.1.1-py2.7.egg/keras/engine/topology.py", line 529, in call
return self.call(x, mask)
File "/home/xxx/local/lib/python2.7/site-packages/Keras-1.1.1-py2.7.egg/keras/layers/recurrent.py", line 227, in call
input_length=input_shape1)
File "/home/xxx/local/lib/python2.7/site-packages/Keras-1.1.1-py2.7.egg/keras/backend/tensorflow_backend.py", line 1306, in rnn
axes = [1, 0] + list(range(2, len(outputs.get_shape())))
File "/usr/local/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/tensor_shape.py", line 462, in len
raise ValueError("Cannot take the length of Shape with unknown rank.")
ValueError: Cannot take the length of Shape with unknown rank.
Any suggestions?
You can't mix tensorflow as keras like that. Keras keeps track of the shape of its tensors separately from how tensorflow does.
Try using x = Input(shape=(20,64))