TensorFlow fake-quantize 层也是从 TF-Lite 调用的

Posted

技术标签:

【中文标题】TensorFlow fake-quantize 层也是从 TF-Lite 调用的【英文标题】:TensorFlow fake-quantize layers are also called from TF-Lite 【发布时间】:2020-10-07 12:46:39 【问题描述】:

我正在使用 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++ sample app 中运行这个量化模型时,我发现它也在推理过程中运行了假量化节点。除此之外,它还对每一层之间的激活进行去量化和量化。

这是 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 作为输入。

如有任何帮助,我们将不胜感激。

【问题讨论】:

你的表现能与非量化模型相媲美吗?意思是,也许假节点无关紧要? 【参考方案1】:

representative_dataset 主要用于训练后量化。

将您的命令与 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))

【讨论】:

【参考方案2】:

您可以强制 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

但是,目前有一个关于输入和输出的未解决问题,请参阅Issue #38285

【讨论】:

不幸的是,这并没有从图中删除虚假量化层,并且它们仍然在推理过程中被调用。 嗨,Meir,您找到解决方案了吗?如果是这样,您能否将其添加到您的问题中。谢谢【参考方案3】:

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

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

【讨论】:

以上是关于TensorFlow fake-quantize 层也是从 TF-Lite 调用的的主要内容,如果未能解决你的问题,请参考以下文章

Tensorflow的安装教程

如何让 Tensorflow Profiler 在 Tensorflow 2.5 中使用“tensorflow-macos”和“tensorflow-metal”工作

python [test tensorflow] test tensorflow installation #tensorflow

关于tensorflow的显存占用问题

java调用tensorflow训练好的模型

tensorflow新手必看,tensorflow入门教程,tensorflow示例代码