Tensorflow目标检测接口配合tflite量化模型(一)

本文涉及的产品
交互式建模 PAI-DSW,5000CU*H 3个月
简介: Tensorflow目标检测接口配合tflite量化模型

1. 部署环境:


在PC上安装CUDA10和对应cuDNN,网上教程很多,这里不再累赘, 推荐使用conda集成环境,1. 新建python环境,2. 安装tensorflow-gpu=1.13, TensorFlow对象检测API需要使用其GitHub存储库中提供的特定目录结构, 所以第三步:从GitHub下载TensorFlow对象检测API存储库(下载TF V1.13版本,这里要与我们Python tensorflow对应 wget


安装依赖


sudo apt-get install protobuf-compiler python-pil python-lxml python-tk
pip install --user Cython
pip install --user contextlib2
pip install --user jupyter
pip install --user matplotlib


安装 COCO API


下载 cocoapi ,然后复制 pycocotools 文件夹到 tensorflow/models/research 文件夹。默认使用基于 Pascal VOC 的评价指标; 如果你对使用 COCO 评价指标感兴趣:使用 COCO 目标检测(object detection)指标,请添加metrics_set: "coco_detection_metrics"到配置文件eval_config消息中;使用 COCO 实例分割(instance segmentation)指标,请添加metrics_set: "coco_mask_metrics"到配置文件eval_config消息中。


git clone https://github.com/cocodataset/cocoapi.git
cd cocoapi/PythonAPI
make
cp -r pycocotools <path_to_tensorflow>/models/research/


编译Protobuf和将库添加进 PYTHONPATH


Tensorflow Object Detection API 使用 Protobufs 来控制模型与训练参数。在使用框架之前,Protobuf 库必须被编译。这可以在 tensorflow/models/research/ 文件夹下运行命令:


./bin/protoc object_detection/protos/*.proto --python_out=.


当在本地运行时,tensorflow/models/research/ 和 slim 文件夹需要加入 PYTHONPATH 。这可以在 tensorflow/models/research/ 文件夹下运行下列命令来完成:


export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim


注意: 如果这里添加路径之后还提示找不到"nets"文件,可以直接复制slim文件到research目录下


测试是否成功


python object_detection/builders/model_builder_test.py


返回OK则OK


2. 制作数据集


使用label-image标注工具对样本进行标注,得到VOC格式数据。将所有的图片放入images/文件夹,标注得到的xml文件保存到merged_xml/文件夹内,并新建文件夹Annotations/


20200420155754602.png


训练集划分与配置文件修改


新建train_test_split.py把xml数据集分为了train 、test、 validation三部分,并存储在Annotations文件夹中,train为训练集占76.5%,test为测试集10%,validation为验证集13.5%,train_test_split.py代码如下:


import os  
import random  
import time  
import shutil  
xmlfilepath = r'merged_xml'  
saveBasePath = r"./Annotations"  
trainval_percent = 0.9  
train_percent = 0.85  
total_xml = os.listdir(xmlfilepath)  
num = len(total_xml)  
list = range(num)  
tv = int(num*trainval_percent)  
tr = int(tv*train_percent)  
trainval = random.sample(list,tv)  
train = random.sample(trainval,tr)  
print("train and val size",tv)  
print("train size",tr)   
start = time.time()   
test_num = 0  
val_num = 0  
train_num = 0  
for i  in list:  
    name = total_xml[i]  
    if i in trainval:  # train and val set  
        if i in train:  
            directory = "train"  
            train_num += 1  
            xml_path = os.path.join(os.getcwd(), 'Annotations/{}'.format(directory))  
            if(not os.path.exists(xml_path)):  
                os.mkdir(xml_path)  
            filePath = os.path.join(xmlfilepath,name)  
            newfile = os.path.join(saveBasePath,os.path.join(directory,name))  
            shutil.copyfile(filePath, newfile)  
        else:  
            directory = "validation"  
            xml_path = os.path.join(os.getcwd(), 'Annotations/{}'.format(directory))  
            if(not os.path.exists(xml_path)):  
                os.mkdir(xml_path)  
            val_num += 1  
            filePath = os.path.join(xmlfilepath,name)   
            newfile = os.path.join(saveBasePath,os.path.join(directory,name))  
            shutil.copyfile(filePath, newfile)  
    else: 
        directory = "test"  
        xml_path = os.path.join(os.getcwd(), 'Annotations/{}'.format(directory))  
        if(not os.path.exists(xml_path)):  
            os.mkdir(xml_path)  
        test_num += 1  
        filePath = os.path.join(xmlfilepath,name)  
        newfile = os.path.join(saveBasePath,os.path.join(directory,name))  
        shutil.copyfile(filePath, newfile)  
end = time.time()  
seconds = end - start  
print("train total : " + str(train_num))  
print("validation total : " + str(val_num))  
print("test total : " + str(test_num))  
total_num = train_num + val_num + test_num  
print("total number : " + str(total_num))  
print( "Time taken : {0} seconds".format(seconds))


xml文件转换为csv文件


新建csvdata/目录存放生成的csv文件,代码如下:


import os  
import glob  
import pandas as pd  
import xml.etree.ElementTree as ET  
def xml_to_csv(path):  
    xml_list = []  
    for xml_file in glob.glob(path + '/*.xml'):  
        tree = ET.parse(xml_file)  
        root = tree.getroot()   
        print(root.find('filename').text)  
        for member in root.findall('object'):  
            value = (root.find('filename').text,  
                     int(root.find('size')[0].text),   #width  
                     int(root.find('size')[1].text),   #height  
                     member[0].text,  
                     int(member[4][0].text),  
                     int(float(member[4][1].text)),  
                     int(member[4][2].text),  
                     int(member[4][3].text)  
                     )  
            xml_list.append(value)  
    column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']  
    xml_df = pd.DataFrame(xml_list, columns=column_name)  
    return xml_df  
def main():  
    for directory in ['train', 'test', 'validation']:  
        xml_path = os.path.join(os.getcwd(), 'Annotations/{}'.format(directory))  
        xml_df = xml_to_csv(xml_path)  
        xml_df.to_csv('csvdata/tf_{}.csv'.format(directory), index=None)  
        print('Successfully converted xml to csv.')  
main()


在csvdata/文件夹下生成训练、验证和测试的csv格式文件:


2020042016062336 (1).png


csv格式数据生成tf record格式数据


建generate_tfrecord.py脚本,并新建tfdata/文件夹,代码如下:


from __future__ import division
from __future__ import print_function
from __future__ import absolute_import
import os
import io
import pandas as pd
import tensorflow as tf
from PIL import Image
from object_detection.utils import dataset_util
from object_detection.utils import label_map_util
from collections import namedtuple
flags = tf.app.flags
flags.DEFINE_string('csv_input', '', 'Path to the CSV input')
flags.DEFINE_string('images_input', '', 'Path to the images input')
flags.DEFINE_string('output_path', '', 'Path to output TFRecord')
flags.DEFINE_string('label_map_path', '', 'Path to label map proto')
FLAGS = flags.FLAGS
def split(df, group):
    data = namedtuple('data', ['filename', 'object'])
    gb = df.groupby(group)
    return [data(filename, gb.get_group(x)) for filename, x in 
            zip(gb.groups.keys(), gb.groups)]
def create_tf_example(group, label_map_dict, images_path):
    with tf.gfile.GFile(os.path.join(
        images_path, '{}'.format(group.filename)), 'rb') as fid:
        encoded_jpg = fid.read()
    encoded_jpg_io = io.BytesIO(encoded_jpg)
    image = Image.open(encoded_jpg_io)
    width, height = image.size
    filename = group.filename.encode('utf8')
    image_format = b'jpg'
    xmins = []
    xmaxs = []
    ymins = []
    ymaxs = []
    classes_text = []
    classes = []
    for index, row in group.object.iterrows():
        xmins.append(row['xmin'] / width)
        xmaxs.append(row['xmax'] / width)
        ymins.append(row['ymin'] / height)
        ymaxs.append(row['ymax'] / height)
        classes_text.append(row['class'].encode('utf8'))
        classes.append(label_map_dict[row['class']])
    tf_example = tf.train.Example(features=tf.train.Features(feature={
        'image/height': dataset_util.int64_feature(height),
        'image/width': dataset_util.int64_feature(width),
        'image/filename': dataset_util.bytes_feature(filename),
        'image/source_id': dataset_util.bytes_feature(filename),
        'image/encoded': dataset_util.bytes_feature(encoded_jpg),
        'image/format': dataset_util.bytes_feature(image_format),
        'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),
        'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),
        'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),
        'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),
        'image/object/class/text': dataset_util.bytes_list_feature(classes_text),
        'image/object/class/label': dataset_util.int64_list_feature(classes),
    }))
    return tf_example
def main(_):
    writer = tf.python_io.TFRecordWriter(FLAGS.output_path)
    label_map_dict = label_map_util.get_label_map_dict(FLAGS.label_map_path)
    images_path = FLAGS.images_input
    examples = pd.read_csv(FLAGS.csv_input)
    grouped = split(examples, 'filename')
    for group in grouped:
        tf_example = create_tf_example(group, label_map_dict, images_path)
        writer.write(tf_example.SerializeToString())
    writer.close()
    output_path = FLAGS.output_path
    print('Successfully created the TFRecords: {}'.format(output_path))
if __name__ == '__main__':
    tf.app.run()


用法:


python generate_tfrecord.py \
--csv_input=./csvdata/tf_train.csv \
--images_input=images \
--output_path=./tfdata/train.record \
--label_map_path=./label_map.pbtxt


类似的依次生成训练、验证和测试数据集:


20200420160757557.png


类别文件


创建label_map.pbtxt文件, 根据自己训练的类别进行修改, 有几个类别就做几个itme!


item {
  name: "face"
  id: 1
  display_name: "face"
}
item {
  name: "telephone"
  id: 2
  display_name: "telephone"
}
item {
  name: "cigarette"
  id: 3
  display_name: "cigarette"
}


配置pipeline.config


到models/research/object_detection/samples/configs/文件夹下将ssd_mobilenet_v2_coco.config拷贝到训练文件夹下,修改内容主要是:

①总类别数 

②tfrecord文件的路径,包括训练集、验证集等路径

③label_map的路径

④预训练模型路径,如果没有则注释掉。也可以设置网络的各种学习参数,如:batch_size,学习率和退化率,训练的总步数等。


●num_classes:3

●fine_tune_checkpoint:“ssd_mobilenet_v1_coco_11_06_2017/model.ckpt” # 预训练模型位置

●num_steps:30000 # 训练步数设置,根据自己数据量来设置,默认为200000

●train_input_reader/input_path:“train.record” # 注意修改成自己的路径位置

●train_input_reader/label_map_path:“label_map.pbtxt” # 类别文件位置,注意修改成自己的路径位置

●num_examples:78 # test数据集的数量

●num_visualizations:78

●#max_evals:10 #注释这个变量,避免一些错误,个人习惯,之前因为这个遇到过错误

●eval_input_reader/inputpath:“test.record” # 注意修改成自己的位置

●eval_input_reader/label_map_path: “label_map.pbtxt” # 注意修改成自己的路径位置


训练模型与导出模型


首先在legacy文件夹中复制一份train.py到object_detection文件夹下,然后运行以下指令(ckpt模型训练后的输出位置)


python train.py --logtostderr --train_dir=training/ --pipeline_config_path=ssd_mobilenet_v2_coco.config 


训练结果


生成一堆models.ckpt-xxx的文件,不同数字代表不同训练步数下保存的模型文件


20200420162251107.png



目录
相关文章
|
3天前
|
机器学习/深度学习 算法 TensorFlow
【图像识别】谷物识别系统Python+人工智能深度学习+TensorFlow+卷积算法网络模型+图像识别
谷物识别系统,本系统使用Python作为主要编程语言,通过TensorFlow搭建ResNet50卷积神经算法网络模型,通过对11种谷物图片数据集('大米', '小米', '燕麦', '玉米渣', '红豆', '绿豆', '花生仁', '荞麦', '黄豆', '黑米', '黑豆')进行训练,得到一个进度较高的H5格式的模型文件。然后使用Django框架搭建了一个Web网页端可视化操作界面。实现用户上传一张图片识别其名称。
25 0
【图像识别】谷物识别系统Python+人工智能深度学习+TensorFlow+卷积算法网络模型+图像识别
|
7天前
|
机器学习/深度学习 人工智能 算法
中草药识别系统Python+深度学习人工智能+TensorFlow+卷积神经网络算法模型
中草药识别系统Python+深度学习人工智能+TensorFlow+卷积神经网络算法模型
42 0
|
9天前
|
机器学习/深度学习 自然语言处理 TensorFlow
构建高效的机器学习模型:基于Python和TensorFlow的实践
构建高效的机器学习模型:基于Python和TensorFlow的实践
31 0
|
17天前
|
机器学习/深度学习 人工智能 算法
食物识别系统Python+深度学习人工智能+TensorFlow+卷积神经网络算法模型
食物识别系统采用TensorFlow的ResNet50模型,训练了包含11类食物的数据集,生成高精度H5模型。系统整合Django框架,提供网页平台,用户可上传图片进行食物识别。效果图片展示成功识别各类食物。[查看演示视频、代码及安装指南](https://www.yuque.com/ziwu/yygu3z/yhd6a7vai4o9iuys?singleDoc#)。项目利用深度学习的卷积神经网络(CNN),其局部感受野和权重共享机制适于图像识别,广泛应用于医疗图像分析等领域。示例代码展示了一个使用TensorFlow训练的简单CNN模型,用于MNIST手写数字识别。
45 3
|
22天前
|
机器学习/深度学习 TensorFlow 算法框架/工具
关于Tensorflow!目标检测预训练模型的迁移学习
这篇文章主要介绍了使用Tensorflow进行目标检测的迁移学习过程。关于使用Tensorflow进行目标检测模型训练的实战教程,涵盖了从数据准备到模型应用的全过程,特别适合对此领域感兴趣的开发者参考。
30 3
关于Tensorflow!目标检测预训练模型的迁移学习
|
22天前
|
机器学习/深度学习 TensorFlow API
Python深度学习基于Tensorflow(3)Tensorflow 构建模型
Python深度学习基于Tensorflow(3)Tensorflow 构建模型
76 2
|
22天前
|
机器学习/深度学习 数据可视化 TensorFlow
【Python 机器学习专栏】使用 TensorFlow 构建深度学习模型
【4月更文挑战第30天】本文介绍了如何使用 TensorFlow 构建深度学习模型。TensorFlow 是谷歌的开源深度学习框架,具备强大计算能力和灵活编程接口。构建模型涉及数据准备、模型定义、选择损失函数和优化器、训练、评估及模型保存部署。文中以全连接神经网络为例,展示了从数据预处理到模型训练和评估的完整流程。此外,还提到了 TensorFlow 的自动微分、模型可视化和分布式训练等高级特性。通过本文,读者可掌握 TensorFlow 基本用法,为构建高效深度学习模型打下基础。
|
22天前
|
机器学习/深度学习 算法 TensorFlow
TensorFlow 2keras开发深度学习模型实例:多层感知器(MLP),卷积神经网络(CNN)和递归神经网络(RNN)
TensorFlow 2keras开发深度学习模型实例:多层感知器(MLP),卷积神经网络(CNN)和递归神经网络(RNN)
|
22天前
|
机器学习/深度学习 TensorFlow API
Python安装TensorFlow 2、tf.keras和深度学习模型的定义
Python安装TensorFlow 2、tf.keras和深度学习模型的定义
|
19天前
|
机器学习/深度学习 数据可视化 TensorFlow
使用TensorFlow进行深度学习入门
【5月更文挑战第18天】本文介绍了TensorFlow深度学习入门,包括TensorFlow的概述和一个简单的CNN手写数字识别例子。TensorFlow是由谷歌开发的开源机器学习框架,以其灵活性、可扩展性和高效性著称。文中展示了如何安装TensorFlow,加载MNIST数据集,构建并编译CNN模型,以及训练和评估模型。此外,还提供了预测及可视化结果的代码示例。