google-coral / tflite

Examples using TensorFlow Lite API to run inference on Coral devices
https://coral.withgoogle.com
Apache License 2.0
182 stars 68 forks source link

Convert keras model to quantized tflite lost precision #20

Closed ChiHangChen closed 3 years ago

ChiHangChen commented 4 years ago

I'm trying to convert my keras model into tflite quantized model so that I can run my model on coral TPU, but the output of my keras model and tflite model are significantly different.

The red points are quantized tflite model output, and blue points are original keras model output.

img is here

Here is my code to convert keras model to quantized tflite model :

quant = True
gc.collect()
import tensorflow as tf
import numpy as np
import pathlib
print(tf.__version__)
converter = tf.lite.TFLiteConverter.from_keras_model(model)
if quant:
    print("Converting quant....")
    sample_size = 200
    rdm_idx = np.random.choice(range(len(X_test)),sample_size)
    rep_data = tf.cast(X_train[rdm_idx], tf.float32) / 255.0
    dataset = tf.data.Dataset.from_tensor_slices(rep_data).batch(1)

    def representative_data_gen():
        for input_value in dataset.take(sample_size):
            yield [input_value]

    converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
    converter.representative_dataset = representative_data_gen
    converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
    converter.inference_input_type = tf.uint8
    converter.inference_output_type = tf.uint8
    tflite_model_quant = converter.convert()
    open("MaskedLandMarkDetction_MobileNetV2_quant_fromKeras_v5.tflite", "wb").write(tflite_model_quant)

    print("Write quantization tflite done.")
else:
    print("Converting normal....")
    tflite_model = converter.convert()
    open("MaskedLandMarkDetction_MobileNetV2_fromKeras.tflite", "wb").write(tflite_model)
    print("Write tflite done.") 

X_train is my training data, and I will scale input images value from 0 to 1 by divided 255., so I do the same in representative_data_gen functions.

Any assistance you can provide would be greatly appreciated.

Namburger commented 4 years ago

@ChiHangChen Your usage definitely looks correct, so I believe this is a bug with tflite conversion. Unfortunately, this issue is out of our hand, please open an issue here. My suggestion is to add some extra calibration steps also?

    calibration_steps = 200
    def representative_data_gen():
        for i in range(calibration_steps):
            for input_value in dataset.take(sample_size):
                yield [input_value]
ChiHangChen commented 4 years ago

@ChiHangChen Your usage definitely looks correct, so I believe this is a bug with tflite conversion. Unfortunately, this issue is out of our hand, please open an issue here. My suggestion is to add some extra calibration steps also?

    calibration_steps = 200
    def representative_data_gen():
        for i in range(calibration_steps):
            for input_value in dataset.take(sample_size):
                yield [input_value]

I did, I add calibration_steps up to 20000 but it still the same.

ChiHangChen commented 4 years ago

I use tensorflow-gpu==2.2.0 BTW.

Namburger commented 4 years ago

@ChiHangChen hummm, just fyi, with tf2.x, these parameters are deprecated:

    converter.inference_input_type = tf.uint8
    converter.inference_output_type = tf.uint8

if you visualize your model with netron, I/O will still be float, are you aware of that? Could I see how you're setting the input tensors?

manoj7410 commented 3 years ago

Feel free to reopen if this issue still persists.