【问题标题】:TFLite Quantized Model still outputs floatsTFLite 量化模型仍然输出浮点数
【发布时间】:2021-06-03 12:20:04
【问题描述】:

我有一个 CNN 已经在工作,但现在有必要将它放入一些特定的硬件中。为此,我被告知要量化模型,因为硬件只能使用整数运算。

我在这里阅读了一个很好的解决方案: How to make sure that TFLite Interpreter is only using int8 operations?

我写了这段代码来让它工作:

model_file = "models/my_cnn.h5"

# load data
model = tf.keras.models.load_model(model_file, custom_objects={'tf': tf}, compile=False)

# convert
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.uint16 # or tf.uint8
converter.inference_output_type = tf.uint16  # or tf.uint8
qmodel = converter.convert()
with open('thales.tflite', 'wb') as f:
   f.write(qmodel)

interpreter = tf.lite.Interpreter(model_content=qmodel)
interpreter.allocate_tensors()
# predict
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
print(input_details)
print(output_details)

image = read_image("test.png")

interpreter.set_tensor(input_details[0]['index'], image)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])
print(output_data)

当我们查看打印的输出时,我们可以看到,首先是详细信息:

input_details

[{'name': 'input_1', 'index': 87, 'shape': array([  1, 160, 160,   3], dtype=int32), 'shape_signature': array([  1, 160, 160,   3], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]

output_details

[{'name': 'Identity', 'index': 88, 'shape': array([  1, 160, 160,   1], dtype=int32), 'shape_signature': array([  1, 160, 160,   1], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]

而量化模型的输出为:

...
[[0.        ]
[0.        ]
[0.        ]
...
[0.00390625]
[0.00390625]
[0.00390625]]

[[0.        ]
[0.        ]
[0.        ]
...
[0.00390625]
[0.00390625]
[0.00390625]]]]

所以,我这里有几个问题:

  1. 在输入/输出细节中我们可以看到输入/输出层是int32,但我在代码中指定了uint16

  2. 同样在输入/输出细节中,我们可以看到多次出现“float32”作为 dtype,我不明白为什么。

  3. 最后,最大的问题是输出包含浮点数,这是不应该发生的。所以看起来模型并没有真正转换为整数。

我如何才能真正量化我的 CNN 以及为什么它无法使用这段代码?

【问题讨论】:

    标签: python tensorflow-lite quantization


    【解决方案1】:

    converter.inference_input_typeconverter.inference_output_type 仅支持 tf.int8tf.uint8,不支持 tf.uint16

    【讨论】:

    • 正如您在评论中看到的,我也尝试了“tf.uint8”,但仍然无法正常工作。 :(
    • 你能分享你的模型文件吗?你想量化什么样的架构?您的代表性数据集生成器是否有效?输入和输出细节中的量化比例和零点都是 0。
    • 不,我不能共享模型。它受 NDA 保护。架构是“某种操作系统 UNET”。是的,生成器按预期工作。
    • 我成功地使用您上面的代码量化了一个虚拟模型。 input_details {'name': 'input_1', 'index': 27, 'shape': array([ 1, 160, 160, 3], dtype=int32), 'shape_signature': array([ -1, 160, 160, 3], dtype=int32), 'dtype': &lt;class 'numpy.uint8'&gt;, 'quantization': (0.003921546973288059, 0), 'quantization_parameters': {'scales': array([0.00392155], dtype=float32), 'zero_points': array([0], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}] 试着看看你的模型,如果有一些层根本无法量化。
    • 非常感谢,我去看看。
    猜你喜欢
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多