MERCI SPACE
Навчальні матеріали

Лабораторна робота 19

Лабораторна робота №19. Створення згорткової нейронної мережі типу YOLO

Мета: ознайомитися з принципами роботи згорткових нейронних мереж для задач детекції об'єктів, опанувати YOLO (You Only Look Once) і бібліотеку Ultralytics для навчання й оцінювання моделі, обґрунтувати вибір порога впевненості для виробничого сценарію та визначити безпечну реакцію системи на невпевнений результат.

Результати навчання та передумови

Після виконання студент уміє:

  • перевіряти повноту й коректність розмітки датасету до навчання;
  • навчати й валідувати модель детекції на власному наборі;
  • інтерпретувати precision, recall, mAP і матрицю помилок;
  • обґрунтовувати поріг впевненості виходячи з ціни хибного спрацювання, а не з максимуму метрики;
  • вимірювати затримку й пропускну здатність моделі на цільовій платформі;
  • проєктувати безпечну реакцію на невпевнений або суперечливий результат розпізнавання.

Передумови: базовий Python, YAML, поняття навчальної, валідаційної та тестової вибірок. Апаратний допуск не потрібний.

Середовище виконання

СередовищеСтатусПримітка
Google ColabосновнеРекомендований GPU T4; доступність залежить від тарифу й лімітів Colab
Локальний ПКдозволеноПотрібні Python і Ultralytics; навчання без GPU може бути тривалим
Raspberry Piдозволено лише для перевірки експортованої моделіНавчання на Raspberry Pi у цій роботі не передбачене
Фізичний комплекс MERC-I5не потрібенВикористовується готовий набір зображень; рух обладнання не виконується

Необхідні знання та матеріали

  • базовий Python і робота з файлами YAML;
  • основи навчальної, валідаційної та тестової вибірок;
  • бібліотека Ultralytics і навчальний датасет із репозиторію first_labs;
  • достатнє місце для ваг моделі та каталогу runs;
  • правила зберігання датасетів MERC-I5;
  • ролі камер комплексу;
  • версії Python, Ultralytics і формату експорту: Потребує перевірки перед проведенням заняття.

Ризики та правила безпеки

Робота виконується з готовим набором зображень. Рух обладнання комплексу не виконується й не дозволений.

Заборонені дії

  • використовувати результат детекції як команду руху робота без окремого дозволу оператора;
  • підбирати поріг впевненості так, щоб отримати кращу метрику на тестовій вибірці, а потім звітувати цю метрику як незалежну;
  • навчати модель на вибірці, у якій ті самі кадри потрапили і в train, і в val;
  • оголошувати модель придатною для комплексу без вимірювання затримки на цільовій платформі.

Чому це критично

Помилка детекції в реальному сценарії призводить не до неправильного числа, а до захоплення роботом не тієї деталі або до руху в порожнє місце. Модель із високою метрикою, але низькою впевненістю на конкретному кадрі, небезпечніша за модель, яка чесно повідомляє «не впевнена».

Безпечний стан

Якщо впевненість нижча за поріг, класи суперечать один одному або детекцій більше, ніж очікувалося — виріб направляється в зону браку або цикл переходить у стан помилки. Автоматичне продовження з «найкращим здогадом» заборонене.

Хід виконання роботи

  1. Опрацювати методичні вказівки.
  2. Налаштувати робоче середовище та підключити необхідні бібліотеки.
  3. Перевірити повноту й коректність розмітки датасету.
  4. Виконати навчання моделі YOLO засобами Ultralytics.
  5. Провести валідацію й тестування, отримати метрики та матрицю помилок.
  6. Обґрунтувати поріг впевненості для виробничого сценарію.
  7. Виміряти затримку та пропускну здатність на цільовій платформі.
  8. Визначити безпечну реакцію на невпевнений результат.
  9. Оформити звіт і надіслати викладачу для перевірки.

Методичні вказівки й теоретичні відомості

1. Теоретичні відомості

Детекція об'єктів є одним із напрямків комп'ютерного зору, який поєднує класифікацію та локалізацію об'єктів на зображенні. Завданням детектора є визначення класу об'єкта та його координат у межах зображення за допомогою обмежувальних рамок.

YOLO (You Only Look Once) є однією з найпоширеніших архітектур для детекції об'єктів у режимі реального часу. На відміну від двоетапних алгоритмів, YOLO виконує пошук та класифікацію об'єктів за один прохід через нейронну мережу.

