我已经使用Keras调整MobileNet v1。现在我有了model.h5
,我需要将其转换为TensorFlow Lite才能在Android应用中使用。
我使用TFLite转换script tflite_convert
。我可以在不进行量化的情况下进行转换,但是我需要更高的性能,因此需要进行量化。
如果我运行此脚本:
tflite_convert --output_file=model_quant.tflite \
--keras_model_file=model.h5 \
--inference_type=QUANTIZED_UINT8 \
--input_arrays=input_1 \
--output_arrays=predictions/Softmax \
--mean_values=128 \
--std_dev_values=127 \
--input_shape="1,224,224,3"
失败:
F tensorflow / contrib / lite / toco / tooling_util.cc:1634]数组 conv1_relu / Relu6,它是DepthwiseConv运算符的输入 产生输出数组conv_dw_1_relu / Relu6,缺少最小/最大 数据,这是量化所必需的。如果准确性很重要,则可以 定位非量化的输出格式,或使用 您的模型从浮点检查点更改输入图 包含最小/最大信息。如果您不在乎准确性,那您 可以轻松传递--default_ranges_min =和--default_ranges_max = 实验。\ n已中止(转储核心)\ n“
如果我使用default_ranges_min
和default_ranges_max
(称为“虚拟量化”),则它可以工作,但是它仅用于调试性能而没有准确性,如错误日志中所述。
那么我需要做些什么才能使Keras模型正确量化?我是否需要找到最佳的default_ranges_min
和default_ranges_max
?怎么样?还是关于Keras训练阶段的变化?
库版本:
Python 3.6.4
TensorFlow 1.12.0
Keras 2.2.4
答案 0 :(得分:1)
不幸的是,Tensorflow还没有提供用于平面缓冲区(tflite)中的每层量化后训练的工具,而仅提供了protobuf。现在唯一可用的方法是在图形中引入fakeQuantization层,然后在训练或校准集中重新训练/微调模型。这称为“ Quantization-aware training”。
一旦引入了fakeQuant层,您就可以输入训练集,并且TF将在前馈上将它们用作模拟量化层(代表8位值的fp-32数据类型),并使用完全反向传播精度值。这样,您可以找回量化带来的精度损失。
此外,fakeQuant层将通过移动平均值捕获每层或每个通道的范围,并将它们存储在最小/最大变量中。
稍后,您可以提取图形定义,并通过freeze_graph
工具摆脱fakeQuant节点。
最后,可以将模型输入tf_lite_converter(不会刹车的交叉手指)中,并提取捕获范围的u8_tflite。
Google在这里提供了一张很好的白皮书,解释了所有这些内容:https://arxiv.org/pdf/1806.08342.pdf
希望有帮助。