Точная настройка моделей YOLOv8 для пользовательских приложений компьютерного зрения
Добро пожаловать в третью и последнюю часть нашей серии из трех частей о YOLOv8! В этой серии мы покажем вам, как работать с YOLOv8, от загрузки готовых моделей до точной настройки этих моделей для конкретных случаев использования и всего, что между ними.
На протяжении всей серии мы будем использовать две библиотеки: FiftyOne, набор инструментов компьютерного зрения с открытым исходным кодом, и Ultralytics, библиотеку, которая даст нам доступ к YOLOv8.
Здесь, в части 3, мы покажем, как точно настроить модель YOLOv8 для вашего конкретного варианта использования.
Этот пост организован следующим образом:
- Обзор частей 1 и 2
- Определение нашего варианта использования
- Выбор обучающих данных
- Тонкая настройка модели YOLOv8
- Оценка улучшения
Продолжайте читать, чтобы узнать, как включить модели YOLOv8 в рабочие процессы компьютерного зрения!
Резюме частей 1 и 2
В Части 1 мы загрузили проверочное разделение набора данных COCO 2017 в FiftyOne с обнаружением наземных объектов. Затем мы сгенерировали прогнозы с помощью модели обнаружения YOLOv8n из Ultralytics YOLOv8 Github и добавили их в наш набор данных в поле метки yolov8n
наших образцов.
Во Части 2 мы использовали Evaluation API FiftyOne для оценки качества этих обнаружений. Мы обнаружили, что эта базовая модель имеет относительно хорошую точность, но имеет проблемы с отзывом для определенных классов. Когда мы углубились в детали, мы увидели, что для некоторых классов, таких как класс book
, несовершенства в метках истинности COCO были, по крайней мере, частью проблемы, но для других классов, таких как bird
, модель могла бы выиграть от точной настройки на более широкий набор примеров.
Обнаружение птиц с помощью YOLOv8
precision recall f1-score support person 0.85 0.68 0.76 11573 car 0.71 0.52 0.60 1971 chair 0.62 0.34 0.44 1806 book 0.61 0.12 0.20 1182 bottle 0.68 0.39 0.50 1051 cup 0.61 0.44 0.51 907 dining table 0.54 0.42 0.47 697 traffic light 0.66 0.36 0.46 638 bowl 0.63 0.49 0.55 636 handbag 0.48 0.12 0.19 540 bird 0.79 0.39 0.52 451 boat 0.58 0.29 0.39 430 truck 0.57 0.35 0.44 415 bench 0.58 0.27 0.37 413 umbrella 0.65 0.52 0.58 423 cow 0.81 0.61 0.70 397 banana 0.68 0.34 0.45 397 carrot 0.56 0.29 0.38 384 motorcycle 0.77 0.58 0.66 379 backpack 0.51 0.16 0.24 371 micro avg 0.76 0.52 0.61 25061 macro avg 0.64 0.38 0.47 25061 weighted avg 0.74 0.52 0.60 25061
Как мы видели в предыдущем разделе, несмотря на то, что YOLOv8 имеет достойную производительность из коробки, он может не подходить для конкретных случаев использования без некоторых модификаций. Например, для класса bird
базовая модель YOLOv8n достигла полноты только 39%.
Предположим, вы работаете в группе по охране птиц, внедряя модели компьютерного зрения в полевые условия для отслеживания и защиты исчезающих видов. Ваша цель — обнаружить в режиме реального времени как можно больше птиц.
Учитывая скорость вывода, архитектура YOLOv8 кажется очевидным выбором. Однако вы не удовлетворены отзывом 39% в отчете об оценке данных проверки COCO. Поскольку это приложение с высокими ставками, вы хотите выжать все возможное из этой архитектуры обнаружения в реальном времени.
Если вы хотите, вы можете обучить новую модель обнаружения YOLOv8 с нуля, как показано в Руководстве по быстрому запуску YOLOv8, но в идеале вы хотели бы использовать существующие знания предварительно обученной модели. К счастью, настроить существующую модель YOLOv8 довольно просто.
Прежде чем продолжить, давайте упростим нашу задачу. Гибкий язык запросов, встроенный в FiftyOne, позволяет легко нарезать наборы данных и находить интересные представления всего за одну строку кода или нажатие кнопки в приложении.
На данный момент у нас есть FiftyOne с нашими проверочными изображениями COCO, обнаружением истинности и прогнозами YOLOv8n в поле метки yolov8n
для каждого образца. Учитывая, что в нашем случае нас интересует только обнаружение птиц, давайте создадим тестовый набор, отфильтровав все не-bird
наземные обнаружения правды, используя filter_labels()
. Мы также будем отфильтровывать прогнозы, отличные от bird
, но передадим аргумент only_matches = False
в filter_labels()
, чтобы убедиться, что мы сохраняем изображения, которые имеют наземные истинные обнаружения bird
без прогнозов YOLOv8n bird
.
test_dataset = dataset.filter_labels( "ground_truth", F("label") == "bird" ).filter_labels( "yolov8n", F("label") == "bird", only_matches=False ).clone() test_dataset.name = "birds-test-dataset" test_dataset.persistent = True ## set classes to just include birds classes = ["bird"]
Затем мы даем набору данных имя, делаем его постоянным и сохраняем в базовой базе данных. В этом тестовом наборе всего 125 изображений, которые мы можем визуализировать в FiftyOne App.
Мы также можем запустить evaluate_detections()
на этих данных, чтобы оценить производительность модели YOLOv8n на изображениях с обнаружением птиц на земле. Мы будем хранить результаты под ключом оценки base
:
base_bird_results = test_dataset.evaluate_detections( "yolov8n", eval_key="base", compute_mAP=True, ) print(base_bird_results.mAP()) ## 0.24897924786479841 base_bird_results.print_report(classes=classes) precision recall f1-score support bird 0.87 0.39 0.54 451
Мы отмечаем, что, хотя отзыв такой же, как и в первоначальном отчете об оценке для всего разделения проверки COCO, точность выше. Это означает, что есть изображения, которые имеют предсказания YOLOv8n bird
, но неназемные обнаружения bird
.
Последним шагом в подготовке этого тестового набора является экспорт данных в формат YOLOv8, чтобы мы могли выполнить вывод только на этих образцах с помощью нашей точно настроенной модели, когда мы закончим обучение. Мы сделаем это, используя функцию export_yolo_data()
, которую мы определили в Части 1.
export_yolo_data( test_dataset, "birds_test", classes )
Выбор обучающих данных
Наиболее важным компонентом тонкой настройки модели являются данные, на которых модель обучается. Если мы хотим, чтобы наша модель демонстрировала высокую производительность на определенном подмножестве данных, наша цель должна заключаться в создании высококачественного обучающего набора данных, примеры которого охватывают все ожидаемые сценарии в этом подмножестве.
Это и искусство, и наука. Это может включать в себя извлечение данных из других наборов данных, аннотирование большего количества данных, которые вы уже собрали, с помощью меток истинности, дополнение ваших данных с помощью таких инструментов, как альбументации, или создание синтетических данных с помощью моделей распространения или GAN.
В этой статье мы воспользуемся первым подходом и включим существующие высококачественные данные из набора данных Open Images Google. Подробное руководство по работе с данными Open Images см. в разделе Загрузка Open Images V6 и пользовательских наборов данных с помощью FiftyOne.
Данные обучения COCO, на которых обучался YOLOv8, содержат 3237 изображений с bird
обнаружениями. Открытые изображения более обширны: обучение, тестирование и проверка разделены на более чем 20 000 изображений с Bird
обнаружениями.
Давайте создадим наш обучающий набор данных. Во-первых, мы создадим набор данных train_dataset
, загрузив метки обнаружения bird
из разделения поезда COCO с помощью FiftyOne Dataset Zoo и клонировав его в новый объект Dataset
:
train_dataset = foz.load_zoo_dataset( 'coco-2017', split='train', classes=classes ).clone() train_dataset.name = "birds-train-data" train_dataset.persistent = True train_dataset.save()
Затем мы загрузим образцы Open Images с Bird
метками обнаружения, передав only_matching=True
, чтобы загрузить только Bird
меток. Затем мы преобразуем эти метки в формат меток COCO, заменив Bird
на bird
.
oi_samples = foz.load_zoo_dataset( "open-images-v6", classes = ["Bird"], only_matching=True, label_types="detections" ).map_labels( "ground_truth", {"Bird":"bird"} )
Мы можем добавить эти новые образцы в наш набор обучающих данных с помощью merge_samples()
:
train_dataset.merge_samples(oi_samples)
Этот набор данных содержит 24 226 образцов с метками bird
, что более чем в семь раз превышает количество птиц, на которых обучалась базовая модель YOLOv8n. В следующем разделе мы покажем, как настроить модель на этих данных с помощью класса YOLO Trainer.
Тонкая настройка YOLOv8 для индивидуального варианта использования
Последним шагом в подготовке наших данных является их разделение на наборы для обучения и проверки и экспорт в формат YOLO. Мы будем использовать разбиение поездов на 80–20, которое мы выберем случайным образом с помощью случайных утилит FiftyOne.
import fiftyone.utils.random as four ## delete existing tags to start fresh train_dataset.untag_samples(train_dataset.distinct("tags")) ## split into train and val four.random_split( train_dataset, {"train": 0.8, "val": 0.2} ) ## export in YOLO format export_yolo_data( train_dataset, "birds_train", classes, split = ["train", "val"] )
Теперь осталось заняться тонкой настройкой! Мы будем использовать тот же синтаксис командной строки YOLO, но вместо установки mode=predict
мы установим mode=train
. Мы укажем начальные веса в качестве отправной точки для обучения, количество эпох, размер изображения и размер пакета.
yolo task=detect mode=train model=yolov8n.pt data=birds_train/dataset.yaml epochs=100 imgsz=640 batch=16
Для тонкой настройки я использовал NVIDIA TITAN GPU. Я настроил обучение на 100 эпох, но в основном оно сходилось после 60 эпох, поэтому я остановился на этом. Вы можете обнаружить, что ваш конкретный вариант использования требует меньшего или потенциально большего количества итераций для достижения желаемой производительности.
Image sizes 640 train, 640 val Using 8 dataloader workers Logging results to runs/detect/train Starting training for 100 epochs... Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 1/100 6.65G 1.392 1.627 1.345 22 640: 1 Class Images Instances Box(P R mAP50 m all 4845 12487 0.677 0.524 0.581 0.339 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 2/100 9.58G 1.446 1.407 1.395 30 640: 1 Class Images Instances Box(P R mAP50 m all 4845 12487 0.669 0.47 0.54 0.316 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 3/100 9.58G 1.54 1.493 1.462 29 640: 1 Class Images Instances Box(P R mAP50 m all 4845 12487 0.529 0.329 0.349 0.188 ...... Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 58/100 9.59G 1.263 0.9489 1.277 47 640: 1 Class Images Instances Box(P R mAP50 m all 4845 12487 0.751 0.631 0.708 0.446 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 59/100 9.59G 1.264 0.9476 1.277 29 640: 1 Class Images Instances Box(P R mAP50 m all 4845 12487 0.752 0.631 0.708 0.446 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 60/100 9.59G 1.257 0.9456 1.274 41 640: 1 Class Images Instances Box(P R mAP50 m all 4845 12487 0.752 0.631 0.709 0.446
После завершения тонкой настройки мы можем генерировать прогнозы на основе наших тестовых данных с «лучшими» весами, найденными в процессе обучения, которые хранятся в runs/detect/train/weights/best.pt
:
yolo task=detect mode=predict model=runs/detect/train/weights/best.pt source=birds_test/images/val save_txt=True save_conf=True
И загрузите эти прогнозы в наши данные и визуализируйте прогнозы в приложении FiftyOne:
filepaths = test_dataset.values("filepath") prediction_filepaths = [get_prediction_filepath(fp, run_number=2) for fp in filepaths] test_dataset.set_values( "yolov8n_bird_det_filepath", prediction_filepaths ) add_yolo_detections( birds_test_dataset, "yolov8n_bird", "yolov8n_bird_det_filepath", classes )
Оценка улучшения
На целостном уровне мы можем сравнить производительность точно настроенной модели с исходной, предварительно обученной моделью, сопоставив их стандартные метрики друг с другом.
Самый простой способ получить эти показатели — использовать Evaluation API от FiftyOne:
finetune_bird_results = test_dataset.evaluate_detections( "yolov8n_bird", eval_key="finetune", compute_mAP=True, )
Из этого мы можем сразу увидеть улучшение средней точности (mAP):
print("yolov8n mAP: {}.format(base_bird_results.mAP())) print("fine-tuned mAP: {}.format(finetune_bird_results.mAP())) yolov8n mAP: 0.24897924786479841 fine-tuned mAP: 0.31339033693212076
Распечатав отчет, мы видим, что отзыв улучшился с 0,39 до 0,56. Это значительное улучшение компенсирует незначительное снижение точности, давая в целом более высокий балл F1 (0,67 по сравнению с 0,54).
precision recall f1-score support bird 0.81 0.56 0.67 506
Мы также можем более внимательно рассмотреть отдельные изображения, чтобы увидеть, где у отлаженной модели возникают проблемы. Когда мы это делаем, мы видим, что модель изо всех сил пытается правильно обрабатывать мелкие функции. Это справедливо как для ложноположительных, так и для ложноотрицательных результатов.
Эта низкая производительность может быть частично связана с качеством данных, поскольку многие из этих функций являются зернистыми. Это также может быть связано с параметрами обучения, поскольку как для предварительного обучения, так и для точной настройки для этой модели использовался размер изображения 640 пикселей, что может не позволить захватывать мелкие детали.
Чтобы еще больше улучшить производительность модели, мы могли бы попробовать различные подходы, в том числе:
- Использование увеличения изображения для увеличения доли изображений с маленькими птицами
- Сбор и аннотирование большего количества изображений с маленькими птицами
- Увеличение размера изображения во время тонкой настройки
Заключение
Тонкая настройка, представленная в предыдущем разделе, предназначена только для иллюстрации.
Несмотря на то, что YOLOv8 представляет собой шаг вперед в моделях обнаружения и сегментации объектов в реальном времени, изначально он предназначен для использования в общих целях. Перед развертыванием модели важно понять, как она работает с вашими данными. Только тогда вы сможете эффективно настроить архитектуру YOLOv8 в соответствии со своими конкретными потребностями.
В этой серии мы показали вам, как вы можете использовать FiftyOne для визуализации, оценки и лучшего понимания прогнозов модели YOLOv8.
В то время как YOLO может посмотреть только один раз, добросовестный инженер по компьютерному зрению или исследователь наверняка посмотрит дважды (или больше)!
Присоединяйтесь к сообществу FiftyOne!
Присоединяйтесь к тысячам инженеров и специалистов по данным, уже использующих FiftyOne для решения некоторых из самых сложных задач в области компьютерного зрения уже сегодня!
- 1350+ участников FiftyOne Slack
- 2550+ звезд на GitHub
- 3200+ Участников встречи
- Использовано 245+ репозиториев
- 56+ авторов
Что дальше?
- Если вам нравится то, что вы видите на GitHub, поставьте звезду проекту.
- "Начать!" Мы упростили запуск и запуск за несколько минут.
- Присоединяйтесь к сообществу Slack FiftyOne, мы всегда рады помочь.
Первоначально опубликовано на https://voxel51.com 21 февраля 2023 г.