第十一期 使用 Tensorflow 实现物体检测 《显卡就是开发板》

版权声明:本文为aggresss原创文章,未经博主允许不得转载。 作者:[email protected] https://blog.csdn.net/aggresss/article/details/78654218

1.物体识别效果演示

物体识别效果演示01
图片选自 Andrew Carter 的博客 Annotating Large Datasets with the TensorFlow Object Detection API


2.物体识别概述

关于 Object Dection 理论说起来太复杂了,可以自行参考 CS231n 的教程,或者通过这篇文章 A Brief History of CNNs in Image Segmentation: From R-CNN to Mask R-CNN 了解一下 R-CNN 的大概原理。现在神经网络的发展太快了,也许几个月后,现在的理论和实践就过时了,下面是 R-CNN 的模型时间线:
RCNN -> SPP -> Fast RCNN -> Faster RCNN -> YOLO -> SSD -> YOLO2 -> Mask RCNN

物体识别概述01
图片选自 CS231n Lecture 8 (2016)


3.数据集介绍

在使用自己的数据集前可以使用已经发布的知名数据集练习一下,比如 Tensorflow Object Detect API 文档里提到的 Quick Start: Training a pet detector ,下面介绍两种数据集,感兴趣可以下载下来体会一下:


Oxford-IIIT Pet Dataset
需要分别下载 DatasetGroundtruth data

  • Dataset –> images
    images 文件夹就是所有种类的图片
  • Groundtruth data –> annotitions
    annotitions 文件夹包含图片的标签信息
    annotations/xmls/ 文件夹时对应 images 文件中图片的标签
    annotations/trainval.txt 是所有图片和标签的文件名索引
    annotations/label_map.pbtxt 文件中记录了所用种类名称对应的ID

PASCAL VOC Dataset
PASCAL (Pattern Analysis, Statistical modelling and Computational Learning)
VOC (Visual Object Classes)
PASCAL VOC 数据集是一个混合数据集,包含四种数据集:

  • Classification/Detection Image Sets
  • Segmentation Image Sets
  • Action Classification Image Sets
  • Person Layout Taster Image Sets

当然我们只使用 Classification/Detection Image Sets ,数据集文件解压后是一个 VOCdevkit 文件,下一层目录是 VOC 数据集年份,我下载的是 VOC2012,tensorflow将数据集转换时之用到了这三个文件夹:

  • ImageSets/Main/ 用于数据集索引
  • JPEGImags/ 图片存放文件夹
  • Annotations/ 数据标签文件夹

4.数据集转换

上面介绍了两种比较流行的成品数据集,Tensorflow Object Detection APIdataset_tools 目录支持这两种数据集转换成 TFRecord 格式的训练集,但是通过上面的分析你会发现,上面的数据集的生成都比较繁琐,都需要生成索引文件,所以我花了一点时间改装了以下生成脚本 create_tf_record.py,使用自己的数据集格式来生成数据集,下面是自定义的数据集格式:

+ breed_xxx
    + annotations
        - x001.xml
        - x002.xml  
    + images
        - x001.jpg
        - x002.jpg
+ breed_yyy
    + annotations
        - y001.xml
        - y002.xml  
    + images
        - y001.jpg
        - y002.jpg
- label_map.pbtxt

label_map.pbtxt 的格式为:

item {
  id: 1
  name: 'breed_xxx'
}

item {
  id: 2
  name: 'breed_yyy'
}

有两点需要注意:

  • 标签文件需要和图片文件有相同的名字;
  • 标签名称需要都包含在 label_map.pbtxt 文件中;

使用 LabelImg 将图片生成标签文件,要求生成的标签文件与图片文件同名并且拓展名为 *.xml

LabelImg 如果是 Python2.7 的 Windows 版本,需要手动安装 PyQt4-4.11.4

LabelImg示例

生成的标签文件记录了以下信息:

<annotation>
  <filename>182.jpg</filename>
  <size>
    <width>1280</width>
    <height>586</height>
    <depth>3</depth>
  </size>
  <segmented>0</segmented>
  <object>
    <name>breed_xxx</name>
    <bndbox>
      <xmin>581</xmin>
      <ymin>106</ymin>
      <xmax>618</xmax>
      <ymax>142</ymax>
    </bndbox>
  </object>
  <object>
    <name>breed_xxx</name>
    <bndbox>
      <xmin>127</xmin>
      <ymin>406</ymin>
      <xmax>239</xmax>
      <ymax>526</ymax>
    </bndbox>
  </object>
</annotation>

在后面的模型训练过程中可能会涉及到图片分辨率的修改,因为分辨率过大可能会报错,那么问题来了,如果图片已经打好标签,修改分辨率后是否要重新打标签呢,其实不用的但是要略作修改,下面的代码是 TFRecord 格式存储标签位置的算法,可以看出它是按照图片分辨率的比例来存储的,所以修改分辨率后原来的标签一样可以使用。

