转pb文件
使用export_inference_graph.py(在object detection目录下)导出pb文件:
python export_inference_graph.py \ --input_type image_tensor \ --pipeline_config_path=ssd_mobilenet_v2_coco.config \ --trained_checkpoint_prefix=training//model.ckpt-30000 \ --output_directory models_trained/
测试pb模型:
import tensorflow as tf import cv2 import os import time import numpy as np from object_detection.utils import label_map_util from object_detection.utils import visualization_utils as vis_util videofile='/home/zyl/Documents/caffe/examples/MobileNet-SSD/videos/20180813140109903.avi' cap=cv2.VideoCapture(videofile) MODEL_NUM_CLASSES=3 MODEL_LABEL_MAP ='/home/zyl/data/dms_tf/label_map.pbtxt' MODEL_PB='/home/zyl/data/dms_tf/model2/export_result/frozen_inference_graph.pb' # read graph model with tf.gfile.GFile(MODEL_PB,'rb') as fd: _graph=tf.GraphDef() _graph.ParseFromString(fd.read()) tf.import_graph_def(_graph,name='') # get the default graph model detection_graph=tf.get_default_graph() # read labelmap label_map=label_map_util.load_labelmap(MODEL_LABEL_MAP) categories=label_map_util.convert_label_map_to_categories(label_map,MODEL_NUM_CLASSES) category_index=label_map_util.create_category_index(categories) with tf.Session(graph=detection_graph) as sess: while(cap.isOpened()): ret,frame=cap.read() frame_np_expanded=np.expand_dims(frame,axis=0) image_tensor = detection_graph.get_tensor_by_name('image_tensor:0') boxes = detection_graph.get_tensor_by_name('detection_boxes:0') scores = detection_graph.get_tensor_by_name('detection_scores:0') classes = detection_graph.get_tensor_by_name('detection_classes:0') num_detections = detection_graph.get_tensor_by_name('num_detections:0') t1=time.time() (boxes,scores,classes,num_detections)=sess.run([boxes,scores,classes,num_detections], \ feed_dict={image_tensor:frame_np_expanded}) vis_util.visualize_boxes_and_labels_on_image_array(frame,np.squeeze(boxes), np.squeeze(classes).astype(np.int32),np.squeeze(scores),category_index, use_normalized_coordinates=True,line_thickness=6) t2=time.time() print('FPS:',1/(t2-t1)) cv2.imshow('MobilenetTF',frame) if cv2.waitKey(1)&0xff ==27: break cap.release()
转tflite文件
因为要使用toco,这里我们需要从源码中编译tensorflow库,新建Python环境,并激活环境,基操不再累赘
安装bazel
首先安装依赖包:
sudo apt-get install pkg-config zip g++ zlib1g-dev unzip
然后下载bazel二进制文件:这里以bazel-0.15.0-installer-linux-x86_64.sh为例说明
修改权限并安装:
chmod +x bazel-0.15.0-installer-linux-x86_64.sh ./bazel-0.15.0-installer-linux-x86_64.sh --user
–user 选项会将bazel安装在$HOME/bin目录下, 显示如下,表示安装成功
设置环境变量
vim ~/.bashrc
在末尾添加
export PATH="$PATH:$HOME/bin"
下载TensorFlow源码并配置构建
mkdir C:\tensorflow-build cd C:\tensorflow-build git clone https://github.com/tensorflow/tensorflow.git cd tensorflow git checkout r1.13 # 签出TensorFlow v1.13的分支
接下来,我们将使用configure.py脚本配置TensorFlow构建
python ./configure.py
接下来,配置系统会给出各种询问,以确认编译时的配置参数,下面挑选比较重要的几个参数解释如下(有默认值的直接回车,Y/n的直接选择n,我是这样做的):
yhilly@ubuntu:~/tensorflow$ ./configure You have bazel 0.9.0 installed. Please specify the location of python. [Default is /home/yhilly/anaconda3/envs/tensorflow/bin/python]:
上面的提示是Bazel让我们选择Python的安装路径,只要确保是Anaconda的Python路径即可,直接按一系列的回车键(Enter)表示使用默认值
Do you wish to build TensorFlow with jemalloc as malloc support? [Y/n]: jemalloc as malloc support will be enabled for TensorFlow.
上面的选项表示是否使用jemalloc代替传统的malloc来管理内存?Jemalloc是杰森·埃文斯(Jason Evans)于2006年开发的用以取代传统低性能的malloc内存管理模块而开发的一款内存管理模块[4]。埃文斯并非等闲之辈,他是FreeBSD项目(一种类UNIX操作系统)的重要维护者之一
Jemalloc先被Firefox浏览器采用,后来又被Facebook在其自己的各类应用上广泛使用,一战成名。好技术当然要用!直接按回车,确认默认值Y(默认值通常就是被大写的选项)
Do you wish to build TensorFlow with Google Cloud Platform support? [Y/n]: n No Google Cloud Platform support will be enabled for TensorFlow.
这个选项是询问是否采用Google云平台来支持TensorFlow。这个云平台国内通常无法访问,建议输入“n”。有条件的读者,可直接按回车确认使用
Do you wish to build TensorFlow with Hadoop File System support? [Y/n]: n No Hadoop File System support will be enabled for TensorFlow.
这个选项是询问是否使用Hadoop 文件系统(HDFS)来支持TensorFlow。如果搭建了Hadoop集群,有读取HDFS数据需求的用户,可以回车确认。如果没有需求,手动输入“n”
Do you wish to build TensorFlow with XLA JIT support? [y/N]: n No XLA JIT support will be enabled for TensorFlow.
这个选项是询问是否开启XLA JIT编译支持。XLA(Accelerated Linear Algebra/加速线性代数)目前还是TensorFlow的实验项目,XLA 使用 JIT(Just in Time,即时编译)技术来分析用户在运行时(runtime)创建的 TensorFlow 图,专门用于实际运行时的维度和类型。作为新技术,这项编译技术还不成熟,爱折腾的可以选y
Do you wish to build TensorFlow with CUDA support? [y/N]: No CUDA support will be enabled for TensorFlow.
这个选项是询问是否使用CUDA。CUDA是一种由NVIDIA推出的通用并行计算架构,该架构使GPU能够解决复杂的计算问题。如果用户配备有NVIDIA的GPU,可以选择“y”,如果仅使用TensorFlow的CPU版本,回车确认“N” (这里只是为了使用toco转换模型,为了节省时间,选择N)
编译源文件
在配置完毕Bazel的编译选项之后,接下来就可以使用如下指令编译TensorFlow的源代码:
bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package
如果想获得GPU支持,则需要加入编译选项“–config=cuda”
bazel build --config=opt --config=cuda --define=no_tensorflow_py_deps=true //tensorflow/tools/pip_package:build_pip_package
现在已经创建了包构建器,让我们使用它来构建实际的TensorFlow wheel文件
bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/tensorflow_pkg
下面我们要做的工作就是,利用pip来安装我们亲手编译的TensorFlow二进制文件
pip install ~/tensorflow_pkg/<Paste full .whl filename here>.whl
让我们通过打开Python shell来确保正确安装:
python
打开Python后,发出以下命令:
>>> import tensorflow as tf >>> tf.__version__
如果一切都已正确安装,它将以已安装的TensorFlow版本响应
生成TF Lite模型
前面frozen的pb模型直接转换会报错,需使用export_tflite_ssd_graph.py进行优化后再转换。将object_detection/export_tflite_ssd_graph.py拷贝到训练目录,运行:
python export_tflite_ssd_graph.py \ --pipeline_config_path=ssd_mobilenet_v2_coco.config \ --trained_checkpoint_prefix=models_trained/model.ckpt-30000\ --output_directory=models
生成冻结后的模型,再转换为对应的TF Lite模型,包括float类型的(模型更大,更准确)和量化后uint8类型的模型(模型更小,但准确率不高)
float32型:
bazel-bin/tensorflow/lite/toco/toco \ --input_file=/home/zyl/Documents/tfmodels/dms/models/tflite_graph.pb \ --input_format=TENSORFLOW_GRAPHDEF \ --output_format=TFLITE \ --output_file=/home/zyl/Documents/tfmodels/dms/models/litefloat_zyl.tflite \ --inference_type=FLOAT \ --input_arrays=normalized_input_image_tensor \ --output_arrays='TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3' \ --input_shapes=1,300,300,3 \ --mean_values=128 \ --std_dev_values=128 \ --default_ranges_min=0 \ --allow_custom_ops
uint8量化:
bazel-bin/tensorflow/lite/toco/toco \ --graph_def_file=/home/zyl/data/dms_tf/model1/tflite_graph.pb \ --output_file=/home/zyl/data/dms_tf/model1/tflite_model/model1.tflite \ --input_shapes=1,300,300,3 \ --input_arrays=normalized_input_image_tensor \ --output_arrays='TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3' \ --inference_type=QUANTIZED_UINT8 \ --mean_values=128 \ --std_dev_values=128 \ --default_ranges_min=0 \ --default_ranges_max=6 \ --change_concat_input_ranges=False \ --allow_custom_ops
调用TensorFlow Lite模型
wget https://raw.githubusercontent.com/EdjeElectronics/TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi/master/TFLite_detection_image.py --no-check-certificate wget https://raw.githubusercontent.com/EdjeElectronics/TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi/master/TFLite_detection_video.py --no-check-certificate wget https://raw.githubusercontent.com/EdjeElectronics/TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi/master/TFLite_detection_webcam.py --no-check-certificate
使用这三个脚本可以实现不同场景的调用
有关在运行脚本的使用的-h选项的更多信息,请在调用脚本时使用该选项。例:
python TFLite_detection_image.py -h