• Quantization模型转换

    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 对模型的识别精度还是有影响的。在边缘设备上资源有限,需要在模型大小、运行速度与识别精度上找到一个权衡。