Распознавание объектов с помощью Tensorflow Object Detection API

искусственный интеллект

В школе есть эксперимент по распознаванию цитрусовых, поэтому я хочу использовать тензорный поток для обучения модели, которая распознает только цитрусовые с моим собственным тренировочным набором Поэтому, как следует, распознавание других объектов также может использовать этот метод для поиска данных для обучения.

полный код

Подготовка окружающей среды

  • Win10
  • Отличная видеокарта (особенно большой объем памяти, минимум 2G)
  • Anaconda
  • tensorflow 1.5
  • python 3.5
  • CUDA 9.0.167 (текущий официальный документ веб-сайта все еще может быть 8.0, но импорт pro-test ищет dll-файл версии 9.0)
  • cuDNN 7.0.5
  • protoc 3.5.1

Настройка среды вначале прошла относительно гладко, а установкаAnacondaЕсли да, то по инструкции на официальном сайте можно специально для обучения создать py-окружение с именем tensorflow, что и автор рекомендует.После установки версии tensorflow GPU поставитьCUDAиcuDNNТакже установлен в каталоге установки CUDAbinиlibnvvpКаталог должен быть добавлен в переменную системной среды. в cuDNNcudaРекомендуется распаковать каталог и поместить его в корневой каталог системного диска, аbinКаталог также добавляется в переменную окружения

Чтобы использовать пакет Object Detection, мы должны вручную скомпилировать файл proto в скрипт Python, который будетtensorflow/modelsПосле полной загрузки инструментом, используемым для компиляции, является protoc, загрузите сжатый пакет соответствующей системы, разархивируйте его на системный диск и поместитеbinКаталог добавляется в переменную окружения, после чего следуют шаги компиляции.документация по установке, Не забудьте поставитьmodelsкаталог иmodels/slimКаталоги добавляются к переменным среды. После успешной компиляции запустите тестовый сценарий, чтобы убедиться, что обнаружение объектов доступно. На этом этапе доступны пакеты, связанные с обнаружением объектов.

Примечание. Если по-прежнему отображается сообщение о том, что соответствующий модуль не найден, он должен находиться в соответствующей среде.site-packagesдобавить каталогtensorflow_model.pthфайл, содержание следующее

第一行是 research 的路径
第二行是 slim 的路径

Сделать тренировочный набор

  • Сканирование связанных изображений цитрусовых (похожих на другие объекты)

Этот шаг пропущен. Вы можете пройти его самостоятельно. Вы также можете щелкнуть правой кнопкой мыши на странице результатов поиска изображений Baidu и сохранить ее как веб-страницу. Получение данных не является целью этой статьи.

  • Обрезать изображение вручную

С одной стороны уменьшите громкость, а с другой постарайтесь отобразить характерный предмет.Учтите,что предмет не должен быть слишком большим.Лучше всего оставить часть фона без строгой проверки.

  • Маркировать картину

Может использоваться в среде winlabelimgДобавьте метки классификации к частям изображения, чтобы сделать наш набор данных.Если вы используете Mac, вы можете попробовать программу под названиемrectlabelПлатное приложение может выполнять более точный выбор кадра по признакам классификации изображений, эффект должен быть лучше и поддерживать вывод тегов изображения в формате PASCAL VOC.

Создание файлов TFRecord

Наши xml-файлы аннотаций классификации, сгенерированные изображением и labelimg, должны быть размещены следующим образом:

Project
.
├── annotations
│   ├── xmls
│   │   ├── tangerine_1.xml
│   │   └── tangerine_2.xml
│   └── trainval.txt
│
├── images
│   └── tangerine_1.jpg
│   └── tangerine_2.jpg
├── data
│   └── tangerine_label_map.pbtxt

Поскольку маркировка объектов изображения с помощью labelimg в этой статье уже соответствует формату оксфордского набора данных домашних животных, автор напрямую использует тот, который находится в каталоге моделей.скрипт конвертацииЧтобы преобразовать набор данных, который мы сделали сами, в файл TFRecord, требуемый документом, измените имя выходного файла наtangerine_train.recordиtangerine_val.record, запустить скрипт конвертации, параметрыdata_dirТо есть в указанном выше дереве каталоговProjectкаталог,output_dirэто выходной каталог,label_map_pathэто мыtangerine_label_map.pbtxtПуть к файлу сценария, по умолчанию используется 30% данных изображения в качестве тестового набора, который можно изменить в соответствии с вашей собственной ситуацией.

Детская обувь, которая обращает внимание на дерево каталогов, может обнаружить, чтоannotationsВ каталоге есть еще одинtrainval.txtфайл, потому что для обнаружения объекта необходимо прочитать каждую строку в нем, чтобы прочитать соответствующий файл xml, а затем прочитать соответствующее изображение jpg в соответствии с содержимым тегов имени файла и пути в xml. Поэтому нам нужно записать все имена файлов xml (без расширения) в виде одной строки файлаtrainval.txtи убедитесь, что он размещен в месте, показанном в дереве каталогов, каждый Содержимое тега имени файла в xml-файле также необходимо изменить на вид с расширением.Здесь я написал несколько скриптов для автоматической модификации в пакетном режиме.

Инструкции по применению:

  • clean_data.py используется для переименования изображений и файлов xml в том же каталоге в обычные имена.
  • gen_trainval.py используется для генерацииtrainval.txtдокумент
  • xml_modify.py используется для изменения части файла xml, чтобыcreate_tangerine_tf_record.pyМожет успешно найти изображение по логотипу, указанному внутри, и сгенерировать TFRecord.

