参考了博客,是一个口罩的识别。
在用标注工具标注自己的数据集后,转换数据集格式,voc的XML格式转换csv格式,csv再转成tensorflow所需要的标签和图片合体的record格式。
XML-CSV 网盘 vln2
CSV-record 源码中就给了,在参考博客中也给出了。
在准备好自己的数据集后,就可以开始配置tensorflow环境了,这个比较麻烦,我是在conda虚拟环境中配置的tensorflow-gpu,版本是1.15,

# your_name为自命名虚拟环境名
conda create -n your_name python=X.X(如2.7,3.6等)

激活你的虚拟环境,执行后就会在终端前有环境名的标志

source activate your_name

然后就可以在环境中 pip 安装所需要的包和依赖

退出虚拟环境

source deactivate

显示所创建的虚拟环境

conda env list

每次用的时候激活就行,防止依赖冲突

下载TensorFlow Models:,根据要求配置好环境后,再执行命令验证一下就行了
环境配置问题,网上基本都可以搜到答案

git clone https://github.com/tensorflow/models.git

然后开始修改config配置文件,我用的是 ssd_mobilenet_v2_coco.config,根据参考博客修改文件,注意:需要自身电脑的配置 修改下batch_size的大小,要不然会出现内存溢出的错误,电脑直接卡死。越小越流畅
修改后,开始训练,原本是用model_main.py训练,但不知是我配置环境的差异,我这个无法训练,于是改用老版的训练
在object_detection目录下,

python legacy/train.py --train_dir=/home/sdu/models/dataset/data/ --pipeline_config_path=/home/sdu/models/dataset/data/ssd_mobilenet_v2_coco.config --logtostderr

这时候训练还会出现问题,cudnn的问题,修改下train.py,加上下面的代码
这里是GPU请求内存的问题

from object_detection.utils import config_util
from tensorflow.compat.v1 import ConfigProto
from tensorflow.compat.v1 import InteractiveSession

config = ConfigProto()
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)

tf.logging.set_verbosity(tf.logging.INFO)

训练过程中,可以用tensorboard来看loss变换曲线,导出损失最小的训练模型
在object_detection目录下

tensorboard --logdir='/home/sdu/models/dataset/data/'

在训练结束后,处理下模型,导出并转换
参考转换模型博客 ,bazel编译源码,中间可能会遇到各种问题,多搜几篇博客看一下,基本上都能解决
大部分都需要configure一下,编译一下环境
最后用toco工具生成模型,有些参数可能会和参考的博客不同,可以用下面的看下网络节点,会返回所转换模型的各个参数,看是否需要修改

bazel build tensorflow/tools/graph_transforms:summarize_graph
bazel-bin/tensorflow/tools/graph_transforms/summarize_graph --in_graph=/home/sdu/models/dataset/data/frozen_graph.pb

这里有两种模型转换的方式,可以是整数型版本tflite模型,也可以是浮点型模型
整数

bazel run tensorflow/lite/toco:toco -- \

--input_file=$OUTPUT_DIR/tflite_graph.pb \

--output_file=$OUTPUT_DIR/detect.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_values=128 \

--change_concat_input_ranges=false \

--allow_custom_ops \

--default_ranges_min=0 \

--default_ranges_max=255 \

浮点

bazel run -c opt tensorflow/lite/toco:toco -- \

--input_file=$OUTPUT_DIR/tflite_graph.pb \

--output_file=$OUTPUT_DIR/float_detect.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=FLOAT \

—allow_custom_ops

生成模型的区别就是权重文件的大小,大约差个五六倍的大小,
移植到安卓端时 用float模型可能会出现
运行安卓项目报错:E/AndroidRuntime: FATAL EXCEPTION: inference
Process: org.tensorflow.lite.examples.detection, PID: 17660
java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite buffer with 1080000 bytes and a Java Buffer with 270000 bytes.

解决方法:将DetectorActivity.java的54行改成TF_OD_API_IS_QUANTIZED = false
这个问题就是float和quantized的一个切换,量化的精度不同,float的量化模型精度要更高一点,但文件会大一点