YOLOv8 — это последняя версия модели YOLO (You Only Look Once), которая устанавливает стандарт для задач обнаружения объектов, классификации изображений и сегментации экземпляров. Разработанный Ultralytics, той же командой, которая создала широко используемую модель YOLOv5, YOLOv8 может похвастаться значительными архитектурными улучшениями и удобными для разработчиков функциями по сравнению с его предшественником.

Обучив YOLOv8 набору данных, который мы создали сами, мы увидим пример сегментации, выполненной в YOLOv8. Прежде всего, поскольку я не смогу опубликовать набор данных, с которым работаю, мы можем начать повествование, создав здесь новые данные. Мы создаем набор данных, содержащий квадраты разных размеров. Мы храним эти созданные данные изображения в трех папках: train, val и test. В этом уроке я буду использовать изображения из папок train и val. Я добавляю необходимую информацию внизу страницы, чтобы вы могли создать свою собственную среду для YOLO.

Создание набора данных

import numpy as np
from PIL import Image
from skimage import draw
import random
from pathlib import Path

def create_image(path, img_size, min_radius):
    path.parent.mkdir( parents=True, exist_ok=True )
    
    arr = np.zeros((img_size, img_size)).astype(np.uint8)
    max_radius = min(img_size//2, img_size//2)

    if min_radius > max_radius:
        min_radius = max_radius

    center_x = random.randint(min_radius, img_size - min_radius - 1)
    center_y = random.randint(min_radius, img_size - min_radius - 1)
    radius = random.randint(min_radius, max_radius)

    row_indxs, column_idxs = draw.rectangle((center_x - radius//2, center_y - radius//2), (center_x + radius//2, center_y + radius//2), shape=arr.shape)
    
    arr[row_indxs, column_idxs] = 255

    im = Image.fromarray(arr)
    im.save(path)

def create_images(data_root_path, train_num, val_num, test_num, img_size=640, min_radius=10):
    data_root_path = Path(data_root_path)
    
    for i in range(train_num):
        create_image(data_root_path / 'train' / 'images' / f'img_{i}.png', img_size, min_radius)
        
    for i in range(val_num):
        create_image(data_root_path / 'val' / 'images' / f'img_{i}.png', img_size, min_radius)
        
    for i in range(test_num):
        create_image(data_root_path / 'test' / 'images' / f'img_{i}.png', img_size, min_radius)

create_images('datasets', train_num=120, val_num=40, test_num=40, img_size=120, min_radius=10)

Теперь мы создадим метки набора данных, состоящего из созданных нами квадратов. Я поделюсь форматом данных для YOLOv8 ниже. Мы увидим разницу между YOLOv5 и YOLOv8 в объяснении в конце кодов.

Создание ярлыков

from rasterio import features

def create_label(image_path, label_path):
    arr = np.asarray(Image.open(image_path))

    # There may be a better way to do it, but this is what I have found so far
    cords = list(features.shapes(arr, mask=(arr >0)))[0][0]['coordinates'][0]
    label_line = '0 ' + ' '.join([f'{cord[0]/arr.shape[1]} {cord[1]/arr.shape[0]}' for cord in cords])

    label_path.parent.mkdir( parents=True, exist_ok=True )
    with label_path.open('w') as f:
        f.write(label_line)

for images_dir_path in [Path(f'datasets/{x}/images') for x in ['train', 'val', 'test']]:
    for img_path in images_dir_path.iterdir():
        label_path = img_path.parent.parent / 'labels' / f'{img_path.stem}.txt'
        create_label(img_path, label_path)

Мы создали данные изображений и их ярлыки. Пришло время установить нужную версию через «ультраликс». Пока я делюсь этой статьей, я установлю эту версию, потому что доступна версия 8.0.54. Но пока вы просматриваете эти коды, может быть выпущена новая версия, поэтому я поделюсь с вами кодом, необходимым для установки новой версии.

Установите ultralytics

pip install ultralytics==8.0.54
# !pip install --upgrade ultralytics
# You can view the version information you are using here.
import ultralytics
print(ultralytics.__version__)

Давайте посмотрим на содержимое data.yaml

Я объясню, каким должно быть содержимое data.yaml после кодов. Если вам интересно, вы можете посмотреть непосредственно на эту часть.

with open("C:/Users/Casper/Desktop/yolov8env/data.yaml") as file:
    yaml_content = file.read()

with Path('data.yaml').open('w') as f:
    f.write(yaml_content)

print(yaml_content)

Давайте обучим модель

Здесь мы использовали yolov8n-seg. Но есть разные варианты типа YOLOv8n YOLOv8s, YOLOv8m, YOLOv8l, YOLOv8x. Об этом мы тоже поговорим.

from ultralytics import YOLO

# Load a model
model = YOLO("yolov8n-seg.yaml")  # build a new model from scratch
model = YOLO("yolov8n-seg.pt")  # load a pretrained model (recommended for training)

# Train the model
model.train(data="C:/Users/Casper/Desktop/yolov8env/data.yaml", imgsz=120, epochs=50)

Выражение imgsz=120 используется для указания размера изображений. Здесь мы устанавливаем его на 120 пикселей. Другими словами, изображения, которые наша модель будет использовать на этапах обучения и оценки, будут иметь размер 120x120 пикселей. Этот размер может варьироваться в зависимости от набора данных и приложения, и можно попробовать разные значения.

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

Как видно выше, результаты обучения хранятся в файлах run/segment/train29.
Работа с 50 эпохами для этого набора данных займет у вас около 4 минут.

Проверить модель

from ultralytics import YOLO

# Load a model
model = YOLO("yolov8n-seg.pt")  # load an official model
model = YOLO("runs/segment/train29/weights/best.pt")  # load a custom model

# Validate the model
metrics = model.val()  # no arguments needed, dataset and settings remembered
metrics.box.map    # map50-95(B)
metrics.box.map50  # map50(B)
metrics.box.map75  # map75(B)
metrics.box.maps   # a list contains map50-95(B) of each category
metrics.seg.map    # map50-95(M)
metrics.seg.map50  # map50(M)
metrics.seg.map75  # map75(M)
metrics.seg.maps   # a list contains map50-95(M) of each category
metrics.confusion_matrix # confusion matrix

seg.map50 означает среднюю среднюю точность (mAP) при 50%-ном пороге пересечения над объединением (IoU). Эта метрика вычисляет точность прогноза модели путем измерения доли правильно определенных пикселей по отношению к истине при пороге 50% IoU.

seg.map75 обозначает среднюю среднюю точность (mAP) при 75% порога пересечения над объединением (IoU). Эта метрика вычисляет точность прогноза модели путем измерения доли правильно определенных пикселей по отношению к истине при пороге 75 % IoU.

seg.maps обозначает среднюю среднюю точность (mAP) по всем пороговым значениям IoU от 0,5 до 0,95 с размером шага 0,05. Этот показатель обеспечивает всестороннюю оценку эффективности модели сегментации в диапазоне пороговых значений IoU.

Давайте проверим значения f1, полноты и точности

#f1_score [0.94928]
print(metrics.seg.f1)

#recall [0.95]
print(metrics.seg.r)

#precision [0.94857]
print(metrics.seg.p)

Давайте посмотрим на результаты

from IPython.display import Image as show_image
show_image(filename="runs/segment/train29/val_batch0_labels.jpg")

show_image(filename="runs/segment/train29/val_batch0_pred.jpg")

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

show_image(filename="runs/segment/train29/confusion_matrix.png")

Теперь давайте рассмотрим YOLOv8.

train: «наборы данных/train/images» — это путь к папке, содержащей тренировочные изображения.

val: «datasets/val/images» означает путь к папке, содержащей проверочные изображения.

nc: 1 означает "количество классов" и представляет общее количество классов объектов в наборе данных. В этом случае есть только один класс — «квадрат».

имена: [‘квадрат’] – это список имен классов объектов в наборе данных. В этом случае есть только один класс, и он называется «квадрат».

Обратите внимание на эту проблему

Вот кое-что, на что мы должны обратить внимание.
Наше значение «nc» равно 1, поскольку в наборе данных есть только «квадрат». Но вскоре я покажу содержимое формата txt. В этой части мы будем писать 0 вместо 1 для «квадрата». Если вы запишете его как 1 в txt, вы получите ошибку индекса.
Другими словами, если бы у нас было всего 20 различных классов, наше значение «nc» было бы равно 20, но мы использовали бы его как 0– 19 при редактировании меток в txt.

Формат файла Txt

В наборе данных, который мы использовали, изображения были размером 120 x 120.
Давайте рассмотрим формат txt в этом наборе данных.
Первый столбец представляет наш класс, поэтому, поскольку у нас есть только один класс (квадрат), все они будут начинаться с 0. Затем он будет продолжаться как x1/120 y1/120 x2/120 y2/120.
Если нам нужно оценить его, например, в другом наборе данных, давайте предположим, что мы выполняем эти операции с изображениями размером 500x800. Затем будет создана текстовая структура типа x1/500 y1/800 x2/500 y2/800….

YOLOv8n, YOLOv8s, YOLOv8m, YOLOv8l, YOLOv8x

YOLOv8 — это современная модель обнаружения объектов, которую можно использовать для различных задач компьютерного зрения. 'n', 's', 'm', 'l' и ' Суффиксы x обозначают разные размеры моделей YOLOv8, которые различаются количеством слоев, параметрами и общей емкостью. Вот краткие пояснения для каждого размера:

YOLOv8n: базовая модель с наименьшим количеством слоев и наименьшими вычислительными затратами. Он подходит для приложений с ограниченными аппаратными ресурсами или где скорость является приоритетом.
YOLOv8s: небольшая версия YOLOv8 с меньшим количеством слоев и меньшей емкостью, чем модели среднего и большого размера. Он обеспечивает баланс между скоростью и точностью и подходит для приложений в реальном времени на устройствах со средней вычислительной мощностью.
YOLOv8m: модель среднего размера, которая имеет больше слоев и емкости, чем YOLOv8, но меньше, чем YOLOv8l и YOLOv8x. Он обеспечивает лучший компромисс между скоростью и точностью и подходит для приложений, где важны и то, и другое.
YOLOv8l: большая модель с большим количеством слоев и большей емкостью, чем YOLOv8m, но также с более высокая вычислительная стоимость. Он подходит для приложений, в которых высокая точность является приоритетом, а аппаратные ресурсы не являются ограничением.
YOLOv8x: самая большая и самая сложная модель в серии YOLOv8 с наибольшим количеством слоев и параметры. Это самая точная модель YOLOv8, но также и самая медленная и самая дорогая в вычислительном отношении, требующая мощного оборудования для эффективной работы. Он подходит для приложений, где важна высокая точность, а аппаратные ресурсы не являются ограничением.

n: Nano
s:Small
m: Medium
l: Большой
x: Очень большой

Создать среду

Я не буду объяснять здесь все этапы создания окружения, я просто добавлю git clone и часть требований. Я могу подробно объяснить настройку новой среды в другой статье YOLOv8.

 git clone https://github.com/ultralytics/ultralytics.git
 pip install -r requirements.txt

Вы видели мои другие статьи?