Принцип роботи алгоритму:

  • Зображення розбивається на сітку.

  • Кожна комірка прогнозує координати об'єктів.

  • Для кожного прогнозу визначається ймовірність належності до певного класу.

  • Після обробки застосовується алгоритм Non-Maximum Suppression (NMS), який усуває дублікати виявлених об'єктів.

Для навчання моделі використовуються текстові файли з анотаціями об'єктів.

Кожен рядок має формат:

Text
<class_id> <x_center> <y_center> <width> <height>

де:

class_id – номер класу;

x_center – координата центру по осі X;

y_center – координата центру по осі Y;

width – ширина рамки;

height – висота рамки.

Усі координати нормалізуються відносно розмірів зображення та належать діапазону від 0 до 1.

Навчання моделі включає:

  1. Підготовку набору даних.
  2. Формування структури каталогів.
  3. Опис датасету у файлі data.yaml.
  4. Процедуру навчання.
  5. Оцінювання якості моделі. Експорт і використання

2. Програмна реалізація

Набір даних

Для спрощення виконання лабораторної роботи вже створено навчальну вибірку зображень і проведено розмітку об'єктів, що будуть розпізнаватися камерою. Набір зображень розміщений у Git-репозиторії first_labs і має таку структуру.

Text
dataset/
├── images/
│   ├── train/
│   ├── val/
│   └── test/
└── labels/
    ├── train/
    ├── val/
    └── test/

Бібліотека Ultralytics

Ultralytics є офіційною Python-бібліотекою для роботи з моделями сімейства YOLO.

Встановлення бібліотеки:

Python
!pip install ultralytics

Підключення бібліотеки:

Python
from ultralytics import YOLO

Завантаження попередньо навченої моделі:

Python
model = YOLO("yolov8n.pt")

Навчання моделі:

Python
model.train(
    data="data.yaml",
    epochs=20,
    imgsz=640,
)

Тестування:

Python
metrics = model.val()
print(metrics)

Детекція об'єктів:

Python
results = model.predict(
    source="test.jpg",
    save=True,
)

Виконання лабораторної роботи

Крок 1. Підготовка середовища

Для швидшого процесу навчання перейдіть у розділ Середовище виконанняЗмінити тип середовища виконання та, якщо доступно, виберіть GPU T4.

Завантажте CV_library із вказаного репозиторію. Знайдіть каталог dataset та ознайомтеся з його вмістом. Імпортуйте Ultralytics і решту необхідних бібліотек.

У Google Colab виконайте:

Python
!git clone https://github.com/Chiptrees/first_labs
!pip install -r first_labs/requirements.txt
!pip install ultralytics

import matplotlib.pyplot as plt
import numpy as np

Очікуваний результат: репозиторій завантажено, каталог first_labs/dataset доступний, імпорт бібліотек завершується без помилок.

Критерій правильності: у вибраному середовищі відображається GPU, якщо він потрібен, а навчальні, валідаційні та тестові каталоги існують.

Якщо результат не отримано: перевірте журнал встановлення й доступний прискорювач; не запускайте навчання з відсутнім або неповним датасетом.

Крок 2. Створення yaml-файлу

Для навчання шаблону YOLO створіть файл формату .yaml.

Python
import yaml

data_yaml_path = "data.yaml"
data_config = {
    "path": "../first_labs/dataset",
    "train": "images/train",
    "val": "images/val",
    "test": "images/test",
    "names": {
        0: "red cube",
        1: "yellow celinder",
    },
}

with open(data_yaml_path, "w", encoding="utf-8") as file:
    yaml.dump(data_config, file, default_flow_style=False, allow_unicode=True)

Очікуваний результат: створено читабельний data.yaml із шляхами до трьох підвибірок і двома класами.

Критерій правильності: усі шляхи з data.yaml існують, а індекси класів відповідають анотаціям. Написання назви класу yellow celinder збережено відповідно до датасету; його виправлення потребує одночасної перевірки всіх анотацій.

Якщо результат не отримано: виведіть абсолютний шлях до датасету та перевірте кожен каталог окремо.

Крок 3. Навчання нейронної мережі

Із бібліотеки завантажте модель YOLOv8 Nano. Орієнтовний час залежить від доступного прискорювача; твердження про тривалість у 10 хвилин потребує перевірки для поточного середовища.

Python
from ultralytics import YOLO

model = YOLO("yolov8n.pt")
results = model.train(
    data="data.yaml",
    epochs=50,
    imgsz=320,
    batch=16,
    hsv_h=0.015,
    hsv_s=0.5,
    hsv_v=0.4,
    degrees=5,
    translate=0.1,
    scale=0.2,
    flipud=0.5,
    mosaic=0.5,
    name="custom_yolov8_model_v1",
)

