Klasyfikacja obrazów
Klasyfikacja obrazów przypisuje jeden rozkład etykiet do całego obrazu i nie lokalizuje żadnych elementów. Kluczem zadania jest classify.
Definicja
Klasyfikacja obrazów tworzy jeden wskaźnik na klasę dla całego obrazu i nie zwraca żadnych współrzędnych. Odpowiada na pytanie, co znajduje się na obrazie, a nigdy gdzie, co odróżnia ją od detekcji obiektów.
classify jest kanonicznym kluczem zadania, a sufiks -cls w nazwie pliku
checkpointu je wybiera. Ten sufiks jest wymagany, a nie opcjonalny dla rodzin
klasyfikacyjnych. Dlatego LibreResNet50.pt nie jest interpretowany jako
klasyfikator, a LibreResNet50-cls.pt już tak.
Funkcja predict() wypełnia result.probs i pozostawia boxes puste. .data
jest pełnym wektorem wskaźników, .top1 indeksem największego wskaźnika, a
.top1conf jego wartością. .top5 zawiera pięć największych indeksów w
kolejności malejącej, a .top5conf ich wskaźniki. Indeksy odwołują się do
result.names. Wycinanie obiektu Results nigdy nie skraca probs, ponieważ
wektor należy do obrazu, a nie do pojedynczego wiersza.
Modele
Klasyfikatory obrazów z obsługą trenowania obejmują:
ResNet, ConvNeXt,
MobileNetV4,
EfficientNetV2 oraz
DINOv2. Pierwsze cztery działają z pakietem bazowym i
mają opublikowane wagi. DINOv2 wymaga pip install "libreyolo[rfdetr]" i nie ma
checkpointu hostowanego przez LibreYOLO. Wczytuje backbone projektu źródłowego
z losowo inicjowaną głowicą liniową, dlatego stanowi punkt początkowy do
dostrajania, a nie gotowy model predykcyjny.
Kolejnych pięć rodzin obsługuje predykcję, walidację i eksport, ale ich funkcja
train() zgłasza NotImplementedError: ViT,
Swin, VGG,
AlexNet oraz DeiT.
CLIP i SigLIP2 klasyfikują bez
stałego zestawu etykiet. Oceniają obraz względem promptów tekstowych, dlatego
set_classes() definiuje klasy podczas wywołania i w ogóle nie ma etapu
trenowania dla nowego zestawu etykiet. Obie rodziny obsługują również zadanie
embed.
ConvNeXt V2 dodaje klasyfikację nadzorowaną ze wstępnie wytrenowanymi wagami CC-BY-NC-4.0. PE obsługuje klasyfikację zero-shot; V-JEPA 2 trenuje sondy klasyfikacji wideo.
Predykcja
Przy pierwszym użyciu wagi są pobierane z Hugging Face i zapisywane w lokalnej pamięci podręcznej.
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Sufiks -cls w nazwie pliku wybiera zadanie, więc argument task# nie jest potrzebny.model = LibreYOLO("LibreResNet50-cls.pt")result = model(SAMPLE_IMAGE, save=True) print(result.names[result.probs.top1], float(result.probs.top1conf))print(result.probs.top5)libreyolo predict model=LibreResNet50-cls.pt save=True \ source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpgfrom libreyolo import LibreYOLO, SAMPLE_IMAGE result = LibreYOLO("LibreResNet50-cls.pt")(SAMPLE_IMAGE)probs = result.probs # .data jest pełnym wektorem (C,), a top5/top5conf to uporządkowane widoki.print(probs.data.shape)for index, score in zip(probs.top5, probs.top5conf): print(result.names[index], float(score))from libreyolo import LibreYOLO, SAMPLE_IMAGE # CLIP ocenia obraz względem promptów tekstowych, dlatego zestaw etykiet# ustala się przy wywołaniu, zamiast zapisywać w checkpointcie.model = LibreYOLO("LibreCLIPb32-cls.pt")model.set_classes(["a person jumping", "an empty street", "a parked car"])result = model(SAMPLE_IMAGE) print(model.names[result.probs.top1], float(result.probs.top1conf))Argumenty conf, iou i max_det nie mają tutaj wpływu. Nie ma kandydatów do
filtrowania progiem ani tłumienia, a jedynie jeden rozkład. Informacje o
źródłach, streamingu i obsłudze wyników zawiera strona
predykcji.
Format zbioru danych
Klasyfikacja korzysta z drzewa katalogów, a nie z plików etykiet ani pliku YAML.
data jest katalogiem głównym zbioru danych.
dataset/ train/ tench/000001.jpg parachute/000002.jpg val/ tench/000101.jpg parachute/000102.jpgtrain/ jest wymagany do trenowania i definiuje mapowanie klas na indeksy na
podstawie posortowanych nazw folderów. Pierwszy folder alfabetycznie staje się
klasą 0. val/ jest wymagany do walidacji. Podział test/ może być obecny,
ale domyślne polecenia trenowania i walidacji go nie używają. Każdy podział
inny niż train musi zawierać te same nazwy folderów klas co oczekiwany zestaw
klas. Dzięki temu niezgodność powoduje wyraźny błąd, a nie ocenę jako błędna
predykcja. Akceptowane rozszerzenia obrazów to .jpg, .jpeg, .png, .bmp,
.webp, .tif i .tiff.
data przyjmuje trzy rodzaje wartości: ścieżkę do katalogu zawierającego
podział train/, adres URL pliku .zip lub jedną ze znanych nazw zbiorów
danych, imagenette160 i smoke10, które są pobierane i zapisywane w pamięci
podręcznej przy pierwszym użyciu.
Kanonicznym modułem wczytującym jest libreyolo.data.classify_dataset.
Trenowanie
from libreyolo import LibreYOLO # imagenette160 jest znaną nazwą zbioru danych i zostanie pobrany przy pierwszym użyciu.# W przypadku własnych danych przekaż katalog zawierający podział train/.model = LibreYOLO("LibreResNet50-cls.pt")model.train(data="imagenette160", epochs=5)libreyolo train model=LibreResNet50-cls.pt data=imagenette160 epochs=5libreyolo train model=LibreResNet50-cls.pt data=imagenette160 \ epochs=50 device=0,1 batch=-1Nie deklaruje się nc. Liczba klas pochodzi z nazw folderów w train/, a
końcowa warstwa liniowa jest przebudowywana odpowiednio do tej liczby, podczas
gdy backbone jest przenoszony bez zmian. Informacje o zbiorach danych,
augmentacji, wielu GPU i modułach rejestrujących zawiera strona
trenowania.
ResNet, ConvNeXt, ConvNeXt V2, MobileNetV4, EfficientNetV2 i DINOv2 obsługują ważenie funkcji straty przez cls_pw lub class_weights. scale w klasyfikacji kontroluje obszar wycinka, a crop_pct wycinanie podczas ewaluacji. Zobacz augmentacje.
Filtr zmiany rozmiaru jest częścią modelu. Przed trenowaniem należy ustawić model.interpolation na "bilinear", "bicubic", "nearest" lub "bilinear_no_antialias": trenowanie, val(), predict(), kalibracja INT8 i eksport używają go wszystkie, a save(), best.pt i last.pt go zapisują, więc ponowne wczytanie go zachowuje. Każda inna nazwa zgłasza ValueError. "bilinear_no_antialias" zmienia rozmiar zwykłą interpolacją dwuliniową bez antyaliasingu wszędzie, w tym w RandomResizedCrop, dla modeli, które będą działać za zmianą rozmiaru w środowisku uruchomieniowym bez antyaliasingu. MobileNetV4, ResNet, ConvNeXt, ConvNeXt V2, EfficientNetV2, DeiT, Swin i ViT domyślnie używają bicubic; AlexNet i VGG bilinear.
Walidacja
Funkcja val() zwraca słownik kluczy metrics/, obliczany na podziale
val/ katalogu głównego zbioru danych.
from libreyolo import LibreYOLO model = LibreYOLO("LibreResNet50-cls.pt") # Słownik kluczy metrics/ oraz top1, top5 i confusion_matrix.metrics = model.val(data="imagenette160") print(metrics["metrics/accuracy_top1"])print(metrics["metrics/accuracy_top5"])print(metrics.top1, metrics.top5)libreyolo val model=LibreResNet50-cls.pt data=imagenette160metrics/accuracy_top1 jest udziałem obrazów, dla których klasa z największym
wskaźnikiem jest klasą prawdziwą. To główny wynik używany podczas trenowania do
wyboru najlepszej epoki. metrics/accuracy_top5 jest udziałem obrazów, dla
których prawdziwa klasa znajduje się wśród pięciu klas o największym wskaźniku.
Metryka mówi tym mniej, im mniej klas zawiera zbiór danych. Słownik obejmuje
również fitness, kopię wartości top-1.
Walidacja ImageFolder zwraca też makrośrednie metrics/precision, metrics/recall i metrics/f1, liczone po klasach obecnych w etykietach walidacyjnych. Klasy bez predykcji wnoszą zerową precyzję. Domyślną funkcją fitness pozostaje dokładność top-1. Walidacja i kalibracja używają transformacji ewaluacyjnej modelu.
Wynik jest podklasą dict z trzema atrybutami: top1 i top5 przechowują dwie
wartości dokładności, a confusion_matrix zlicza każdy obraz według jego klasy
top-1 względem etykiety, indeksowana matrix[predicted, true]. plots=True
zapisuje ją jako liczności w confusion_matrix.png oraz jako udziały każdej
etykiety w confusion_matrix_normalized.png. Powyżej 2000 klas gęsta macierz i
jej wykresy są niedostępne, a nonzero(), tp_fp() i class_accuracy()
odczytują liczności; zobacz walidacja i metryki.
Eksport
from libreyolo import LibreYOLO model = LibreYOLO("LibreResNet50-cls.pt")model.export(format="onnx")libreyolo export model=LibreResNet50-cls.pt format=onnxfrom libreyolo import LibreYOLO, SAMPLE_IMAGE # Funkcja fabrykująca wybiera ścieżkę na podstawie sufiksu pliku, więc# wyeksportowany artefakt wczytuje się jak checkpoint i zwraca ten sam obiekt Results.model = LibreYOLO("LibreResNet50-cls.onnx")result = model(SAMPLE_IMAGE) print(result.probs.top1, result.probs.top1conf)Wyeksportowany artefakt wczytuje się ponownie przez LibreYOLO() na podstawie
sufiksu pliku. Plik .onnx lub .engine działa więc jak checkpoint i zwraca
ten sam obiekt Results. Zakres formatów różni się między rodzinami, a macierz
na stronie każdego modelu jest generowana ze zweryfikowanego zestawu, a nie
wpisywana ręcznie. Formaty, ich zestawy zależności i ograniczenia opisuje strona
eksportu i wdrożenia.