Bildklassifikation
Die Bildklassifikation weist einem ganzen Bild eine Labelverteilung zu und lokalisiert nichts darin. Der Task-Key ist classify.
Definition
Die Bildklassifikation erzeugt für das ganze Bild einen Score pro Klasse und überhaupt keine Koordinaten. Sie beantwortet, was im Bild ist, nie wo, und genau das trennt sie von der Objekterkennung.
classify ist der kanonische Task-Key, und das Suffix -cls im Dateinamen
eines Checkpoints wählt ihn aus. Dieses Suffix ist bei
Klassifikations-Familien Pflicht statt optional, LibreResNet50.pt wird also
nicht als Klassifikator gelesen, sondern nur LibreResNet50-cls.pt.
predict() füllt result.probs und lässt boxes leer. .data ist der volle
Score-Vektor, .top1 der Index des höchsten Scores und .top1conf sein Wert,
.top5 die fünf höchsten Indizes in absteigender Reihenfolge und .top5conf
ihre Scores. Die Indizes zeigen in result.names. Ein Results-Objekt zu
slicen kürzt probs nie, weil der Vektor zum Bild gehört und nicht zu einer
einzelnen Zeile.
Modelle
Trainierbare Bildklassifikatoren sind ResNet, ConvNeXt, MobileNetV4, EfficientNetV2 und DINOv2. Die ersten vier laufen mit dem Basispaket und bieten veröffentlichte Gewichte. DINOv2 benötigt pip install "libreyolo[rfdetr]" und hat keinen von LibreYOLO gehosteten Checkpoint: Es lädt das Upstream-Backbone mit einem zufällig initialisierten linearen Head und ist damit ein Ausgangspunkt für Fine-Tuning, kein fertiges Vorhersagemodell.
Fünf weitere sagen vorher, validieren und exportieren, aber ihr train() löst
NotImplementedError aus: ViT, Swin,
VGG, AlexNet und
DeiT.
CLIP und SigLIP2 klassifizieren
ohne feste Labelmenge. Sie bewerten das Bild gegen Text-Prompts, deshalb
definiert set_classes() die Klassen zur Aufrufzeit, und für eine neue
Labelmenge gibt es überhaupt keinen Trainingsschritt. Beide bedienen auch den
embed-Task.
ConvNeXt V2 ergänzt überwachte Klassifikation mit vortrainierten Gewichten unter CC-BY-NC-4.0. PE unterstützt Zero-Shot-Klassifikation; V-JEPA 2 trainiert Probes für die Videoklassifikation.
Vorhersage
Die Gewichte werden beim ersten Aufruf von Hugging Face geladen und lokal zwischengespeichert.
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Das Suffix -cls im Dateinamen wählt den Task, ein task-Argument# ist also nicht nötig.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 ist der volle (C,)-Vektor; top5/top5conf sind sortiert.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 bewertet das Bild gegen Text-Prompts, die Labelmenge wird# also beim Aufruf gesetzt statt im Checkpoint festgeschrieben.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))conf, iou und max_det haben hier keine Wirkung: Es gibt keine Kandidaten,
die man schwellen oder unterdrücken könnte, nur eine Verteilung. Siehe
Vorhersage für Quellen, Streaming und den Umgang mit
Ergebnissen.
Datensatzformat
Die Klassifikation nutzt einen Verzeichnisbaum, keine Labeldateien und keine
YAML. data ist das Wurzelverzeichnis des Datensatzes.
dataset/ train/ tench/000001.jpg parachute/000002.jpg val/ tench/000101.jpg parachute/000102.jpgtrain/ ist für das Training erforderlich und legt die Zuordnung von Klasse zu
Index über den sortierten Ordnernamen fest, der alphabetisch erste Ordner wird
also Klasse 0. val/ ist für die Validierung erforderlich. Ein test/-Split
darf vorhanden sein, und die Standardbefehle für Training und Validierung nutzen
ihn nicht. Jeder Split außer train muss dieselben Klassenordnernamen enthalten
wie die erwartete Klassenmenge, und genau das lässt eine Abweichung laut
scheitern, statt sie als falsche Vorhersage zu werten. Die akzeptierten
Bildendungen sind .jpg, .jpeg, .png, .bmp, .webp, .tif und .tiff.
data nimmt drei Dinge: einen Pfad zu einem Verzeichnis mit einem
train/-Split, eine .zip-URL oder einen der bekannten Datensatznamen,
imagenette160 und smoke10, die beim ersten Aufruf geladen und
zwischengespeichert werden.
Der kanonische Loader ist libreyolo.data.classify_dataset.
Training
from libreyolo import LibreYOLO # imagenette160 ist ein bekannter Datensatzname und lädt beim ersten# Aufruf. Für eigene Daten ein Verzeichnis mit train/-Split angeben.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=-1Es gibt kein nc zu deklarieren: Die Klassenanzahl kommt aus den Ordnernamen
unter train/, und die finale lineare Schicht wird passend neu aufgebaut,
während das Backbone unverändert übernommen wird. Siehe
Training für Datensätze, Datenaugmentierung, Multi-GPU und
Logger.
ResNet, ConvNeXt, ConvNeXt V2, MobileNetV4, EfficientNetV2 und DINOv2 unterstützen Loss-Gewichtung über cls_pw oder class_weights. Bei der Klassifikation steuert scale die Ausschnittsfläche und crop_pct den Auswertungsausschnitt. Siehe Augmentierungen.
Der Resize-Filter gehört zum Modell. Setze model.interpolation vor dem Training auf "bilinear", "bicubic", "nearest" oder "bilinear_no_antialias": Training, val(), predict(), INT8-Kalibrierung und Export verwenden ihn, und save(), best.pt und last.pt halten ihn fest, sodass ein erneutes Laden ihn behält. Jeder andere Name löst ValueError aus. "bilinear_no_antialias" skaliert überall mit schlichtem bilinearem Resampling und ohne Antialiasing, RandomResizedCrop eingeschlossen, für Modelle, die hinter einem Runtime-Resize ohne Antialiasing laufen. MobileNetV4, ResNet, ConvNeXt, ConvNeXt V2, EfficientNetV2, DeiT, Swin und ViT verwenden standardmäßig bicubic; AlexNet und VGG bilinear.
Validierung
val() liefert ein Dictionary von metrics/-Keys, berechnet über
den val/-Split des Datensatz-Wurzelverzeichnisses.
from libreyolo import LibreYOLO model = LibreYOLO("LibreResNet50-cls.pt") # Ein dict mit metrics/-Keys sowie top1, top5 und 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 ist der Anteil der Bilder, deren höchstbewertete Klasse
die richtige ist, und die Kennzahl, die das Training nutzt, um die beste Epoche
zu wählen. metrics/accuracy_top5 ist der Anteil, dessen richtige Klasse
irgendwo unter den fünf höchstbewerteten Klassen auftaucht, was umso weniger
aussagt, je weniger Klassen der Datensatz hat. Das Dictionary trägt außerdem
fitness, eine Kopie des Top-1-Werts.
Die ImageFolder-Validierung liefert auch die Makrometriken metrics/precision, metrics/recall und metrics/f1, gemittelt über die in den Validierungszielen vorhandenen Klassen. Nicht vorhergesagte Klassen tragen mit Precision null bei. Die Standardfitness bleibt Top-1-Accuracy. Validierung und Kalibrierung verwenden die Auswertungstransformation des Modells.
Das Ergebnis ist eine dict-Unterklasse mit drei Attributen: top1 und top5 halten die beiden Accuracy-Werte, und confusion_matrix zählt jedes Bild mit seiner Top-1-Klasse gegen sein Label, indiziert als matrix[predicted, true]. plots=True schreibt sie als Zählungen nach confusion_matrix.png und als Anteile jedes Labels nach confusion_matrix_normalized.png. Ab 2,000 Klassen sind die dichte Matrix und ihre Diagramme nicht verfügbar, und nonzero(), tp_fp() und class_accuracy() lesen stattdessen die Zählungen; siehe Validierung und Metriken.
Export
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 # Die Factory routet über die Dateiendung: Ein exportiertes Artefakt# lädt wie ein Checkpoint und liefert dasselbe Results-Objekt.model = LibreYOLO("LibreResNet50-cls.onnx")result = model(SAMPLE_IMAGE) print(result.probs.top1, result.probs.top1conf)Ein exportiertes Artefakt lädt über LibreYOLO() anhand seiner Dateiendung
zurück, deshalb verhält sich eine .onnx- oder .engine-Datei wie ein
Checkpoint und liefert dieselben Results. Die Formatabdeckung unterscheidet
sich je Familie; die Matrix auf jeder Modellseite wird aus dem validierten Satz
erzeugt statt von Hand getippt. Siehe
Export und Deployment für die Formate, ihre Extras und ihre
Einschränkungen.