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

本文涉及的产品
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
交互式建模 PAI-DSW,每月250计算时 3个月
模型训练 PAI-DLC,100CU*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



目录
相关文章
|
5月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
深度学习之格式转换笔记(三):keras(.hdf5)模型转TensorFlow(.pb) 转TensorRT(.uff)格式
将Keras训练好的.hdf5模型转换为TensorFlow的.pb模型,然后再转换为TensorRT支持的.uff格式,并提供了转换代码和测试步骤。
138 3
深度学习之格式转换笔记(三):keras(.hdf5)模型转TensorFlow(.pb) 转TensorRT(.uff)格式
|
4月前
|
机器学习/深度学习 数据采集 数据可视化
TensorFlow,一款由谷歌开发的开源深度学习框架,详细讲解了使用 TensorFlow 构建深度学习模型的步骤
本文介绍了 TensorFlow,一款由谷歌开发的开源深度学习框架,详细讲解了使用 TensorFlow 构建深度学习模型的步骤,包括数据准备、模型定义、损失函数与优化器选择、模型训练与评估、模型保存与部署,并展示了构建全连接神经网络的具体示例。此外,还探讨了 TensorFlow 的高级特性,如自动微分、模型可视化和分布式训练,以及其在未来的发展前景。
452 5
|
4月前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
203 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
4月前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
213 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
4月前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
179 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
6月前
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
181 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
5月前
|
机器学习/深度学习 移动开发 TensorFlow
深度学习之格式转换笔记(四):Keras(.h5)模型转化为TensorFlow(.pb)模型
本文介绍了如何使用Python脚本将Keras模型转换为TensorFlow的.pb格式模型,包括加载模型、重命名输出节点和量化等步骤,以便在TensorFlow中进行部署和推理。
217 0
|
7月前
|
API UED 开发者
如何在Uno Platform中轻松实现流畅动画效果——从基础到优化,全方位打造用户友好的动态交互体验!
【8月更文挑战第31天】在开发跨平台应用时,确保用户界面流畅且具吸引力至关重要。Uno Platform 作为多端统一的开发框架,不仅支持跨系统应用开发,还能通过优化实现流畅动画,增强用户体验。本文探讨了Uno Platform中实现流畅动画的多个方面,包括动画基础、性能优化、实践技巧及问题排查,帮助开发者掌握具体优化策略,提升应用质量与用户满意度。通过合理利用故事板、减少布局复杂性、使用硬件加速等技术,结合异步方法与预设缓存技巧,开发者能够创建美观且流畅的动画效果。
123 0
|
7月前
|
C# 开发者 前端开发
揭秘混合开发新趋势:Uno Platform携手Blazor,教你一步到位实现跨平台应用,代码复用不再是梦!
【8月更文挑战第31天】随着前端技术的发展,混合开发日益受到开发者青睐。本文详述了如何结合.NET生态下的两大框架——Uno Platform与Blazor,进行高效混合开发。Uno Platform基于WebAssembly和WebGL技术,支持跨平台应用构建;Blazor则让C#成为可能的前端开发语言,实现了客户端与服务器端逻辑共享。二者结合不仅提升了代码复用率与跨平台能力,还简化了项目维护并增强了Web应用性能。文中提供了从环境搭建到示例代码的具体步骤,并展示了如何创建一个简单的计数器应用,帮助读者快速上手混合开发。
177 0
|
7月前
|
UED 开发工具 iOS开发
Uno Platform大揭秘:如何在你的跨平台应用中,巧妙融入第三方库与服务,一键解锁无限可能,让应用功能飙升,用户体验爆棚!
【8月更文挑战第31天】Uno Platform 让开发者能用同一代码库打造 Windows、iOS、Android、macOS 甚至 Web 的多彩应用。本文介绍如何在 Uno Platform 中集成第三方库和服务,如 Mapbox 或 Google Maps 的 .NET SDK,以增强应用功能并提升用户体验。通过 NuGet 安装所需库,并在 XAML 页面中添加相应控件,即可实现地图等功能。尽管 Uno 平台减少了平台差异,但仍需关注版本兼容性和性能问题,确保应用在多平台上表现一致。掌握正确方法,让跨平台应用更出色。
90 0

热门文章

最新文章