xmin.append(float(obj['bndbox']['xmin']) / width)
ymin.append(float(obj['bndbox']['ymin']) / height)
xmax.append(float(obj['bndbox']['xmax']) / width)
ymax.append(float(obj['bndbox']['ymax']) / height)

但是要把修改分辨率后的真实尺寸记录到 TFRecord 中,而不是标签文件中记录的分辨率:

    with tf.gfile.GFile(image_path, 'rb') as fid:
        encoded_jpg = fid.read()
    encoded_jpg_io = io.BytesIO(encoded_jpg)
    image = PIL.Image.open(encoded_jpg_io)
    if image.format != 'JPEG':
        raise ValueError('Image format not JPEG')
    key = hashlib.sha256(encoded_jpg).hexdigest()

    real_width = image.size[0]
    real_height = image.size[1]
    width = int(data['size']['width'])
    height = int(data['size']['height'])
example = tf.train.Example(
        features=tf.train.Features(
            feature={
                'image/height':
                dataset_util.int64_feature(real_height),
                'image/width':
                dataset_util.int64_feature(real_width),

以上代码节选自我自己写的 create_tf_record.py 脚本,使用方法为:

 python ./create_tf_record.py --data_path="datasets"

另外,我还写了一个可以批量修改图片分辨率的脚本 image_resize.py , 以便批量修改图片分辨率,使用方法为:

python image_resize.py -p path -w wide -l height

其中,wide 和 height 参数可以只提供一个,它会自动按比例计算。


5.重新训练模型

可以使用我写的 Dockefile 快速构建 Tensorflow Object Detection API 的训练环境。
GPU可以使用下面代码构建:

wget \
https://raw.githubusercontent.com/aggresss/GPUDemo/master/object-detection/Dockerfile_GPU
docker build -f Dockerfile_GPU -t xxx .

使用下面命令验证训练环境是否配置成功:

python object_detection/builders/model_builder_test.py

训练过程可以参考官方文档 running_locally.md .
文件组织方式为:

+data
  -label_map file
  -train TFRecord file
  -eval TFRecord file
+models
  + model
    -pipeline config file
    +train
    +eval

Tensorflow Object Detection API 将训练配置参数都放到了 pipeline config 文件中,所以重新训练模型的关键是创建一个适用于自己的 config 文件,Tensorflow Object Detection APIsamples/configs 文件夹已经提供了很多示例,只要稍作修改就可以使用。detection_model_zoo.md 中列出了很多己经训练过的模型,这些模型都是 out-of-the-box 类型的,当然如果想让它识别我们自己的图片集还是要拿过来 fine-tune 一下,我使用的是 ssd_inception_v2_coco ,其中 ssd 表示物体检测算法,inception_v2 表示神经网络结构,coco 表示使用 coco 数据集进行训练。

ssd_inception_v2_coco.config 复制到本地目录进行修改,主要修改项目包括:

  • num_classes: xxx // 修改为实际训练的种类数
  • batch_size: xxx //默认为24,可以根据图片集的大小适当调节
  • 搜索文件中的 “PATH_TO_BE_CONFIGURED” 将 model 和 data 文件夹的实际路径按说明修改好

现在我们已经具备训练的条件了:

  • TFRecord 格式的数据集
  • 预训练的模型文件
  • 训练的配置文件

使用下面命令训练模型:

# From the tensorflow/models/research/ directory
python object_detection/train.py \
    --logtostderr \
    --pipeline_config_path=${PATH_TO_YOUR_PIPELINE_CONFIG} \
    --train_dir=${PATH_TO_TRAIN_DIR}

使用下面命令查看训练结果:

tensorboard --logdir=${PATH_TO_MODEL_DIRECTORY}

模型训练好后需要 导出模型 使用下面命令导出模型:

# From tensorflow/models/research/
python object_detection/export_inference_graph.py \
    --input_type image_tensor \
    --pipeline_config_path ${PIPELINE_CONFIG_PATH} \
    --trained_checkpoint_prefix ${TRAIN_PATH} \
    --output_directory output_inference_graph.pb

导出模型后就可以使用模型进行预测:

# From tensorflow/models/research/
python object_detection/inference.py \
    --frozen_graph ${FROZEN_GRAPH_PATH} \
    --label_map ${LABEL_MAP_FILE} \
    --input_dir ${IAMGE_INPUT_PATH} \
    --output_dir ${IMAGE_OUTPUT_PATH}

参考文档

  1. How to train your own Object Detector with TensorFlow’s Object Detector API

  2. Building a Toy Detector with Tensorflow Object Detection API

  3. How to play Quidditch using the TensorFlow Object Detection API

  4. Annotating Large Datasets with the TensorFlow Object Detection API

  5. Traffic Light Detection Using the TensorFlow* Object Detection API

  6. Tracking the Millennium Falcon with TensorFlow

  7. Object detection in sports: TensorFlow Object Detection API case study

猜你喜欢

转载自blog.csdn.net/aggresss/article/details/78654218