5

我正在使用 TensorFlow 2.1 来训练具有量化感知训练的模型。

这样做的代码是:

import tensorflow_model_optimization as tfmot
model = tfmot.quantization.keras.quantize_annotate_model(model)

这将向图中添加伪量化节点。这些节点应该调整模型的权重,以便它们更容易量化为 int8 并处理 int8 数据。

训练结束时,我将模型转换并量化为 TF-Lite,如下所示:

converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = [give data provider]
quantized_tflite_model = converter.convert()

在这一点上,我不希望在 TL-Lite 图中看到虚假量化层。但令人惊讶的是,我确实看到了它们。此外,当我在 TF-Lite C++示例应用程序中运行这个量化模型时,我看到它也在推理过程中运行了假量化节点。除此之外,它还对每一层之间的激活进行去量化和量化。

这是 C++ 代码的输出示例:

节点 0 运算符内置代码 80 FAKE_QUANT
输入:1
输出:237
节点 1 运算符内置代码 114 QUANTIZE
输入:237
输出:238
节点 2 运算符内置代码 3 CONV_2D
输入:238 59 58
输出:167
临时:378
节点 3 运算符内置代码 6 DEQUANTIZE
输入:167
输出:239
节点 4 运算符内置代码 80 FAKE_QUANT
输入:239
输出:166
节点 5 运算符内置代码 114 QUANTIZE
输入:166
输出:240
节点 6 运算符内置代码 3 CONV_2D
输入:240 61 60
输出:169

所以我觉得这一切都很奇怪,同时考虑到这个模型应该只在 int8 上运行并且实际上假量化节点将 float32 作为输入。

这里的任何帮助将不胜感激。

4

3 回答 3

0

您可以强制 TF Lite 仅使用 INT 操作:

converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]

如果发生错误,则网络的某些层还没有 INT8 实现。

此外,您还可以尝试使用Netron调查您的网络。

尽管如此,如果您还想拥有 INT8 输入和输出,您还需要调整这些:

converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8

但是,目前存在关于输入和输出的未解决问题,请参阅问题 #38285

于 2020-06-26T14:34:31.730 回答
0

代表数据集主要用于训练后量化。

将您的命令与 QAT 示例进行比较,您可能希望删除该行。

https://www.tensorflow.org/model_optimization/guide/quantization/training_example

converter = tf.lite.TFLiteConverter.from_keras_model(q_aware_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]

quantized_tflite_model = converter.convert()


# Create float TFLite model.
float_converter = tf.lite.TFLiteConverter.from_keras_model(model)
float_tflite_model = float_converter.convert()

# Measure sizes of models.
_, float_file = tempfile.mkstemp('.tflite')
_, quant_file = tempfile.mkstemp('.tflite')

with open(quant_file, 'wb') as f:
  f.write(quantized_tflite_model)

with open(float_file, 'wb') as f:
  f.write(float_tflite_model)

print("Float model in Mb:", os.path.getsize(float_file) / float(2**20))
print("Quantized model in Mb:", os.path.getsize(quant_file) / float(2**20))
于 2020-06-22T21:57:56.473 回答
0

我遇到了同样的问题。在我的例子中,量化的 tflite 模型的大小通过虚假量化增加了 ~3 倍。你会想到吗?检查 Netron 中的 tflite 图显示在每个操作之间插入了量化层。

到目前为止,我的解决方法是在没有虚假量化的情况下启动模型的新副本,然后从量化感知训练模型中逐层加载权重。它不能直接为整个模型设置权重,因为假量化层也有参数。

于 2021-02-17T22:36:52.600 回答