v2-f6559ccf4b15ef36669e14ddf6718f04_1440w.jpg?source=172ae18b

2019.12.24—quantization-aware training

环境:tensorflow1.15+ubuntu16.04+cuda10.0

参考网址:

https://github.com/tensorflow/tensorflow/tree/r1.13/tensorflow/contrib/quantize​github.com

参考博客:

CSDN-专业IT技术社区-登录​blog.csdn.net CSDN-专业IT技术社区-登录​blog.csdn.net

参考知乎:

芯尚刃:Tensorflow模型量化(Quantization)原理及其实现方法​zhuanlan.zhihu.com
lonlon ago:TensorFlow 保存模型为 PB 文件​zhuanlan.zhihu.com
v2-727dd6b2b3a703d061cb83397a026bdb_ipico.jpg

一、知识储备

1.ckpt模型:tensorflow代码训练完后,得到4个文件

v2-89fa3e057eff0348e8a4c516cf7f8791_b.jpg

v2-c0b69450829e0bbb9ac46b4f818a9cb2_b.jpg
四个文件的内容

2.ckpt转pb

2.1原因:

ckpt 格式的模型文件有几个缺点,首先这种模型文件是依赖 TensorFlow 的,只能在其框架下使用;其次,在恢复模型之前还需要再定义一遍网络结构,然后才能把变量的值恢复到网络中。

PB 格式,它具有语言独立性,可独立运行,封闭的序列化格式,任何语言都可以解析它,它允许其他语言和深度学习框架读取、继续训练和迁移。

2.2过程:

1.通过传入 CKPT 模型的路径得到模型的图和变量数据

2.通过 import_meta_graph 导入模型中的图

3.通过 saver.restore 从模型中恢复图中各个变量的数据

4.通过 graph_util.convert_variables_to_constants 将模型持久化

3.两种量化方式对比

v2-182465627230b23ffeb3249dec9eb90f_b.jpg

二、实验过程

第一步:先看了一下官网给的教程,总体来说分为两部分,感觉官网给的教程比较粗糙,大概步骤如下:

1.1:在训练时添加如下代码(在训练图结构内添加伪量化节点):

v2-02f04032ac06bba667141665e441b339_b.jpg

1.2:在评估时添加如下代码(重写推理图结构并保存为新的模型):

v2-2f04d34e903e61a7b0b870880b8d5263_b.jpg

第二步:我又找了具体实现在线量化的例子,大多是针对经典数据集(minist,cifar,imagenet)分类模型的量化,于是我想着先把分类模型量化过一遍,看一下这个方法的可行性:

2020.1.06--TensorFlow-Slim image classification model library实践

参考网址:https://github.com/tensorflow/models/tree/master/research/slim

v2-1804b10cd671524755182f141592acf3_b.jpg

按照教程,选择的是cifar10数据集,生成tfrecord文件后利用mobilenet_v1进行训练和测试

v2-0c10c906f5a1e66fdef811bb14af0c95_b.jpg

具体代码:

  1. 训练参考(我将数据集更换为cifar10)https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet_v1_train.py
  2. 评估参考:https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet_v1_eval.py

但是没有得到frozen_eval_graph.pb,应该是少了其他代码,和之前预想的有点不大一样。

于是又参考以下网址,是针对minst数据集分类模型的一个在线量化,教程比较靠谱,实现了模型的量化感知训练。

参考网址:https://www.cnblogs.com/jiangxinyang/p/12056209.html

v2-c10d510f527119f94d62aa54559da2f1_b.jpg

上图代码主要功能是将在训练时添加伪量化节点后的到的ckpt文件进行重写推理图转为pb文件,也是量化感知训练的关键步骤。

第三步:也是最困难的步骤,就是针对我自己的检测模型做在线量化,感觉tensorflow object detection API中的代码集成性很高,具体在哪个部分加入代码,就比较困难,如何把分类中的方法迁移过来,又是一大难点。

3.1 在trainer.py中加入如下代码:

v2-1a60d0b4cd9bf00c72928021481aef6a_b.jpg

训练时没有报错,得到ckpt文件,得到的ckpt文件和以前训练得到的模型的区别如下:

v2-e11fe8dbc00adce85354204e2e0ad4ac_b.jpg

3.2 接下来,我在evaluator.py加入如下代码:

v2-fd4b5b4e24da6dd4784360a958d5e1c4_b.jpg

得到.pb模型。

主要疑问在output_node_names:我选取mobilenetv2的最后一层,具体怎么选取不太确定。

v2-4b4a86ba439ccc2269324a8a48336eb1_b.jpg

疑问:正常来说这两个模型大小的区别是这样吗?

解析pb模型对比:

v2-81e6dfc6af16abe7a193c15443d8afba_b.jpg

整体量化流程:

v2-3d8f8e52af31fb693c71159c42a2a92a_b.jpg

伪量化含义理解:

伪量化是完全量化的第一步,它只是模拟了量化的过程,并没有实现量化,只是在训练过程中添加了伪量化节点(创建训练图推理图分别添加进去),计算过程还是用float32计算。

然后训练得出.pb文件,放到toco指令里(或者调用tf.lite.TFLiteConverter库函数)去实现第二步完整的量化,最后生成tflite,得到int8模型。

后续继续改进ing

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