用TensorFlow训练一个物体检测器(手把手教学版)

TunSoFrices组编任一可怕的的反对检测API。,笔者可以应用上面所说的事API来锻炼笔者本人的最高纪录集以实施特殊的目的工作。。

作者的软硬件四周分配额

CPU: i7-6800k (无使付出努力),主流CPU可以)
OS: Ubuntu Linux 16.04 LTS 优良独角兽徽章版
内存:16G
硬磁盘:ssd
显卡:NVIDIA GEFORCE GTX 1080TI 11G (越大越好。,CUDA地核越多越好,我在锻炼中,应用GPU,昌盛比应用CPU快10-20倍。

一位异国顺序员分享了他看法心爱浣熊DET的经历。

原始地址(必要十字架墙):

原作者吉图布:   (作者的最高纪录集可以在在这里下载)

本文要点摘录引见了勘探者的锻炼连贯。,虽然太粗糙了,初学者很难齐肩并进。。手巧的初学者,我赚钱了详细情节的开动。,让笔者如今一同书房。!

你为什么执意非常的做?

手巧的面不光心爱,与外用的民主党员圆元是很遍及的事。。爱上浣熊和浣熊的附近的地区,作者选择了它作为勘探者的检测反对。。相机可以优美的体型在屋子四周结尾后。,看一眼有没浣熊入侵你的屋子,你可以即时赚得你倘若来了任一不速之客。。浣熊如同非常的了。!

一、使成为最高纪录集

机具书房必要最高纪录作为半成品,因而笔者率先要做的是优美的体型任一锻炼最高纪录集。,同时笔者必要使用契合Tensorflow的最高纪录体式来禁猎地这些最高纪录及其监视。

1。在输入最高纪录从前,必要思索几件事。:概要的,你必要些许浣熊的五彩缤纷的相片。;其二,你必要图中浣熊的场所座标系(Xmin),ymin,xmax,YMAX)地位和分类学浣熊。为了检测任一反对,笔者的工作十足的复杂。,你可以下定义任一类。;

2。笔者在哪里可以找到最高纪录?互联网方法是最大的资源。。包罗次要搜标引擎在内的图像搜索和图像网站。,找寻些许辨别的估量、位姿、灯火下的相片。作者搜索了二百只浣熊来锻炼他的勘探者。,但非常的做更不用说。,说起来,在IMANET上有浣熊最高纪录集。,好朋友可以下载,记录IMANET必要十字架高墙,不然,无法检查证明码。);

目的干脆面君:动动手,用TensorFlow API锻炼出本人的目的检测霉

三。当笔者有最高纪录时,笔者必要把它们贴上监视。。分类学很复杂。,都是浣熊,但笔者必要人工控制地位浣熊在每任一图片。。最好的徽章器完成是LabelImg。, 论图像徽章,请求教于我的另一篇文字《手把手教你图片打标》

