Quantization模型转换

提示

Quantized模型是对原模型进行转换过程中,将float参数转化为uint8类型,进而产生的模型会更小、运行更快,但是精度会有所下降。

前面我们介绍了Float 模型的转换方法,接下来我们要展示下 Quantized 模型,在TF1.0上,可以使用命令行工具转换 Quantized模型。在笔者尝试的情况看在TF2.0上,命令行工具目前只能转换为Float 模型,Python API只能转换为 Quantized 模型。

Python API转换方法如下:

  1. import tensorflow as tf
  2.  
  3. converter = tf.lite.TFLiteConverter.from_saved_model('saved/1')
  4. converter.optimizations = [tf.lite.Optimize.DEFAULT]
  5. tflite_quant_model = converter.convert()
  6. open("mnist_savedmodel_quantized.tflite", "wb").write(tflite_quant_model)

最终转换后的 Quantized模型即为同级目录下的 mnist_savedmodel_quantized.tflite

相对TF1.0,上面的方法简化了很多,不需要考虑各种各样的参数,谷歌一直在优化开发者的使用体验。

在TF1.0上,我们可以使用 tflite_convert 获得模型具体结构,然后通过graphviz转换为pdf或png等方便查看。在TF2.0上,提供了新的一步到位的工具 visualize.py ,直接转换为html文件,除了模型结构,还有更清晰的关键信息总结。

提示

visualize.py 目前看应该还是开发阶段,使用前需要先从github下载最新的 TensorFlowFlatBuffers 源码,并且两者要在同一目录,因为 visualize.py 源码中是按两者在同一目录写的调用路径。

下载 TensorFlow:

  1. git clone [email protected]:tensorflow/tensorflow.git

下载 FlatBuffers:

  1. git clone [email protected]:google/flatbuffers.git

编译 FlatBuffers:(笔者使用的Mac,其他平台请大家自行配置,应该不麻烦)

  • 下载cmake:执行 brew install cmake

  • 设置编译环境:在 FlatBuffers 的根目录,执行 cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release

  • 编译:在 FlatBuffers 的根目录,执行 make

编译完成后,会在跟目录生成 flatc,这个可执行文件是 visualize.py 运行所依赖的。

visualize.py使用方法

在tensorflow/tensorflow/lite/tools目录下,执行如下命令

  1. python visualize.py mnist_savedmodel_quantized.tflite mnist_savedmodel_quantized.html

生成可视化报告的关键信息

../../_images/visualize1.png

模型结构

../../_images/visualize2.png

可见,Input/Output格式都是 FLOAT32 的多维数组,Input的min和max分别是0.0和255.0。

跟Float模型对比,Input/Output格式是一致的,所以可以复用Float模型Android部署过程中的配置。

提示

暂不确定这里是否是TF2.0上的优化,如果是这样的话,对开发者来说是非常友好的,如此就归一化了Float和Quantized模型处理了。

具体配置如下:

  1. // Quantized模型相关参数
  2. // com/dpthinker/mnistclassifier/model/QuantSavedModelConfig.java
  3. public class QuantSavedModelConfig extends BaseModelConfig {
  4. @Override
  5. protected void setConfigs() {
  6. setModelName("mnist_savedmodel_quantized.tflite");
  7.  
  8. setNumBytesPerChannel(4);
  9.  
  10. setDimBatchSize(1);
  11. setDimPixelSize(1);
  12.  
  13. setDimImgWeight(28);
  14. setDimImgHeight(28);
  15.  
  16. setImageMean(0);
  17. setImageSTD(255.0f);
  18. }
  19.  
  20. @Override
  21. public void addImgValue(ByteBuffer imgData, int val) {
  22. imgData.putFloat(((val & 0xFF) - getImageMean()) / getImageSTD());
  23. }
  24. }

运行效果如下:

../../_images/quantized.png

Float模型与 Quantized模型大小与性能对比:

可见, Quantized模型在模型大小和运行性能上相对Float模型都有非常大的提升。不过,在笔者试验的过程中,发现有些图片在Float模型上识别正确的,在 Quantized模型上会识别错,可见 Quantization 对模型的识别精度还是有影响的。在边缘设备上资源有限,需要在模型大小、运行速度与识别精度上找到一个权衡。