Hi @Jean_de and @Khushwanth
I have managed to make it work!
As I suspected, the model we build in the C2W2 colab has float inputs (image below from netron.app, great tool to visualise models):
But the model used in the Image Classification android studio app provided has uint8 inputs:
This is why when I substituted the new model we created in the colab (called ‘converted_model.tflite’) with the model provided in the IImage Classification android studio app (called ‘mobilenet_v1_1.0_224_quant.tflite’) I got an error (‘Cannot copy to a TensorFlowLite tensor (serving_default_keras_layer_input:0) with 602112 bytes from a Java Buffer with 150528 bytes’)
So after lots of reading around of stack overflow and tensorflow docs and banging my head against the wall I went back to the Colab (C2W2) to alter the process where we convert the model to tflite.
To be more specific, I made sure that in the conversion process, when we quantize, both the input and output of the model were converted to the uint8 datatype.
This is known as “integer-only quantization”, and here is the code to do it from the Tensorflow docs:
def representative_data_gen():
for input_value in tf.data.Dataset.from_tensor_slices(train_images).batch(1).take(100):
yield [input_value]
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_data_gen
# Ensure that if any ops can't be quantized, the converter throws an error
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
# Set the input and output tensors to uint8 (APIs added in r2.3)
converter.inference_input_type = tf.uint8
converter.inference_output_type = tf.uint8
tflite_model_quant = converter.convert()
But in order for that code to work in C2W2, it needs to look like this:
def format_image(image, label):
image = tf.image.resize(image, IMAGE_SIZE) / 255.0
return image
BATCH_SIZE = 32
train_images = train_examples.shuffle(num_examples // 4).batch(BATCH_SIZE).map(format_image).prefetch(1)
def representative_data_gen():
for input_value in train_images.take(100):
yield [input_value]
converter = tf.lite.TFLiteConverter.from_saved_model(RPS_SAVED_MODEL)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_data_gen
# Ensure that if any ops can't be quantized, the converter throws an error
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
# Set the input and output tensors to uint8 (APIs added in r2.3)
converter.inference_input_type = tf.uint8
converter.inference_output_type = tf.uint8
tflite_model_quant = converter.convert()
Downloading and saving this other model in the Image Classification android studio app now works
I am not a mentor in the D&D specialization, but since you guys are, I would suggest posting this discovery and solution as a gitissue, it may help future learners if this is fixed
Jaime