4、到眼前为止,笔者受胎些许浣熊的图片此外这些图片的标注发稿(annotation)(是否你有点懒,您可以从作者的GITHUB下载这些图片和正文发稿。, 在这里我将下载原始作者的正文发稿和图片。

(单击下载) ZIP可以下载整个地以协议约束。

5、笔者神速扩大下载的ZIP包,如次,正文含量是正文发稿。,图像含量是任一图像发稿,正文发稿射中靶子发稿名装满是对应发稿的发稿名。,必要特殊阐明的是,raccoon上面所说的事最高纪录集外面的标注发稿xml里的filename是png后缀,说起来,笔者下载的图像是JPG体式。,预算书原始作者掉换体式。,乃,在后头的文本中,笔者必要对上面所说的事发稿名做大约处置。。笔者不必要任何的其他的发稿解包。,整个拟出,嗣后,笔者将逐渐地构图这些发稿。。

6。终极的,将图像和图像的监视掉换成TFREST体式,它可以分为锻炼集和证明集来启动下任一。!用LabelImg is PASCAL徽章的发稿 VOC体式,ToSoFrof为Pascal暂代他人职务本子 VOC体式标注发稿和相关联的的图片掉换为TFRecord,不外,应用此本子,笔者必要先优美的体型TySoFr流四周并优美的体型TySoFrase. object detection api ,在流行中的这两个党派,请参阅我的布景文字Ubuntu 16.04下搭建TensorFlow运转四周(用Anaconda)》《Ubuntu 16.04下优美的体型TensorFlow Object Detection API(反对检测API),后来的,承担您先前阵地这两篇文字排列了四周。。

二、将图片和正文掉换成TFREST体式

在~/tensorflow/models/research/object_detection/dataset_tools含量下(~表现以后用户主含量,查找发稿,这是TaSoFLASH暂代他人职务的PASCAL。 将VOC体式掉换成TFREST体式的本子,落实以下本子,再版一份,孤独地上面所说的事本子是指向相当于每平方米一牛顿的力的 作曲VOC最高纪录集的含量和解。,因而笔者必要编译来修正它:

(根) forest@forest-MS-7A20:~/tensorflow/models/research$ cp object_detection/dataset_tools/ object_detection/dataset_tools/
(根) forest@forest-MS-7A20:~/tensorflow/models/research$ gedit object_detection/dataset_tools/

这条线的多种经营太大了。,这并产生断层任一接任一的解说。,上面暂代他人职务完整的的发稿行为准则。

# -*- 编码:UTF-8 -*-

# Copyright 2017 The TensorFlow 作者。 All Rights 保存的。
#
# Licensed under the Apache License, Version 2.0 (the 准许
# you may not use this file except in compliance with the 准许。
# You may obtain a copy of the License at
#
#     
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 暗指的。
# See the License for the specific language governing permissions and
# limitations under the 准许。
# ==============================================================================

掉换 raw PASCAL dataset to TFRecord for object_detection.

Example usage:
    python object_detection/dataset_tools/ \
	--data_dir=/home/forest/dataset/raccoon_dataset-master/images \
	--set=/home/forest/dataset/raccoon_dataset-master/ \
	--output_path=/home/forest/dataset/raccoon_dataset-master/ \
	--label_map_path=/home/forest/dataset/raccoon_dataset-master/ \
	--annotations_dir=/home/forest/dataset/raccoon_dataset-master/annotations
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import hashlib
import io
import logging
import os

from lxml import etree
import PIL.Image
import tensorflow as tf

from object_detection.utils import dataset_util
from object_detection.utils import label_map_util


flags = tf.app.flags
(''data_dir'', '''', 根 directory to raw PASCAL VOC data集中。
(设置), 教育, 掉换 training set, validation set or ''
                    兼并 集中。
(''annotations_dir'', 正文,
                    (绝对) path to annotations directory.'')
(年), ''VOC2007'', 要求的 challenge year.'')
(''output_path'', '''', 渠道 to output TFRecord'')
(''label_map_path'', ''data/'',
                    渠道 to label map 原
(''ignore_difficult_instances'', False, 倘若 to ignore ''
                     英〉硬海滩 加盖于)
FLAGS = flags.FLAGS

SETS = [教育, 瓦尔, ''trainval'', 受测验
YEARS = [''VOC2007'', ''VOC2012'', 兼并'']


def dict_to_tf_example(data,
                       dataset_directory,
                       label_map_dict,
                       ignore_difficult_instances=False,
                       image_subdirectory=''JPEGImages''):
  """Convert XML derived dict to tf.Example 原句

  Notice that this function normalizes the bounding box coordinates provided
  by the raw 最高纪录。

  Args:
    data: dict holding PASCAL XML fields for a single image (学到) by
      running )
    dataset_directory: Path to root directory holding PASCAL dataset
    label_map_dict: A map from string label names to integers ids.
    ignore_difficult_instances: Whether to skip difficult instances in the
      dataset  (default: False).
    image_subdirectory: String specifying subdirectory within the
      PASCAL dataset directory holding the actual image 最高纪录。

  Returns:
    example: The converted tf.Example.

  Raises:
    ValueError: if the image pointed to by data[''filename''] is not a valid JPEG
  """
  # 上面这句里的replace执意指向reccoon的标注发稿里的filename监视后缀违法而特殊添加的
  img_path = (dataset_directory, data[''filename''].replace(''.png'',''.jpg'').replace(''.PNG'',''.jpg''))
  full_path = img_path
  with tf.gfile.GFile(full_path, ''rb'') as fid:
    encoded_jpg = ()
  encoded_jpg_io = (encoded_jpg)
  image = (encoded_jpg_io)
  if image.format != ''JPEG'':
    raise ValueError(''Image format not JPEG'')
  key = (encoded_jpg).hexdigest()

  width = int(data[''size''][''width''])
  height = int(data[''size''][''height''])

  xmin = []
  ymin = []
  xmax = []
  ymax = []
  classes = []
  classes_text = []
  truncated = []
  poses = []
  difficult_obj = []
  for obj in data[''object'']:
    difficult = bool(int(obj[英〉硬海滩'']))
    if ignore_difficult_instances and difficult:
      continue

    difficult_obj.append(int(difficult))

    (float(obj[''bndbox''][''xmin'']) / width)
    (float(obj[''bndbox''][''ymin'']) / height)
    (float(obj[''bndbox''][''xmax'']) / width)
    (float(obj[''bndbox''][''ymax'']) / height)
    (obj[''name''].encode(''utf8''))
    (label_map_dict[obj[''name'']])
    (int(obj[''truncated'']))
    (obj[''pose''].encode(''utf8''))

  example = (features=(feature={
      ''image/height'': (height),
      ''image/width'': (width),
      ''image/filename'': (
          data[''filename''].encode(''utf8'')),
      ''image/source_id'': (
          data[''filename''].encode(''utf8'')),
      ''image/key/sha256'': ((''utf8'')),
      ''image/encoded'': (encoded_jpg),
      ''image/format'': (''jpeg''.encode(''utf8'')),
      ''image/object/bbox/xmin'': (xmin),
      ''image/object/bbox/xmax'': (xmax),
      ''image/object/bbox/ymin'': (ymin),
      ''image/object/bbox/ymax'': (ymax),
      ''image/object/class/text'': (classes_text),
      ''image/object/class/label'': (classes),
      ''image/object/difficult'': (difficult_obj),
      ''image/object/truncated'': (truncated),
      ''image/object/view'': (poses),
  }))
  return example


def main(_):
  #if FLAGS.set not in SETS:
  #  raise 值违法集 must be in : 体式(集中)
  #if  not in YEARS:
  #  raise 使付出努力年 must be in : 体式(年)

  data_dir = FLAGS.data_dir
  years = [''VOC2007'', ''VOC2012'']
  if  != 兼并'':
    years = []

  writer = ()

  label_map_dict = ()

  for year in years:
    (朗读) from PASCAL %s 最高纪录集。'', 年)
    examples_path = FLAGS.set
    #                             ''aeroplane_'' + FLAGS.set + 'txt’)
    annotations_dir = FLAGS.annotations_dir
    examples_list = dataset_util.read_examples_list(examples_path)
    for idx, example in enumerate(examples_list):
      if idx % 100 == 0:
        (对) image %d of %d'', idx, len(examples_list))
      path = (annotations_dir, example + .xml
      with tf.gfile.GFile(path, ''r'') as fid:
        xml_str = ()
      xml = (xml_str)
      data = (xml)[''annotation'']

      tf_example = dict_to_tf_example(data, FLAGS.data_dir, label_map_dict,
                                      FLAGS.ignore_difficult_instances)
      (())

  ()


if __name__ == ''__main__'':
  ()

有构架的必要笔者下定义好笔者的类别ID与类别系统命名法的相干,通常用pbtxt体式发稿禁猎地,笔者在~/dataset/raccoon_dataset-master/含量下新建任一名为的文本发稿,目录如次:

item {
  id: 1
  name: ''raccoon''
}

鉴于笔者孤独地任一类别,因而在这里就只必要下定义1个item,若你有多个类别,就必要多个item,当心,id从1开端,name的值要和标注发稿里的类别name俱,即你在图像打标的时辰徽章的是raccoon,在这里要写raccoon,不克不及写”浣熊”.

笔者必要用两个文本发稿,来告知掉换本子,哪一些图片发稿用来做锻炼集,哪一些图片发稿用来做证明集。在~/dataset/raccoon_dataset-master/含量下新建任一名为的文本发稿,目录(上面所说的事清单是我用python本子产额的,人工取前160张作为锻炼集,后40张作为证明集)如次:

raccoon-194
raccoon-101
raccoon-4
raccoon-105
raccoon-97
raccoon-113
raccoon-48
raccoon-108
raccoon-156
raccoon-55
raccoon-161
raccoon-2
raccoon-59
raccoon-18
raccoon-41
raccoon-126
raccoon-79
raccoon-23
raccoon-92
raccoon-58
raccoon-153
raccoon-165
raccoon-182
raccoon-122
raccoon-95
raccoon-86
raccoon-6
raccoon-99
raccoon-46
raccoon-130
raccoon-167
raccoon-186
raccoon-183
raccoon-177
raccoon-170
raccoon-179
raccoon-73
raccoon-82
raccoon-5
raccoon-10
raccoon-94
raccoon-30
raccoon-67
raccoon-85
raccoon-87
raccoon-112
raccoon-174
raccoon-196
raccoon-134
raccoon-133
raccoon-148
raccoon-13
raccoon-89
raccoon-16
raccoon-128
raccoon-150
raccoon-106
raccoon-120
raccoon-144
raccoon-137
raccoon-12
raccoon-140
raccoon-21
raccoon-141
raccoon-107
raccoon-47
raccoon-29
raccoon-115
raccoon-25
raccoon-124
raccoon-3
raccoon-1
raccoon-131
raccoon-50
raccoon-103
raccoon-80
raccoon-71
raccoon-42
raccoon-142
raccoon-176
raccoon-149
raccoon-33
raccoon-132
raccoon-118
raccoon-26
raccoon-65
raccoon-43
raccoon-200
raccoon-135
raccoon-154
raccoon-93
raccoon-22
raccoon-36
raccoon-69
raccoon-96
raccoon-114
raccoon-181
raccoon-84
raccoon-193
raccoon-68
raccoon-192
raccoon-70
raccoon-74
raccoon-88
raccoon-8
raccoon-34
raccoon-139
raccoon-91
raccoon-109
raccoon-27
raccoon-54
raccoon-52
raccoon-185
raccoon-136
raccoon-61
raccoon-127
raccoon-98
raccoon-155
raccoon-75
raccoon-28
raccoon-173
raccoon-57
raccoon-56
raccoon-187
raccoon-160
raccoon-35
raccoon-151
raccoon-175
raccoon-129
raccoon-20
raccoon-116
raccoon-66
raccoon-37
raccoon-180
raccoon-143
raccoon-40
raccoon-76
raccoon-111
raccoon-64
raccoon-24
raccoon-60
raccoon-168
raccoon-17
raccoon-32
raccoon-147
raccoon-117
raccoon-172
raccoon-189
raccoon-45
raccoon-81
raccoon-7
raccoon-63
raccoon-110
raccoon-198
raccoon-100
raccoon-39
raccoon-9
raccoon-19
raccoon-195
raccoon-197

在~/dataset/raccoon_dataset-master/含量下新建任一名为的文本发稿,目录如次:

raccoon-138
raccoon-90
raccoon-44
raccoon-152
raccoon-162
raccoon-190
raccoon-191
raccoon-51
raccoon-62
raccoon-102
raccoon-119
raccoon-178
raccoon-49
raccoon-184
raccoon-72
raccoon-157
raccoon-14
raccoon-163
raccoon-53
raccoon-188
raccoon-104
raccoon-169
raccoon-146
raccoon-164
raccoon-31
raccoon-166
raccoon-171
raccoon-78
raccoon-77
raccoon-145
raccoon-199
raccoon-123
raccoon-11
raccoon-83
raccoon-158
raccoon-125
raccoon-15
raccoon-159
raccoon-38
raccoon-121

上面所说的事列表可以用上面的Python本子产额

import os
import random

pt="/home/forest/dataset/raccoon_dataset-master/images/"
image_name=(pt)
for temp in image_name:
    if temp.endswith(".jpg"):
        print temp.replace(''.jpg'','''')

运转笔者汇编的本子,产额TFREST发稿

#from ~/tensorflow/models/research
python object_detection/dataset_tools/ \
	--data_dir=/home/forest/dataset/raccoon_dataset-master/images \
	--set=/home/forest/dataset/raccoon_dataset-master/ \
	--output_path=/home/forest/dataset/raccoon_dataset-master/ \
	--label_map_path=/home/forest/dataset/raccoon_dataset-master/ \
	--annotations_dir=/home/forest/dataset/raccoon_dataset-master/annotations

是否输入 if not xml,解说落实成,~/dataset/raccoon_dataset-master/ 执意笔者必要锻炼集发稿

吵闹落实以下本子,产额证明集TFREST发稿

python object_detection/dataset_tools/ \
	--data_dir=/home/forest/dataset/raccoon_dataset-master/images \
	--set=/home/forest/dataset/raccoon_dataset-master/ \
	--output_path=/home/forest/dataset/raccoon_dataset-master/ \
	--label_map_path=/home/forest/dataset/raccoon_dataset-master/ \
	--annotations_dir=/home/forest/dataset/raccoon_dataset-master/annotations

是否输入 if not xml,解说落实成,~/dataset/raccoon_dataset-master/ 执意笔者必要证明集发稿

三、下载前朝反方向相关的事情时尚

四、修正朝反方向相关的事情分配额发稿

 再版object_detection/samples/configs下的 到 ~/dataset/raccoon_dataset-master/下,重命名为,并终止以下修正:

# SSD with Mobilenet v1 configuration for MSCOCO 最高纪录集。
# Users should configure the fine_tune_checkpoint field in the train config as
# well as the label_map_path and input_path fields in the train_input_reader and
# eval_input_reader. Search for "PATH_TO_BE_CONFIGURED" to find the fields that
# should be 分配额好的。


model {
  ssd {
    num_classes: 1
    box_coder {
      faster_rcnn_box_coder {
        y_scale: 
        x_scale: 
        height_scale: 
        width_scale: 
      }
    }
。。。


train_config: {
  batch_size: 24
  optimizer {
    rms_prop_optimizer: {
      learning_rate: {
        exponential_decay_learning_rate {
          initial_learning_rate: 
          decay_steps: 800720
          decay_factor: 
        }
      }
      momentum_optimizer_value: 
      decay: 
      epsilon: 
    }
  }
  fine_tune_checkpoint: "/home/forest/tensorflow/models/research/object_detection/ssd_mobilenet_v1_coco_2017_11_17/"
  from_detection_checkpoint: true
  # Note: The below line limits the training process to 200K steps, which we
  # empirically found to be sufficient enough to train the pets 最高纪录集。 This
  # effectively bypasses the learning rate schedule (the learning rate will
  # never 衰退) Remove the below line to train 不定期地
  num_steps: 200000
  data_augmentation_options {
    random_horizontal_flip {
    }
  }
  data_augmentation_options {
    ssd_random_crop {
    }
  }
}


train_input_reader: {
  tf_record_input_reader {
    input_path: "/home/forest/dataset/raccoon_dataset-master/"
  }
  label_map_path: "/home/forest/dataset/raccoon_dataset-master/"
}


eval_config: {
  num_examples: 40
  # Note: The below line limits the evaluation process to 10 评价。
  # Remove the below line to evaluate 不定期地
  metrics_set:"pascal_voc_metrics"
  max_evals: 10
}


eval_input_reader: {
  tf_record_input_reader {
    input_path: "/home/forest/dataset/raccoon_dataset-master/"
  }
  label_map_path: "/home/forest/dataset/raccoon_dataset-master/"
  shuffle: false
  num_readers: 1
}

在~/dataset/raccoon_dataset-master/含量下新建任一train含量,禁猎地锻炼的核对点发稿。

五、开端锻炼

在目的检测渠道下,落实以下命令,开端锻炼,:

# 从 ~/tensorflow/models/research/object_detection 上面的命令在含量下运转

python –logtostderr \–pipeline_config_path=/home/forest/dataset/raccoon_dataset-master/ \–train_dir=/home/forest/dataset/raccoon_dataset-master/train

是否GPU,您必要在发稿的五十分之一五行中,添加前面的句子:

GPU必要添加以下句子,0代表第铺地板GPU器材

[”CUDA_VISIBLE_DEVICES”] = “0”

您可以在端子中恣意工夫按下CTRL C。,朝反方向相关的事情止付,这么笔者什么时辰完毕锻炼呢?请看上面的目录。。

六、应用证明集来评价朝反方向相关的事情所有物(可选)

在~/dataset/raccoon_dataset-master/含量下新建任一eval含量,用于禁猎地EVE的发稿。孤独端子,落实以下命令

(根) forest@forest-MS-7A20:~/tensorflow/models/research/object_detection$ python eval.py \
	--logtostderr \
	--pipeline_config_path=/home/forest/dataset/raccoon_dataset-master/ \
	--checkpoint_dir=/home/forest/dataset/raccoon_dataset-master/train \
	--eval_dir=/home/forest/dataset/raccoon_dataset-master/eval

固执己见上面所说的事端子运转,在锻炼完毕时,以后CTRL C完毕EVE

七、浅谈招招标射中靶子朝反方向相关的事情处理

为了更手巧的 TensorFlow 对顺序的逮捕、调试与最优化,谷歌流出了一布景电话学 TensorBoard 的形象器。你可以用 TensorBoard 揭露给你看 TensorFlow 图像,绘制图像产额的定量标引图和附加最高纪录。TensorBoard 完成朗读 TensorFlow 运转事变发稿运转。TensorFlow 组编的事变发稿将组编在 TensorFlow 运转中触及的次要最高纪录。

开拓新车站楼,运转以下口述:

(根) forest@forest-MS-7A20:~$ source activate root
(根) forest@forest-MS-7A20:~$ tensorboard --logdir=/home/forest/dataset/raccoon_dataset-master/

在浏览程序中翻开浏览程序射中靶子HTTP地址,你可以关照TooBooad的次要相间的,可以看出,在20k 步前,减少神速减少,以后它很小。,完成任一夜晚的锻炼,如今亲密的80K step了, mAP吝啬的精密率为67%(鉴于栩栩如生的锻炼完后来的改装的eval,因而这是一则垂线,教育上有埃瓦,在这里应该是任一买通。,笔者差不多可以终止锻炼。在朝反方向相关的事情端子终止CTRL C朝反方向相关的事情。。

是否你在教育前面,我开端运转,您还可以拉滑块如次,以检查随工夫多种经营。,视觉引人注目所有物的多种经营。

八、将核对点发稿导出到解冻霉发稿

TysFROW方法组编大方的必要TRAI的变量,当锻炼完毕时,这些变量的值被决定。,笔者可以用康斯坦斯来掉换锻炼射中靶子核对点发稿射中靶子变量。,用于重要性的霉发稿。当心75895 党派阵地你本人的最末任一核对点的编号来修剪。

(根) forest@forest-MS-7A20:~/tensorflow/models-master/research/object_detection$ python export_inference_graph.py \
--pipeline_config_path=/home/forest/dataset/raccoon_dataset-master/ \
--trained_checkpoint_prefix=/home/forest/dataset/raccoon_dataset-master/train/-75895 \
--output_directory=/home/forest/dataset/raccoon_dataset-master/train

/home/forest/dataset/raccoon_dataset-master/train下的 这份发稿是笔者宝贵的,终极霉发稿。

九、使用霉引人注目浣熊

翻开Ubuntu 16.04下优美的体型TensorFlow Object Detection API(反对检测API)里最末一步提到的DEMO,终止以下修正:

…..

在任一开动中运转每行

终极坐果如次

发表评论

电子邮件地址不会被公开。 必填项已用*标注