Очікуваний результат: навчання завершується без аварій, а в runs/detect/custom_yolov8_model_v1/weights/ створюються best.pt і last.pt.

Критерій правильності: втрати й метрики записані для всіх запланованих епох, а файл best.pt завантажується через YOLO().

Якщо результат не отримано: збережіть журнал помилки, перевірте шляхи та доступну пам'ять; не оголошуйте частково створені ваги готовою моделлю.

Крок 4. Огляд результатів навчання

Після завершення навчання моделі YOLO у робочій директорії автоматично створюється папка runs, у якій зберігаються всі результати тренування, тестування та прогнозування моделі.

Типова структура директорії має вигляд:

Text
runs/detect/custom_yolov8_model_v1/
├── weights/
│   ├── best.pt
│   └── last.pt
├── results.csv
├── results.png
├── confusion_matrix.png
└── інші діагностичні файли

Призначення основних файлів:

  • best.pt – модель із найкращими показниками на валідаційній вибірці;

  • last.pt – модель після завершення останньої епохи навчання;

  • results.png – графіки процесу навчання;

  • results.csv – числові результати по кожній епосі;

  • confusion_matrix.png – матриця помилок класифікації;

  • predict/ – результати детекції на тестових зображеннях;

  • val/ – результати перевірки моделі на тестовій вибірці.

Text
Class             Images  Instances  Box(P)      R      mAP50  mAP50-95
all                   49        118   0.960   0.979      0.990      0.774
red cube              31         47   0.937   1.000      0.989      0.749
yellow celinder       41         71   0.984   0.958      0.992      0.799

Наведені числа є прикладом, а не гарантованим результатом конкретного запуску.

Після виконання перевірки функцією model.val(), крім технічної інформації (характеристики програмного середовища, інформація про модель) було отримуємо такі результативні показники:

Text
Scanning ... <images> images, <backgrounds> backgrounds, <corrupt> corrupt

Означає скільки зображень було протестовано, скільки зображень без об'єктів та скільки пошкоджених файлів

Text
Class  Images  Instances  Box(P  R  mAP50  mAP50-95)

Основні метрики якості де:

  • Precision (P) - характеризує точність спрацьовувань моделі Показує, яка частка знайдених об'єктів є правильними.

  • Recall (R) - показує, яку частину реальних об'єктів модель змогла знайти.

  • mAP50 - оцінює якість одночасно локалізації та класифікації об'єктів.

  • mAP50-95 - оцінювання проводиться для набору порогів IoU від 0.5 до 0.95. Вона є значно суворішою за mAP50 і вважається основною метрикою сучасних систем детекції.

Далі оцінка результатів загальна та для окремих класів

Text
all              ...
red cube         ...
yellow celinder  ...

Огляд графіків навчання

Графіки втрат і метрик навчання YOLO

Рис. 1. results.png

На рисунку results.png наведено зміну основних показників під час навчання мережі. Графіки train/ характеризують процес навчання на навчальних даних, val - перевірку на валідаційних.

  • box_loss - показує помилку визначення координат об'єктів на навчальній вибірці.

  • cls_loss - відображає помилку класифікації.

  • dfl_loss - (Distribution Focal Loss), інша помилка, яка використовується для більш точного визначення координат рамок.

Графіки змін метрик precision(B), recall(B), mAP50(B), mAP50-95(B) відображають зміну цих показників у процесі навчання.

Матриця помилок моделі YOLO

Рис. 2. Confusion Matrix.png

Матриця помилок (Confusion Matrix.png) використовується для оцінювання правильності класифікації кожного класу. Рядки матриці відповідають реальним класам об'єктів, а стовпці – передбаченим моделлю класам. Ідеальна матриця має найбільші значення на головній діагоналі.

Примітка: Зверніть увагу, що у матриці помилок значна кількість передбачень, віднесених до категорії background. Найімовірнішою причиною цього є неповна розмітка тестового набору даних. Під час перевірки модель виявляла об'єкти, які фактично були присутні на зображеннях, але не були позначені в анотаціях. У такому випадку система оцінювання інтерпретує правильне виявлення як помилкове спрацьовування. Таким чином, особливості матриці помилок можуть бути пов'язані не з роботою моделі, а з неповнотою вихідної розмітки даних.

Очікуваний результат: отримано метрики валідації, графік навчання та матрицю помилок, які можна пов'язати з конкретним запуском.

