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

В Части I этой серии я прошел через этапы подготовки данных и обучения, необходимые для обучения глубокой нейронной сети на спутниковых снимках жилых районов, чтобы обнаруживать два класса (бассейны и автомобили). Напомню, что я использовал реализацию RetinaNet компании Fizyr Keras, обучил модель для 30 эпох на 640 изображениях и получил mAP 0,74.

Теперь, когда у меня есть обученные веса, я хочу использовать их для вывода - для генерации детектирования на ранее невидимых изображениях.

Полное руководство (начиная с Части I) демонстрирует сквозной рабочий процесс глубокого обучения для реализации детектора объектов с использованием архитектуры RetinaNet. Он организован следующим образом:

  1. Некоторые априорные варианты (обсуждаются в Части I этого сообщения)
  2. Загрузка и подготовка данных обучения (обсуждается в Части I этого сообщения)
  3. Обучение глубокой нейронной сети с помощью RetinaNet (обсуждается в Части I этого сообщения)
  4. Использование обученной модели для вывода

Этот пост посвящен Разделу 4.

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

4.1. Создание данных обнаружения ранее невидимых изображений

После того, как вы достигли точности, которой вы довольны, вы можете быстро использовать обученные веса для генерации обнаружения на ранее невидимых (тестовых) изображениях в два простых шага:

i. Преобразование модели - модели обучения, используемые для процедуры обучения keras-retinanet, представляют собой урезанные версии моделей вывода, которые нам нужны для прогнозирования. Учебные модели в основном содержат только те уровни, которые необходимы для обучения. Вот почему нам нужно преобразовать обучающую модель, сохраненную в /snapshots/, чтобы сделать ее полезной для вывода.

ii. Создавайте прогнозы (координаты класса и ограничивающего прямоугольника) и сохраняйте их как файл .csv.

Для этого я создаю image_inference_write.py файл и начинаю с создания парсера аргументов. Используя эти аргументы, я создаю переменные для входного пути, выходного пути, желаемого порога, пути к модели и пути к ранее сгенерированномуclass.csv. Затем я загружаю метки классов и модель вывода и создаю список изображений, на которых я хочу запустить обнаружение:

Затем я перебираю этот список путей изображения вывода каждый раз, когда создаю файл для хранения прогнозов, затем загружаю, обрабатываю и масштабирую изображения перед тем, как делать прогнозы с использованием model.predict_on_batch(). Обнаружения слабых мест отфильтровываются в соответствии с желаемым порогом (по умолчанию 0,5). Каждое действительное обнаружение, описываемое путем к изображению, оценкой достоверности, координатами его ограничивающего прямоугольника и его классом, затем записывается в файл CSV, который сохраняется в выходном каталоге.

После создания файла я могу запустить следующий сценарий, чтобы сгенерировать данные прогнозируемого обнаружения, сохраненные в указанном каталоге (аргумент -o):

# convert training model to inference model
!python /content/keras-retinanet/keras_retinanet/bin/convert_model.py '/content/snapshots/resnet50_csv_30.h5' '/content/snapshots/resnet50_csv_30_inference.h5'
inference_model = '/content/snapshots/resnet50_csv_30_inference.h5'
# generate predictions
!python /content/ije_retinanet/image_inference_write.py \
-i '/content/data/test_data_images/test_data_images/test/' \
-t 0.6 \
-m {inference_model} \
-o  /content/data/ \
-l /content/images_subset/classes.csv

Обратите внимание, что эта программа создает отдельный файл CSV для каждого изображения, содержащий все обнаружения, сделанные на этом одном изображении. В целях анализа может быть полезно объединить все выходные файлы в один, например:

# combine all csv files into one
fout=open("/content/data/output/out.csv","a")
# write header
fout.write("path,confidence,ymin,xmin,ymax,xmax,class\n")
# append files
for fi in glob.glob("/content/data/*.csv"):
  f = open(fi)
  for line in f:
    fout.write(line)
fout.close()

4.2. Создание изображений с ограничивающими рамками вокруг обнаруженных объектов

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

Я создаю image_inference_print.py файл и начинаю с настройки парсера аргументов, который позволяет мне указать программе на i. входной каталог изображений, на которых я хочу обнаруживать объекты, ii. путь к тренированным весам, и iii. путь к каталогу, в котором я хочу сохранить обнаружения. Он также предоставляет возможность указать настраиваемый порог для фильтрации слабых обнаружений, если я захочу поэкспериментировать со значениями, отличными от значения по умолчанию 0,5.

Как и раньше, я просматриваю список изображений, на которых хочу произвести обнаружение. Однако на этот раз, помимо предварительной обработки изображения и корректировки масштаба изображения, я делаю копию изображения для рисования, генерирую визуализацию обнаружений с помощью keras-retinanet инструментов на основе OpenCV и сохраняю вывод по пути, указанному в аргументах :

С этой программой я теперь могу легко генерировать выводы для моих тестовых изображений, используя следующий скрипт:

# create output directory where you want to save images with bounding boxes
!mkdir /content/data/output
# # uncomment if you haven't already converted training model to inference model
# !python /content/ije_retinanet/image_inference_print.py \
# -i /content/data/test_data_images/test_data_images/test/ \
# -t 0.6 \
# -m  {inference_model} \
# -o /content/data/output
# inference_model = '/content/snapshots/resnet50_csv_30_inference.h5'
# generate detections on images
!python /content/ije_retinanet/image_inference_print.py \
-i /content/data/test_data_images/test_data_images/test/ \
-t 0.6 \
-m  {inference_model} \
-o /content/data/output

Вот несколько примеров входных и выходных изображений:

И вуаля! Не идеально, но отличное начало.

Не стесняйтесь обращаться с любыми вопросами или комментариями.

Спасибо за внимание!

Вот ссылка на полную записную книжку:



Вот ссылка на мой репозиторий GitHub, содержащий полный код:



Части моего кода основаны на этом репозитории.