Пожалуйста, прочитайте комментарии к коду для получения подробной информации об использовании

Выберите модель и измените соответствующий файл конфигурации

Модель, используемая в этой статье, представляет собой набор данных кокоса.faster_rcnn_resnet101Модель, если вы хотите использовать предварительно обученную модель, нам нужно загрузить сжатый пакет модели и добавить к нему префиксmodel.ckptраспаковать файлы в нашуProject/trainingПод содержанием,faster_rcnn_resnet101_coco.configявляется соответствующим файлом модели, в которомPATH_TO_BE_CONFIGUREDИзмените часть самостоятельно.Во время обучения tensorflow прочитает соответствующий файл модели, тренировочный набор, тестовый набор и метку, прочитав файл конфигурации.Если вам нужно изменить количество шагов обучения, чтобы сократить время обучения, вы можете изменить егоnum_steps

Обучение модели и просмотр эффекта

тренировочная команда

# 在 research 目录下
$ python object_detection/train.py --logtostderr --pipeline_config_path=E:/DL/tangerine-recognition/faster_rcnn_resnet101_coco.config --train_dir=E:/DL/tangerine-recognition/training

Откройте тензорную доску, чтобы увидеть, как функция потерь меняется во время обучения.

$ tensorboard --logdir=E:/DL/tangerine-recognition/training --port=6006 --host=localhost
# 访问 localhost:6006

Откройте тензорную доску, чтобы увидеть влияние модели на тестовый набор.

# 在 research 目录下
$ python object_detection/eval.py --logtostderr --pipeline_config_path=E:/DL/tangerine-recognition/faster_rcnn_resnet101_coco.config --eval_dir=E:/DL/tangerine-recognition/eval --checkpoint_dir=E:/DL/tangerine-recognition/training

$ tensorboard --logdir=E:/DL/tangerine-recognition/eval --port=6006 --host=localhost

# 访问 localhost:6006,右上角选择 image

tensorboard

Экспорт обученной модели

# 在 research 目录下
$ python object_detection/export_inference_graph.py --input_type image_tensor --pipeline_config_path E:/DL/tangerine-recognition/faster_rcnn_resnet101_coco.config --trained_checkpoint_prefix E:/DL/tangerine-recognition/training/model.ckpt-{设置的步数} --output_directory E:/DL/tangerine-recognition/training/result

В каталоге результатов вы можете увидеть нашиfrozen_inference_graph.pbГрафические модели, готовые к развертыванию в рабочей среде

Используйте python для вызова обученной модели для распознавания

# demo.py
import cv2
import numpy as np
import tensorflow as tf
from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as vis_util


class TOD(object):
    def __init__(self):
        self.PATH_TO_CKPT = 'E:\\DL\\tangerine-recognition\\training\\result\\frozen_inference_graph.pb'
        self.PATH_TO_LABELS = 'E:\\DL\\tangerine-recognition\\tangerine_label_map.pbtxt'
        self.NUM_CLASSES = 1
        self.detection_graph = self._load_model()
        self.category_index = self._load_label_map()

    def _load_model(self):
        detection_graph = tf.Graph()
        with detection_graph.as_default():
            od_graph_def = tf.GraphDef()
            with tf.gfile.GFile(self.PATH_TO_CKPT, 'rb') as fid:
                serialized_graph = fid.read()
                od_graph_def.ParseFromString(serialized_graph)
                tf.import_graph_def(od_graph_def, name='')
        return detection_graph

    def _load_label_map(self):
        label_map = label_map_util.load_labelmap(self.PATH_TO_LABELS)
        categories = label_map_util.convert_label_map_to_categories(label_map,
                                                                    max_num_classes=self.NUM_CLASSES,
                                                                    use_display_name=True)
        category_index = label_map_util.create_category_index(categories)
        return category_index

    def detect(self, image):
        with self.detection_graph.as_default():
            with tf.Session(graph=self.detection_graph) as sess:
                # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
                image_np_expanded = np.expand_dims(image, axis=0)
                image_tensor = self.detection_graph.get_tensor_by_name('image_tensor:0')
                boxes = self.detection_graph.get_tensor_by_name('detection_boxes:0')
                scores = self.detection_graph.get_tensor_by_name('detection_scores:0')
                classes = self.detection_graph.get_tensor_by_name('detection_classes:0')
                num_detections = self.detection_graph.get_tensor_by_name('num_detections:0')
                # Actual detection.
                (boxes, scores, classes, num_detections) = sess.run(
                    [boxes, scores, classes, num_detections],
                    feed_dict={image_tensor: image_np_expanded})
                # Visualization of the results of a detection.
                vis_util.visualize_boxes_and_labels_on_image_array(
                    image,
                    np.squeeze(boxes),
                    np.squeeze(classes).astype(np.int32),
                    np.squeeze(scores),
                    self.category_index,
                    use_normalized_coordinates=True,
                    line_thickness=8)

        cv2.namedWindow("detection", cv2.WINDOW_NORMAL)
        cv2.imshow("detection", image)
        cv2.waitKey(0)

if __name__ == '__main__':
    image = cv2.imread('image.jpg')
    detecotr = TOD()
    detecotr.detect(image)

окончательный эффект

demo-result

использованная литература

Для коммерческих перепечаток, пожалуйста, свяжитесь с автором для авторизации Для некоммерческих перепечаток, пожалуйста, укажите источник Спасибо за сотрудничество!

Контактное лицо: tecker_yuknigh@163.com

reward-code