2019.6.27目标检测之自定义目标检测

如果您已经按照本教程进行操作,那么现在应该有一个文件夹Tensorflow,放在(例如C:\Users\sglvladi\Documents)下面,带有以下目录树:

TensorFlow
├─ addons
│ └── labelImg
└─ models
├── official
├── research
├── samples
└── tutorials
现在在下面创建一个新文件夹TensorFlow 并调用它workspace。这是内部的workspace,我们将存储我们所有的培训调校。现在让我们进入工作空间并创建另一个名为的文件夹training_demo。现在我们的目录结构应如下:

TensorFlow
├─ addons
│ └─ labelImg
├─ models
│ ├─ official
│ ├─ research
│ ├─ samples
│ └─ tutorials
└─ workspace
└─ training_demo
该training_demo文件夹应为我们的培训文件夹,其中包含与我们的模型培训相关的所有文件。每当我们希望训练不同的模型时,建议创建一个单独的培训文件夹。培训文件夹的典型结构如下所示。

training_demo
├─ annotations
├─ images
│ ├─ test
│ └─ train
├─ pre-trained-model
├─ training
└─ README.md
以下是上述树中显示的每个文件夹/文件管理器的说明:

annotations:此文件夹将用于存储所有*.csv文件和相应的TensorFlow *.record文件,其中包含数据集图像的注释列表。

images:此文件夹包含数据集中所有图像的副本,以及*.xml为每个图像生成的相应文件,一次labelImg用于注释对象。

images\train:此文件夹包含所有图像的副本以及*.xml将用于训练模型的相应文件。
images\test:此文件夹包含所有图像的副本以及相应的*.xml文件,这些文件将用于测试我们的模型。
pre-trained-model:此文件夹将包含我们选择的预先训练的模型,该模型将用作我们培训工作的起始检查点。

training:此文件夹将包含训练管道配置文件*.config,*.pbtxt标签映射文件以及在模型训练期间生成的所有文件。

README.md:这是一个可选文件,提供有关我们模型的训练条件的一些一般信息。TensorFlow不会以任何方式使用它,但是当您有一些培训文件夹和/或您在一段时间后重新访问经过培训的模型时,它通常会有所帮助。

如果你不理解上面提到的大部分内容,不用担心,因为我们将看到如何进一步生成所有文件。

注释图像
要注释图像,我们将使用labelImg包。如果尚未安装该软件包,请查看LabelImg安装。

收集完所有用于测试模型的图像(理想情况下每个类别超过100个)后,将它们放在文件夹中training_demo\images。

打开一个新的Anaconda /命令提示符窗口并cd进入Tensorflow\addons\labelImg。

如果(如LabelImg安装中所示)您创建了一个单独的Conda环境,labelImg则继续并通过运行以下命令将其激活:

activate labelImg
接下来继续并开始labelImg,将其指向您的training_demo\images文件夹。

python labelImg.py …\workspace\training_demo\images
应打开文件资源管理器对话框窗口,该窗口指向该training_demo\images文件夹。

按“选择文件夹”按钮,开始注释图像。

打开后,您应该看到一个类似于下面的窗口:

替代文字
我不会介绍如何使用的教程labelImg,但您可以查看labelImg的repo以获取更多详细信息。这里labelImg还提供了一个很好的Youtube视频,展示了如何使用。重要的是,一旦您注释了所有*.xml图像,就应该在training_demo\images文件夹中生成一组新文件,每个图像一个。

完成对图像数据集的注释后,通常只使用其中一部分进行训练,其余用于测试目的。通常,该比例为90%/ 10%,即90%的图像用于训练,其余10%用于测试,但您可以选择适合您需要的任何比例。

确定如何拆分数据集后,将所有训练图像及其相应*.xml文件复制到training_demo\images\train文件夹中。同样,复制所有测试图像及其*.xml文件,然后将其粘贴到其中training_demo\images\train。

创建标签映射
TensorFlow需要标签贴图,即将每个使用过的标签映射为整数值。该标签图由训练和检测过程使用。

下面我展示一个示例标签图(例如label_map.pbtxt),假设我们的数据集包含2个标签,dogs并且cats:
item {
id: 1
name: ‘cat’
}

item {
id: 2
name: ‘dog’
}
创建TensorFlow记录
现在我们已经生成了注释并将数据集拆分为所需的训练和测试子集,现在是时候将我们的注释转换为所谓的TFRecord格式。

这样做有两个步骤:

将单个*.xml文件转换*.csv为每个数据集的统一文件。
将*.csv每个数据集的文件转换为*.record文件(TFRecord格式)。
在我们继续描述上述步骤之前,让我们创建一个可以存储一些脚本的目录。在该TensorFlow文件夹下,创建一个新文件夹TensorFlow\scripts,我们可以使用它来存储一些有用的脚本。为了使事情更加整洁,让我们创建一个新文件夹TensorFlow\scripts\preprocessing,我们将存储可用于预处理培训输入的脚本。下面是TensorFlow目录树结构,截至目前:

