从 TensorFlow 到 TensorFlow Lite 的模型转换不起作用,因为并非所有参数都量化为 int8

问题描述 投票:0回答:1

我尝试将TensorFlow模型转换为.tflite,我发现.tflite的参数并不都是int8,而有些参数也是float32。只有dense参数是int8,而conv2d参数也是float32。为什么(TensorFlow官网也说:参数量化为int8。)?我期望所有参数都被量化,而激活没有被量化。

操作系统:Ubuntu 22.04 GPU:RX 3090,TensorFlow:2.4

代码如下:

import tensorflow as tf
import numpy as np
import pathlib
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "1"

mnist = tf.keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

train_images = train_images.astype(np.float32) / 255.0
test_images = test_images.astype(np.float32) / 255.0


model = tf.keras.Sequential([
tf.keras.layers.InputLayer(input_shape=(28, 28)),
tf.keras.layers.Reshape(target_shape=(28, 28, 1)),
tf.keras.layers.Conv2D(filters=12, kernel_size=(3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
tf.keras.layers.Flatten(), 
tf.keras.layers.Dense(10) 
])
model.summary()

model.compile(optimizer='adam',
          loss=tf.keras.losses.SparseCategoricalCrossentropy(
              from_logits=True),
          metrics=['accuracy'])
model.fit(
train_images,
train_labels,
epochs=1,
validation_data=(test_images, test_labels)
)

converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAUL]

tflite_model_quant = converter.convert()
tensorflow converters tensorflow-lite tflite
1个回答
0
投票

您编写的代码对应于 TFLite 中的动态范围量化。正如文档所建议的,

这种类型的量化,仅在转换时静态量化从浮点到整数的权重,提供 8 位精度

以及 TFLite 团队的另一篇 博客文章 (2) 建议,

动态量化模型与全量化模型类似,全连接和卷积算子的权重在模型转换期间被量化为 8 位整数。所有其他张量都没有量化,它们仍然是 float32 张量。

很明显,

Conv2D
的核和
Dense
层的权重在转换时被量化为
int8
,所有其他张量都是
float32

现在在推理时,

float32
激活被量化为
int8
,以带来相当于完全
int8
量化模型的优化。 (2) 的另一点,

全量化和动态范围量化之间的第二个区别是全连接和卷积运算符的输出采用 32 位浮点格式,而不是全量化运算符的 8 位整数。

动态范围量化排除了所有参数量化为

int8
的可能性。在模型转换期间,权重和核被量化为
int8
,但激活仍保持在
float32
。在推理期间,观察激活值的范围,将其量化为
int8
,从而实现更好的量化后质量保留。

© www.soinside.com 2019 - 2024. All rights reserved.