Критерій правильності: у звіті наведено власні, а не скопійовані прикладні значення precision, recall, mAP50 і mAP50-95, а також пояснено щонайменше одну помилку або аномалію.

Якщо результат не отримано: перевірте наявність best.pt, відповідність класів і повноту розмітки; не робіть висновок про якість моделі лише за навчальною втратою.

Крок 5. Експорт та використання моделі

Після завершення навчання модель YOLO може бути експортована у різні формати для подальшого використання на персональних комп'ютерах, мобільних пристроях або вбудованих системах. У даній лабораторній роботі виконується експорт моделі у формат TensorFlow Lite (TFLite), який призначений для запуску нейронних мереж на пристроях з обмеженими обчислювальними ресурсами.

Під час навчання більшість нейронних мереж використовують представлення чисел типу Float32. Кожне значення займає 32 біти пам'яті. Проте у даному коді є можливість змінити квантування на цілі числа типу Int8, які займають лише 8 біт.

За рахунок зменшення точності, математичні операції у такій моделі виконуються швидше. Завдяки цьому зменшується час відповіді, що дозволяє запускати її на пристроях із невеликими апаратними ресурсами

Це особливо корисно при використанні їх на мобільних пристроях,одноплатних комп'ютерів (Raspberry Pi), робототехнічних систем, вбудованих систем керування.

Оберіть один із двох режимів та запустіть код.

Python
from ultralytics import YOLO

int8_quantization = True
model = YOLO("/content/runs/detect/custom_yolov8_model_v1/weights/best.pt")
export_format = "tflite"

if int8_quantization:
    model.export(format=export_format, int8=True, data="data.yaml")
    print("Модель експортовано у TFLite з квантуванням INT8.")
else:
    model.export(format=export_format)
    print("Модель експортовано у TFLite у форматі Float32.")

Використання моделі:

Python
tflite_model_path = (
    "/content/runs/detect/custom_yolov8_model_v1/weights/best_int8.tflite"
)
test_images_dir = "/content/first_labs/dataset/images/test"
Розпізнавання жовтих циліндрів на конвеєрі

Рис. 3. Розпізнавання жовтих циліндрів

Розпізнавання червоного куба і жовтих циліндрів

Рис. 4. Розпізнавання об'єктів двох класів

Розпізнавання червоного куба біля грипера

Рис. 5. Розпізнавання червоного куба біля грипера

Очікуваний результат: модель експортовано у вибраний формат, вона відкривається без помилок і формує передбачення для тестових зображень.

Критерій правильності: у звіті порівняно розмір, метрики та час обробки хоча б одного зображення для початкової й експортованої моделей. Якщо вимірювання на Raspberry Pi не проводилося, це позначено явно.

Якщо результат не отримано: збережіть повідомлення експорту, перевірте створений шлях і сумісність середовища; не використовуйте файл, який не пройшов тестове завантаження.

Крок 6. Обґрунтування порога впевненості

Поріг впевненості — це не налаштування, яке підбирають під максимум метрики. Це інженерне рішення, яке залежить від ціни двох різних помилок:

ПомилкаЩо станеться в комірці MERC-I5Наслідок
Хибне спрацювання (низький поріг)робот спробує захопити те, чого немає, або віднесе деталь не в той боксзіпсований цикл, можливе зіткнення з конструкцією
Пропуск (високий поріг)деталь проїде повз, її не буде виявленодеталь не оброблена, але рух не небезпечний

Для навчального комплексу вартість хибного спрацювання вища, ніж вартість пропуску: невиявлена деталь просто йде в зону браку, а помилкове захоплення створює механічний ризик. Тому поріг обирають зміщеним у бік точності.

Побудуйте таблицю «поріг → precision → recall → кількість хибних спрацювань» щонайменше для п'яти значень і обґрунтуйте вибір.

Очікуваний результат: таблиця з п'яти рядків і письмове обґрунтування обраного значення.

Критерій правильності: обґрунтування спирається на наслідки помилки в сценарії, а не лише на найбільше число в таблиці.

Якщо результат не отримано: переконайтеся, що метрики обчислюються на тестовій вибірці, а не на валідаційній, яка вже впливала на навчання.

Крок 7. Вимірювання швидкодії на цільовій платформі

Модель, яка добре працює в Colab на GPU, може бути непридатною на Raspberry Pi. Виміряйте час одного передбачення на 30 послідовних кадрах і обчисліть середню затримку та пропускну здатність.

Python
import time

