第二部分伪量化训练在这里:
https://blog.csdn.net/angela_12/article/details/85000072#commentsedit
(参照社区问题中Zongjun大神的回答)
“如果是在android 上,Tensorflow Lite (tflite) 可以利用hardware accelerator,应该是更快的。量化只是一个float32到uint8的过程,本质上是weights\bias大小的变化(是原来的25%),有的microcontroller太小,不量化根本就放不进去,并且mircocontroller大部分是8bit计算,float32非常昂贵,所以需要量化。”
本博客时间有延迟,现在谷歌删掉了以前在tensorflow/tools/quantization文件夹里的的quantize_graph.py工具,所以以前的工具不能用了(也可以去网上找到那部分下载看看)
之前用量化工具做量化的时候是2018年7月19号,时间有点久远,但因为之前做过了现在想整理一下所以还是写出来记录一下~
我目前没有环境,所以就没法验证,先写着,等过段时间试试有没有问题,不过应该没啥问题,哈哈。
1.源码安装TensorFlow(简称TF)及相关库:
git clone https://github.com/tensorflow/tensorflow
参考源码安装博客
注: TF最好安装在虚拟环境里,这个可以找下如何在Linux里安装虚拟环境virtualenv,然后使用的时候先进入虚拟环境中,TF激活virtualenv:
source bin/activate
进入会出现虚拟环境名:(tensorflow)$
退出环境:
(tensorflow)$ deactivate
2.编译:
1)进入tensorflow根目录:
cd tensorflow
2)下载安装bazel编译工具:
bazel官网安装方法,jdk不低于1.8,也是源码安装
可参考:TensorFlow Lite模型生成以及bazel的安装使用
2019.3.27更新: bazel环境重新搭了一遍,感觉不用那么麻烦,这次没有源码安装也可以使用tensorflow的指令,方法就是进入官网,按照官网推荐的二进制安装方法操作,一共四步,按顺序操作即可:
1.第三步的时候注意看好文件名称,将指令内的.sh文件替换成下载的文件名,且两句话分别执行。
3)运行configure:
./configure (出来是下图的样子)
3.编译TF/pip安装包:
CPU:
sudo bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package
GPU:
sudo bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
生成pip安装包,.whl文件:
mkdir -p /tmp/tensorflow/
sudo bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
查看/tmp/tensorflow_pkg这个文件夹,会出现.whl文件,把下面的文件替换成自己的,然后安装:
sudo pip3 install tensorflow-1.3.0rc1-cp27-cp27mu-linux_x86_64.whl
最后,进入Python环境,查看是否安装成功:
import tensorflow
不报错TF就安装成功了。
如果这种方法在build_pip_package这步不可行的话,可以试试直接
pip install tensorflow
我当时实在编译不出whl文件,就pip了,结果pip的过程中自动安装了whl,然后就能用工具了,后面也没问题,所以可以试试,如果再出问题再解决吧~
4.开始量化,编译quantize_graph工具:
sudo bazel build tensorflow/tools/quantization:quantize_graph
5.压缩.pb,以谷歌GoogLeNet 为例:
下载模型:
curl http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz -o /tmp/inceptionv3.tgz
解压(我用的):
tar xzf /tmp/inceptionv3.tgz -C /tmp/
或者(两者位置不同,可以自己试试):
tar xzf /tmp/inceptionv3.tgz
6.压缩:
sudo bazel-bin/tensorflow/tools/quantization/quantize_graph \
--input=/tmp/classify_image_graph_def.pb \
--output_node_names="softmax" \
--output=/tmp/quantized_graph.pb \
--mode=eightbit
压缩后,到保存模型的文件夹下,用ls -lh查看模型大小,可以看到,原模型92M,压缩后变为24M。
7.测试:
回到tensorflow根目录,编译label _image代码:
sudo bazel build tensorflow/examples/label_image:label_image
测试量化前的模型:
sudo bazel-bin/tensorflow/examples/label_image/label_image \
--graph=/tmp/classify_image_graph_def.pb \
--input_width=299 \
--input_height=299 \
--input_mean=128 \
--input_std=128 \
--input_layer="Mul:0" \
--output_layer="softmax:0" \
--labels="/tmp/imagenet_synset_to_human_label_map.txt" \
--image="/tmp/cropped_panda.jpg"
测试量化后的模型:
sudo bazel-bin/tensorflow/examples/label_image/label_image \
--graph=/tmp/quantized_graph.pb \
--input_width=299 \
--input_height=299 \
--input_mean=128 \
--input_std=128 \
--input_layer="Mul:0" \
--output_layer="softmax:0" \
--labels="/tmp/imagenet_synset_to_human_label_map.txt" \
--image="/tmp/cropped_panda.jpg"
测试结果准确率基本差不多,是可以用的。
(这部分要看图片的话,可以参考这篇博客。)
1)这种方法感觉只适合量化已有网络的pb文件,就是官方给出的那些,里面自己就带有最大最小值的,不然应该是要自己添加量化节点进去统计最大最小值,添加据说有API可以,等我有时间再找找。
不过现在谷歌删除了这个方法,以后就用伪量化训练吧,简单省力(可参考我的第一篇博客,也就是此篇的(2))。
2)查看上面指令中的相关信息可以用以下指令:
编译:
bazel build tensorflow/tools/graph_transforms:summarize_graph
执行:
sudo bazel-bin/tensorflow/tools/graph_transforms/summarize_graph --in_graph=/tmp/classify_image_graph_def.pb --print_structure=true
8.转化为tflite:
1)先编译frozen工具:
bazel build tensorflow/python/tools:freeze_graph
把生成的pbtxt和ckpt文件固化,生成pb:
bazel-bin/tensorflow/python/tools/freeze_graph \
--input_graph=/home/.../tensorflow/tensorflow/.../mnist.pbtxt \
--input_checkpoint=/home/.../tensorflow/tensorflow/../mnist.ckpt \
--output_graph=/home/../tensorflow/tensorflow/../forzon_mnist_fakequantize.pb \
--output_node_names=output
如果你的代码写的是:
tf.train.write_graph(sess.graph_def,'','graph.pb',as_text=False)
这种直接保存了图模型,但没有图中变量的值,所以需要固化。
但如果是这种:
graph = convert_variables_to_constants(sess, sess.graph_def, ["output_image"])
tf.train.write_graph(graph, '.', 'graph.pb', as_text=False)
这样就不用固化,可以直接用生成的pb文件。
“因为这个是将模型里面的所有变量都变为常量,就可以直接使用.pb文件做成接口,无需.ckpt文件再次导入变量的值。”
2)然后,转化tflite:
编译:
bazel build tensorflow/contrib/lite/toco:toco
运行:
bazel-bin/tensorflow/contrib/lite/toco/toco \
--input_file=/home/.../tensorflow/.../Mnist_train/speech_my_frozen_graph.pb \
--output_file=/home/.../tensorflow/.../Mnist_train/speech_my_frozen_graph.tflite \
--input_format=TENSORFLOW_GRAPHDEF \
--output_format=TFLITE \
--inference_type=QUANTIZED_UINT8 \
--input_shapes=1,98,40,1 \
--input_arrays=Reshape_1 \
--output_arrays=labels_softmax \
--allow_custom_ops
1.tensorflow模型量化:https://blog.csdn.net/u011961856/article/details/76736103
2.源码安装tensorflow:https://blog.csdn.net/u011961856/article/details/76725411
3.tensorflow Quantize(量化):https://blog.csdn.net/xueyingxue001/article/details/72726421
4.1)Bazel教程:http://www.360doc.com/content/17/0601/16/10408243_659039083.shtml
2)Bazel官网:https://docs.bazel.build/versions/master/install.html
5.固化部分,保存pb的代码,参考:
https://blog.csdn.net/qq_16564093/article/details/78996563
这个工具网上博客讲解的可以,我就稍微总结一下,因为现在也不怎么用了,看图就用Netron了。
1)安装pip install tensorboard
2)写.py文件,然后运行,生成logs文件夹:
在这里插入代码片
3)tensorboard --logdir logdir (保存的目录名),启动并生成图的链接,复制在浏览器打开,保持运行状态
这个是大神推荐的,我觉得很好很方便,链接:https://www.lutzroeder.com/ai/
里面的Demo点进去,可以在线直接查看,只要把自己的文件拖进去就好了,点击图中节点就会在后侧显示相关信息,还有文档可以查看,在节点名字旁的“?”里。
源码和使用介绍在这里。