TensorFlow
├─ addons
│ └─ labelImg
├─ models
│ ├─ official
│ ├─ research
│ ├─ samples
│ └─ tutorials
├─ scripts
│ └─ preprocessing
└─ workspace
└─ training_demo
转换*.xml为*.csv
为此,我们可以编写一个简单的脚本来遍历和文件夹*.xml中的所有文件,并为两者中的每一个生成一个。training_demo\images\traintraining_demo\images\test*.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()
for member in root.findall(‘object’):
value = (root.find(‘filename’).text,
int(root.find(‘size’)[0].text),
int(root.find(‘size’)[1].text),
member[0].text,
int(member[4][0].text),
int(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():
image_path = r’C:\Users\Administrator\Desktop\deep_learning\workspace\training_demo\image\test’#
xml_df = xml_to_csv(image_path)
xml_df.to_csv(r’C:\Users\Administrator\Desktop\deep_learning\workspace\training_demo\annotation\test_labels.csv’, index=None)
print(‘Successfully converted xml to csv.’)

if name == ‘main’:
main()
创建一个名称xml_to_csv.py在下的新文件TensorFlow\scripts\preprocessing,打开它,将上面的代码粘贴到其中并保存
在pycharm中运行
一旦上述完成,应该有下2个新的文件training_demo\annotations夹,命名test_labels.csv和train_labels.csv分别。
转换*.csv为*.record
现在我们已经获得了*.csv注释文件,我们需要将它们转换为TFRecords。下面是一个示例脚本,允许我们这样做:

将CSV文件和图像数据整合为TFRecords

“”"
name: generate_tfrecord.py

Usage:

From tensorflow/models/

Create train data:

python generate_tfrecord.py --csv_input=data/train_labels.csv --output_path=train.record

Create test data:

python generate_tfrecord.py --csv_input=data/test_labels.csv --output_path=test.record
“”"

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 collections import namedtuple, OrderedDict

flags = tf.app.flags
flags.DEFINE_string('csv_input', '', 'Path to the CSV input')
flags.DEFINE_string('output_path', '', 'Path to output TFRecord')
FLAGS = flags.FLAGS


# TO-DO replace this with label map
def class_text_to_int(row_label):#修改类别
    if row_label == 'huge':
        return 1
    else:
        None


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, path):
    with tf.gfile.GFile(os.path.join(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(class_text_to_int(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(csv_input, output_path, image_path):
    writer = tf.python_io.TFRecordWriter(output_path)
    path = image_path
    examples = pd.read_csv(csv_input)
    grouped = split(examples, 'filename')
    for group in grouped:
        tf_example = create_tf_example(group, path)
        writer.write(tf_example.SerializeToString())

    writer.close()
    print('Successfully created the TFRecords: {}'.format(output_path))

if __name__ == '__main__':#修改路径
#     csv_input = r'C:\Users\Administrator\Desktop\deep_learning\workspace\training_demo\annotation\train_labels.csv'
#     output_path = r'C:\Users\Administrator\Desktop\deep_learning\workspace\training_demo\annotation\train.tfrecord'
#    image_path = r'C:\Users\Administrator\Desktop\deep_learning\workspace\training_demo\image\train'
#     main(csv_input, output_path, image_path)

    csv_input = r'C:\Users\Administrator\Desktop\deep_learning\workspace\training_demo\annotation\test_labels.csv'
    output_path = r'C:\Users\Administrator\Desktop\deep_learning\workspace\training_demo\annotation\test.tfrecord'
    image_path = r'C:\Users\Administrator\Desktop\deep_learning\workspace\training_demo\image\test'
    main(csv_input, output_path, image_path)在这里插入代码片

训练模型
在我们开始训练模型之前,让我们复制TensorFlow/models/research/object_detection/legacy/train.py脚本并将其直接粘贴到我们的training_demo文件夹中。我们需要这个脚本来训练我们的模型。

现在,要cd在training_demo文件夹中启动新的培训作业,请键入以下内容:

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

一旦开始培训过程,您应该看到一系列类似于下面的打印输出(加/减一些警告)

INFO:tensorflow:depth of additional conv before box predictor: 0
INFO:tensorflow:depth of additional conv before box predictor: 0
INFO:tensorflow:depth of additional conv before box predictor: 0
INFO:tensorflow:depth of additional conv before box predictor: 0
INFO:tensorflow:depth of additional conv before box predictor: 0
INFO:tensorflow:depth of additional conv before box predictor: 0
INFO:tensorflow:Restoring parameters from ssd_inception_v2_coco_2017_11_17/model.ckpt
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Starting Session.
INFO:tensorflow:Saving checkpoint to path training\model.ckpt
INFO:tensorflow:Starting Queues.
INFO:tensorflow:global_step/sec: 0
INFO:tensorflow:global step 1: loss = 13.8886 (12.339 sec/step)
INFO:tensorflow:global step 2: loss = 16.2202 (0.937 sec/step)
INFO:tensorflow:global step 3: loss = 13.7876 (0.904 sec/step)
INFO:tensorflow:global step 4: loss = 12.9230 (0.894 sec/step)
INFO:tensorflow:global step 5: loss = 12.7497 (0.922 sec/step)
INFO:tensorflow:global step 6: loss = 11.7563 (0.936 sec/step)
INFO:tensorflow:global step 7: loss = 11.7245 (0.910 sec/step)
INFO:tensorflow:global step 8: loss = 10.7993 (0.916 sec/step)
INFO:tensorflow:global step 9: loss = 9.1277 (0.890 sec/step)
INFO:tensorflow:global step 10: loss = 9.3972 (0.919 sec/step)
INFO:tensorflow:global step 11: loss = 9.9487 (0.897 sec/step)
INFO:tensorflow:global step 12: loss = 8.7954 (0.884 sec/step)
INFO:tensorflow:global step 13: loss = 7.4329 (0.906 sec/step)
INFO:tensorflow:global step 14: loss = 7.8270 (0.897 sec/step)
INFO:tensorflow:global step 15: loss = 6.4877 (0.894 sec/step)

如果您没有看到类似于上面所示的打印输出,和/或培训作业在几秒钟后崩溃,那么请查看常见问题部分下的问题和建议的解决方案,看看您是否能找到一个办法。或者,您可以尝试官方Tensorflow模型仓库的问题部分。

如果您正在观察与上述类似的输出,那么祝贺您已成功开始第一次培训工作。现在你可以很好地享受一杯冰镇啤酒,因为等待训练完成可能需要一段时间。按照人们在网上的说法,TotalLoss如果你想获得“公平”的检测结果,似乎建议让你的模型达到至少2(理想情况下是1和更低)。显然,TotalLoss越低越好,但是TotalLoss应该避免非常低,因为模型可能最终过度拟合数据集,这意味着当应用于数据集外的图像时它将表现不佳。要TotalLoss在您的模型进行培训时监控以及其他一些指标,请使用TensorBoard查看Monitor Training Job Progress。
使用TensorBoard监视训练作业进度
TensorFlow的一个非常好的功能是,它允许您在训练模型时连续监视和可视化许多不同的训练/检测性能指标。允许我们完成所有Tensorboard的特定工具。

要启动新的TensorBoard服务器,我们按照以下步骤操作:

打开一个新的Anaconda /命令提示符

激活您的TensorFlow conda环境(如果有的话),例如
打开一个新的Anaconda /命令提示符

激活您的TensorFlow conda环境(如果有的话),例如:

activate tensorflow_gpu
cd进入training_demo文件夹。

运行以下命令:

tensorboard --logdir=training
上面的命令将启动一个新的TensorBoard服务器,该服务器(默认情况下)侦听您机器的端口6006。假设一切顺利,您应该看到类似于下面的打印输出(加/减一些警告):

TensorBoard 1.6.0 at http://YOUR-PC:6006 (Press CTRL+C to quit)
完成此操作后,转到您的浏览器并输入http://YOUR-PC:6006您的地址栏,然后您将看到一个类似于下图所示的仪表板(如果您的模型刚刚开始培训,可能会少一些):
2019.6.27目标检测之自定义目标检测_第1张图片
导出训练推理图
完成培训工作后,您需要提取新训练的推理图,稍后将使用该图来执行对象检测。这可以按如下方式完成:

打开一个新的Anaconda /命令提示符

激活您的TensorFlow conda环境(如果有的话),例如:

activate tensorflow_gpu
复制TensorFlow/models/research/object_detection/export_inference_graph.py脚本并将其直接粘贴到您的training_demo文件夹中。

在training_demo/training文件夹中model.ckpt-*检查检验点文件,其中包含短划线名称后面的最大编号,例如model.ckpt-34350)。此数字表示创建文件的训练步骤索引。

或者,只需training_demo/training按降序时间对所有文件进行排序,然后选择model.ckpt-*列表中首先出现的文件。

记下文件的名称,因为当我们调用export_inference_graph.py脚本时它将作为参数传递。

现在,cd在您的training_demo文件夹中,运行以下命令:
python export_inference_graph.py --input_type image_tensor --pipeline_config_path training/ssd_inception_v2_coco.config --trained_checkpoint_prefix training/model.ckpt-13302 --output_directory trained-inference-graphs/output_inference_graph_v1.pb
已生成文件frozen_inference_graph.pb,这是您的模型
如何运行模型
现在你有了你的模型(frozen_inference_graph.pb)。

运行它

(tensorflow1) C:\tensorflow1\models\research\object_detection> python Object_detection_webcam.py

你可能感兴趣的:(目标检测)