def measure_latency(model, image, runs: int = 30, warmup: int = 5):
    for _ in range(warmup):
        model.predict(source=image, verbose=False)
    samples = []
    for _ in range(runs):
        start = time.perf_counter()
        model.predict(source=image, verbose=False)
        samples.append(time.perf_counter() - start)
    samples.sort()
    return {
        "median_s": samples[len(samples) // 2],
        "p95_s": samples[int(len(samples) * 0.95) - 1],
        "fps": 1.0 / (sum(samples) / len(samples)),
    }

Очікуваний результат: медіанна затримка, 95-й процентиль і оцінка кадрів за секунду для кожного середовища, у якому ви запускали модель.

Критерій правильності: вимірювання виконане після прогріву; наведено p95, а не лише середнє.

Якщо результат не отримано: зафіксуйте, у якому середовищі вимірювання неможливе, і не переносьте показники з іншого середовища як власні.

Крок 8. Безпечна реакція на невпевнений результат

Реалізуйте функцію рішення, яка перетворює результат детекції на дію.

Python
def decide(detections: list[dict], threshold: float) -> dict:
    """detections: [{'label': str, 'confidence': float}, ...]"""
    confident = [d for d in detections if d["confidence"] >= threshold]
    if not confident:
        return {"action": "REJECT", "reason": "NO_CONFIDENT_DETECTION"}
    labels = {d["label"] for d in confident}
    if len(labels) > 1:
        return {"action": "ERROR", "reason": f"CONFLICTING_LABELS:{sorted(labels)}"}
    if len(confident) > 1:
        return {"action": "ERROR", "reason": "MULTIPLE_OBJECTS"}
    return {"action": "ROUTE", "label": confident[0]["label"]}

Очікуваний результат: три різні гілки — маршрут, зона браку, стан помилки.

Критерій правильності: жоден вхід не призводить до дії ROUTE з непевним або суперечливим результатом; функція ніколи не обирає «найімовірніший» клас із двох конфліктних.

Якщо результат не отримано: не додавайте правило «брати детекцію з найбільшою впевненістю» — саме воно й створює небезпечну поведінку.

Сценарії перевірки

  • Позитивний: модель правильно розпізнає представників обох класів на тестових зображеннях із впевненістю вище обраного порога.
  • Негативний: зображення без цільових об'єктів не створює впевнених хибних передбачень; такі випадки фіксуються та призводять до REJECT.
  • Суперечливий: два різні класи з високою впевненістю на одному об'єкті призводять до ERROR, а не до вибору «кращого».
  • Перевірка даних: відсутня або неповна анотація виявляється під час огляду датасету й враховується в інтерпретації матриці помилок.
  • Перевірка експорту: експортована модель завантажується та формує результат на тому самому контрольному зображенні.
  • Швидкодія: затримка виміряна після прогріву, наведено p95.

Таблиці вимірювань і метрики

Якість моделі

Параметр навчанняЗначення
Базова модель
Кількість епох
imgsz
Розмір train / val / test
МетрикаЗначення на valЗначення на test
precision
recall
mAP@0.5
mAP@0.5:0.95

Вибір порога

ПорігprecisionrecallХибних спрацюваньПропусків
0,25
0,40
0,50
0,65
0,80

Обраний поріг: … Обґрунтування: …

Швидкодія

СередовищеФормат моделіМедіана, сp95, сFPS
Colab GPUFP32
Локальний ПКFP32
Raspberry Pi 5FP32
Raspberry Pi 5INT8

Метрики: 0 випадків, коли суперечливий результат призвів до дії ROUTE; 0 кадрів, спільних для train і val; затримка виміряна після прогріву в кожному заявленому середовищі.

Вимоги до звіту

Виконайте загальні вимоги до звіту. Додатково додайте всі три таблиці вимірювань, графік навчання, матрицю помилок, приклади правильних і помилкових детекцій, порівняння початкової й експортованої моделей, обґрунтування порога впевненості та опис безпечної реакції на невпевнений результат.

Критерії оцінювання

Застосовується базова рубрика: підготовка — 10%, реалізація — 40%, перевірка — 25%, аналіз — 15%, звіт — 10%.

Контрольні питання

  1. Чим precision відрізняється від recall?
  2. Чому неповна розмітка може погіршити матрицю помилок навіть для правильного передбачення?
  3. Який компроміс виникає під час квантування FP32-моделі до INT8?
  4. Чому якість експортованої моделі потрібно повторно перевіряти?

Висновки

Напишіть висновки щодо виконаної роботи.

Посилання на лабораторну роботу №19 та приклад тут:

MERCI SPACE