上回记录了mobilenet ssd v2模型的压缩和转换过程,还留了一个尾巴,那就是模型的量化。这应该也是一个可以深入的问题,毕竟我在查阅资料的时候看到了什么量化、伪量化,whatever。具体的概念和原理不在此赘述(其实就是我也还没研究过。。。),本着工程实用优先的原则,先记录一下量化流程吧,毕竟业务部门只关心能不能上线以及何时上线
书接上文,MobileNet SSD V2模型的压缩与tflite格式的转换 - ,因为是tflite模型的量化,所以上文的流程还是需要走一遍的,只是几个地方需要调整一下。
修改配置文件
这次我们需要用到的就是图中的最后一个文件,经过对比,量化模型的配置文件与非量化的区别就在于多了如下几行:
graph_rewriter {
quantization {
delay: 48000
weight_bits: 8
activation_bits: 8
}
}
所以如果你不想下载新的文件,在之前的配置文件末尾加上这一部分就可以了。
训练模型
和配置文件类似,加载预训练模型有对应的量化版可以选择,然后就和上文一样训练,一样导出。
~~~~~~~~~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~~~
到此为止,得到了训练产生的ckpt以及导出的pb文件。
tflite量化
接下来进入模型量化的核心部分,
第一步,将ckpt转成pb文件,使用的是python export_tflite_ssd_graph.py,会得到tflite_graph.pb和tflite_graph.pbtxt两个文件,这里与之前是相同的;
第二步,将pb转为tflite文件,依旧是进入到tensorflow/contrib/lite/python目录,运行python tflite_convert.py,然而这一次,除了上次设置的参数:
--graph_def_file=XXX/tflite_graph.pb 上一步生成的pb文件地址
--output_file=XXX/xxx.tflite 输出的tflite文件地址
--input_arrays=normalized_input_image_tensor 输入输出的数组名称对于mobilenet ssd是固定的,不用改
--output_arrays='TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3'
--input_shape=1,XXX,XXX,3 输入的图片大小,需要与配置文件中一致
--allow_custom_ops
还有几个参数需要注意一下:
--inference_type=QUANTIZED_UINT8 默认是FLOAT,量化时需要改为QUANTIZED_UINT8
--mean_values=128
--std_dev_values=128
对于均值和标准差的设置,我找到了一个来自stackoverflow的计算方法:
mean_value = the uint8 value in the range [0, 255] that corresponds to floating point 0.0. So if the float range is [0.0, 1.0], then mean_value = 0.
std_value = (uint8_max - uint8_min) / (float_max - float_min). So if the float range is [0.0, 1.0], then std_value = 255 / 1.0 = 255.
(我试了0,255和128,128这两组,直观感受128,128效果更好,网上也有人实测其他组合效果更加,因此大家还是自己去调参吧)
经过这么一通操作,最后生成的tflite模型仅400+K,精度损失肯定是有的,但我还没有具体去测。
参考
https://blog.csdn.net/qq_26535271/article/details/84930868
Tensorflow Lite toco --mean_values --std_values? - Stack Overflow