Leitfaden zur Modell-YAML-Konfiguration
Die Modell-YAML-Konfigurationsdatei dient als architektonischer Bauplan für Ultralytics neuronale Netze. Sie definiert, wie Layer verbunden sind, welche Parameter jedes Modul verwendet und wie das gesamte Netzwerk über verschiedene Modellgrößen hinweg skaliert.
Konfigurationsstruktur
Modell-YAML-Dateien sind in drei Hauptabschnitte unterteilt, die zusammenarbeiten, um die Architektur zu definieren.
Parameter-Abschnitt
Der parameters-Abschnitt legt die globalen Eigenschaften und das Skalierungsverhalten des Modells fest:
# Parameters
nc: 80 # number of classes
scales: # compound scaling constants [depth, width, max_channels]
n: [0.50, 0.25, 1024] # nano: shallow layers, narrow channels
s: [0.50, 0.50, 1024] # small: shallow depth, standard width
m: [0.50, 1.00, 512] # medium: moderate depth, full width
l: [1.00, 1.00, 512] # large: full depth and width
x: [1.00, 1.50, 512] # extra-large: maximum performance
kpt_shape: [17, 3] # pose models onlynclegt die Anzahl der Klassen fest, die das Modell vorhersagt.scalesdefinieren zusammengesetzte Skalierungsfaktoren, die die Tiefe, Breite und maximale Anzahl der Kanäle des Modells anpassen, um verschiedene Größenvarianten (von Nano bis Extra-Large) zu erzeugen.kpt_shapegilt für Pose-Modelle. Es kann[N, 2]für(x, y)Keypoints oder[N, 3]für(x, y, visibility)sein.
Der scales-Parameter ermöglicht es dir, mehrere Modellgrößen aus einem einzigen Basis-YAML zu generieren. Wenn du beispielsweise yolo26n.yaml lädst, liest Ultralytics das Basis-yolo26.yaml und wendet die n-Skalierungsfaktoren (depth=0.50, width=0.25) an, um die Nano-Variante zu erstellen.
Wenn dein Datensatz ein abweichendes nc oder kpt_shape erfordert, überschreibt Ultralytics die Modellkonfiguration zur Laufzeit automatisch, damit sie zum Datensatz-YAML passt.
Backbone- und Head-Architektur
Die Modellarchitektur besteht aus Backbone- (Merkmalsextraktion) und Head-Abschnitten (aufgabenspezifisch):
backbone:
# [from, repeats, module, args]
- [-1, 1, Conv, [64, 3, 2]] # 0: Initial convolution
- [-1, 1, Conv, [128, 3, 2]] # 1: Downsample
- [-1, 3, C2f, [128, True]] # 2: Feature processing
head:
- [-1, 1, nn.Upsample, [None, 2, nearest]] # 6: Upsample
- [[-1, 2], 1, Concat, [1]] # 7: Skip connection
- [-1, 3, C2f, [256]] # 8: Process features
- [[8], 1, Detect, [nc]] # 9: Detection layerFormat der Layer-Spezifikation
Jeder Layer folgt dem konsistenten Schema: [from, repeats, module, args]
| Komponente | Zweck | Beispiele |
|---|---|---|
| from | Eingangsverbindungen | -1 (vorheriger), 6 (Layer 6), [4, 6, 8] (Multi-Input) |
| repeats | Anzahl der Wiederholungen | 1 (einzeln), 3 (3-mal wiederholen) |
| module | Modultyp | Conv, C2f, TorchVision, Detect |
| args | Modulargumente | [64, 3, 2] (Kanäle, Kernel, Stride) |
Verbindungsmuster
Das from-Feld erzeugt flexible Datenflussmuster in deinem Netzwerk:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layerLayer werden beginnend bei 0 indiziert. Negative Indizes referenzieren vorherige Layer (-1 = vorheriger Layer), während positive Indizes spezifische Layer anhand ihrer Position referenzieren.
Modulwiederholung
Der repeats-Parameter erzeugt tiefere Netzwerkabschnitte:
- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layerDie tatsächliche Anzahl der Wiederholungen wird mit dem Tiefenskalierungsfaktor deiner Modellgrößenkonfiguration multipliziert.
Verfügbare Module
Module sind nach Funktionalität gegliedert und im Ultralytics-Modulverzeichnis definiert. Die folgenden Tabellen zeigen häufig verwendete Module nach Kategorien, wobei im Quellcode viele weitere verfügbar sind:
Grundlegende Operationen
| Modul | Zweck | Quelle | Argumente |
|---|---|---|---|
Conv | Convolution + BatchNorm + Aktivierung | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample | Räumliches Upsampling | PyTorch | [size, scale_factor, mode] |
nn.Identity | Durchleitungsoperation | PyTorch | [] |
Zusammengesetzte Blöcke
| Modul | Zweck | Quelle | Argumente |
|---|---|---|---|
C2f | CSP-Bottleneck mit 2 Convolutions | block.py | [out_ch, shortcut, expansion] |
SPPF | Spatial Pyramid Pooling (schnell) | block.py | [out_ch, kernel_size] |
Concat | Kanalweise Konkatenation | conv.py | [dimension] |
Spezialisierte Module
| Modul | Zweck | Quelle | Argumente |
|---|---|---|---|
TorchVision | Beliebiges TorchVision-Modell laden | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index | Spezifischen Tensor aus Liste extrahieren | block.py | [out_ch, index] |
Detect | YOLO-Detektions-Head | head.py | [nc, anchors, ch] |
Dies stellt einen Teil der verfügbaren Module dar. Für die vollständige Liste der Module und ihrer Parameter, erkunde das Modulverzeichnis.
Erweiterte Funktionen
TorchVision-Integration
Das TorchVision-Modul ermöglicht die nahtlose Integration jedes TorchVision-Modells als Backbone:
from ultralytics import YOLO
# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="coco8.yaml", epochs=100)Setze den letzten Parameter auf True, um intermediäre Feature-Maps für die Multi-Scale-Detektion zu erhalten.
Index-Modul zur Merkmalsauswahl
Wenn du Modelle verwendest, die mehrere Feature-Maps ausgeben, wählt das Index-Modul spezifische Ausgaben aus:
backbone:
- [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, True]] # Multi-output
head:
- [0, 1, Index, [192, 4]] # Select 4th feature map (192 channels)
- [0, 1, Index, [384, 6]] # Select 6th feature map (384 channels)
- [0, 1, Index, [768, 8]] # Select 8th feature map (768 channels)
- [[1, 2, 3], 1, Detect, [nc]] # Multi-scale detectionModul-Auflösungssystem
Zu verstehen, wie Ultralytics Module findet und importiert, ist entscheidend für Anpassungen:
Modul-Suchprozess
Ultralytics verwendet ein dreistufiges System in parse_model:
# Core resolution logic
m = getattr(torch.nn, m[3:]) if "nn." in m else getattr(torchvision.ops, m[4:]) if "ops." in m else globals()[m]- PyTorch-Module: Namen, die mit
'nn.'beginnen →torch.nnNamespace - TorchVision-Operationen: Namen, die mit
'ops.'beginnen →torchvision.opsNamespace - Ultralytics-Module: Alle anderen Namen → globaler Namensraum via Importe
Modul-Importkette
Standardmodule werden durch Importe in tasks.py verfügbar:
from ultralytics.nn.modules import ( # noqa: F401
SPPF,
C2f,
Conv,
Detect,
# ... many more modules
Index,
TorchVision,
)Integration benutzerdefinierter Module
Änderung des Quellcodes
Die Änderung des Quellcodes ist der flexibelste Weg, um eigene Module zu integrieren, kann jedoch knifflig sein. Um ein benutzerdefiniertes Modul zu definieren und zu verwenden, befolge diese Schritte:
-
Installiere Ultralytics im Entwicklungsmodus mithilfe der Git-Clone-Methode aus dem Quickstart-Leitfaden.
-
Definiere dein Modul in
ultralytics/nn/modules/block.py:class CustomBlock(nn.Module): """Custom block with Conv-BatchNorm-ReLU sequence.""" def __init__(self, c1, c2): """Initialize CustomBlock with input and output channels.""" super().__init__() self.layers = nn.Sequential(nn.Conv2d(c1, c2, 3, 1, 1), nn.BatchNorm2d(c2), nn.ReLU()) def forward(self, x): """Forward pass through the block.""" return self.layers(x) -
Mache dein Modul auf Paketebene verfügbar in
ultralytics/nn/modules/__init__.py:from .block import CustomBlock # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock -
Zu Importen hinzufügen in
ultralytics/nn/tasks.py:from ultralytics.nn.modules import CustomBlock # noqa -
Behandle spezielle Argumente (falls erforderlich) innerhalb von
parse_model()inultralytics/nn/tasks.py:# Add this condition in the parse_model() function if m is CustomBlock: c1, c2 = ch[f], args[0] # input channels, output channels args = [c1, c2, *args[1:]] -
Verwende das Modul in deiner Modell-YAML:
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]] -
Überprüfe die FLOPs, um sicherzustellen, dass der Forward-Pass funktioniert:
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # should print non-zero FLOPs if working
Beispielkonfigurationen
Einfaches Erkennungsmodell
# Simple YOLO detection model
nc: 80
scales:
n: [0.33, 0.25, 1024]
backbone:
- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
- [-1, 3, C2f, [128, True]] # 2
- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
- [-1, 6, C2f, [256, True]] # 4
- [-1, 1, SPPF, [256, 5]] # 5
head:
- [-1, 1, Conv, [256, 3, 1]] # 6
- [[6], 1, Detect, [nc]] # 7TorchVision-Backbone-Modell
# ConvNeXt backbone with YOLO head
nc: 80
backbone:
- [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, True]]
head:
- [0, 1, Index, [192, 4]] # P3 features
- [0, 1, Index, [384, 6]] # P4 features
- [0, 1, Index, [768, 8]] # P5 features
- [[1, 2, 3], 1, Detect, [nc]] # Multi-scale detectionKlassifizierungsmodell
# Simple classification model
nc: 1000
backbone:
- [-1, 1, Conv, [64, 7, 2, 3]]
- [-1, 1, nn.MaxPool2d, [3, 2, 1]]
- [-1, 4, C2f, [64, True]]
- [-1, 1, Conv, [128, 3, 2]]
- [-1, 8, C2f, [128, True]]
- [-1, 1, nn.AdaptiveAvgPool2d, [1]]
head:
- [-1, 1, Classify, [nc]]Bewährte Methoden
Tipps zum Architekturentwurf
Fang einfach an: Beginne mit bewährten Architekturen, bevor du Anpassungen vornimmst. Nutze vorhandene YOLO-Konfigurationen als Vorlagen und modifiziere sie schrittweise, anstatt sie von Grund auf neu zu erstellen.
Teste schrittweise: Überprüfe jede Änderung schrittweise. Füge ein benutzerdefiniertes Modul nach dem anderen hinzu und stelle sicher, dass es funktioniert, bevor du mit der nächsten Änderung fortfährst.
Kanäle überwachen: Stelle sicher, dass die Kanalabmessungen zwischen verbundenen Schichten übereinstimmen. Die Ausgabekanäle (c2) einer Schicht müssen mit den Eingabekanälen (c1) der nächsten Schicht in der Sequenz übereinstimmen.
Verwende Skip-Verbindungen: Nutze die Wiederverwendung von Merkmalen mit [[-1, N], 1, Concat, [1]]-Mustern. Diese Verbindungen helfen beim Gradientenfluss und ermöglichen es dem Modell, Merkmale aus verschiedenen Skalen zu kombinieren.
Skaliere angemessen: Wähle Modellgrößen basierend auf deinen Rechenbeschränkungen. Nutze Nano (n) für Edge-Geräte, Small (s) für eine ausgewogene Leistung und größere Größen (m, l, x) für maximale Genauigkeit.
Überlegungen zur Leistung
Tiefe vs. Breite: Tiefe Netzwerke erfassen komplexe hierarchische Merkmale durch mehrere Transformationsschichten, während breite Netzwerke mehr Informationen parallel in jeder Schicht verarbeiten. Bringe diese Aspekte basierend auf der Komplexität deiner Aufgabe ins Gleichgewicht.
Skip-Verbindungen: Verbessern den Gradientenfluss während des Trainings und ermöglichen die Wiederverwendung von Merkmalen im gesamten Netzwerk. Sie sind besonders wichtig bei tieferen Architekturen, um verschwindende Gradienten zu verhindern.
Flaschenhals-Blöcke (Bottleneck): Reduzieren die Rechenkosten bei gleichzeitiger Beibehaltung der Ausdrucksstärke des Modells. Module wie C2f verwenden weniger Parameter als Standard-Faltungen, bewahren aber die Kapazität zum Erlernen von Merkmalen.
Multi-Scale-Merkmale: Essenziell für die Erkennung von Objekten unterschiedlicher Größe im selben Bild. Verwende FPN-Muster (Feature Pyramid Network) mit mehreren Erkennungsköpfen auf verschiedenen Skalen.
Fehlerbehebung
Häufige Probleme
| Problem | Ursache | Lösung |
|---|---|---|
KeyError: 'ModuleName' | Modul nicht importiert | Zu tasks.py Importen hinzufügen |
| Kanalabmessungen stimmen nicht überein | Falsche args-Spezifikation | Kompatibilität der Eingabe-/Ausgabekanäle überprüfen |
AttributeError: 'int' object has no attribute | Falscher Argumenttyp | Moduldokumentation auf korrekte Argumenttypen prüfen |
| Modell lässt sich nicht erstellen | Ungültige from-Referenz | Sicherstellen, dass referenzierte Schichten existieren |
Tipps zur Fehlersuche
Bei der Entwicklung benutzerdefinierter Architekturen hilft systematisches Debuggen, Probleme frühzeitig zu erkennen:
Verwende Identitätskopf für Tests
Ersetze komplexe Köpfe durch nn.Identity, um Backbone-Probleme zu isolieren:
nc: 1
backbone:
- [-1, 1, CustomBlock, [64]]
head:
- [-1, 1, nn.Identity, []] # Pass-through for debuggingDies ermöglicht die direkte Überprüfung der Backbone-Ausgaben:
import torch
from ultralytics import YOLO
model = YOLO("debug_model.yaml")
output = model.model(torch.randn(1, 3, 640, 640))
print(f"Output shape: {output.shape}") # Should match expected dimensionsÜberprüfung der Modellarchitektur
Das Überprüfen der FLOPs-Anzahl und das Ausgeben jeder Schicht kann ebenfalls helfen, Probleme mit deiner benutzerdefinierten Modellkonfiguration zu debuggen. Die FLOPs-Anzahl sollte für ein gültiges Modell ungleich null sein. Wenn sie null ist, liegt wahrscheinlich ein Problem mit dem Forward-Pass vor. Das Ausführen eines einfachen Forward-Passes sollte den exakten Fehler aufzeigen, der auftritt.
from ultralytics import YOLO
# Build model with verbose output to see layer details
model = YOLO("debug_model.yaml", verbose=True)
# Check model FLOPs. Failed forward pass causes 0 FLOPs.
model.info()
# Inspect individual layers
for i, layer in enumerate(model.model.model):
print(f"Layer {i}: {layer}")Schrittweise Validierung
- Minimal starten: Zuerst mit der einfachstmöglichen Architektur testen
- Schrittweise hinzufügen: Komplexität Schicht für Schicht aufbauen
- Abmessungen prüfen: Kompatibilität von Kanal- und räumlicher Größe verifizieren
- Skalierung validieren: Mit verschiedenen Modellgrößen (
n,s,m) testen
FAQ
Wie ändere ich die Anzahl der Klassen in meinem Modell?
Setze den nc-Parameter oben in deiner YAML-Datei entsprechend der Klassenanzahl deines Datensatzes.
nc: 5 # 5 classesKann ich ein benutzerdefiniertes Backbone in meiner Modell-YAML verwenden?
Ja. Du kannst jedes unterstützte Modul verwenden, einschließlich TorchVision-Backbones, oder dein eigenes benutzerdefiniertes Modul definieren und importieren, wie unter Integration benutzerdefinierter Module beschrieben.
Wie skaliere ich mein Modell für verschiedene Größen (Nano, Small, Medium usw.)?
Verwende den scales-Abschnitt in deiner YAML, um Skalierungsfaktoren für Tiefe, Breite und maximale Kanäle zu definieren. Das Modell wendet diese automatisch an, wenn du die Basis-YAML-Datei mit der an den Dateinamen angehängten Skala lädst (z. B. yolo26n.yaml).
Was bedeutet das Format [from, repeats, module, args]?
Dieses Format legt fest, wie jede Schicht aufgebaut ist:
from: Eingabequelle(n)repeats: Anzahl der Wiederholungen des Modulsmodule: Der Schichttypargs: Argumente für das Modul
Wie behebe ich Kanal-Mismatch-Fehler?
Überprüfe, ob die Ausgabekanäle einer Schicht mit den erwarteten Eingabekanälen der nächsten übereinstimmen. Verwende print(model.model.model), um die Architektur deines Modells zu untersuchen.
Wo finde ich eine Liste der verfügbaren Module und ihrer Argumente?
Überprüfe den Quellcode im Verzeichnis ultralytics/nn/modules für alle verfügbaren Module und deren Argumente.
Wie füge ich ein benutzerdefiniertes Modul zu meiner YAML-Konfiguration hinzu?
Definiere dein Modul im Quellcode, importiere es wie unter Änderung des Quellcodes gezeigt und referenziere es namentlich in deiner YAML-Datei.
Kann ich vortrainierte Gewichte mit einer benutzerdefinierten YAML verwenden?
Ja, du kannst model.load("path/to/weights") verwenden, um Gewichte aus einem vortrainierten Checkpoint zu laden. Es werden jedoch nur die Gewichte für die Schichten geladen, die übereinstimmen.
Wie validiere ich meine Modellkonfiguration?
Verwende model.info(), um zu prüfen, ob die FLOPs-Anzahl ungleich null ist. Ein gültiges Modell sollte eine FLOPs-Anzahl ungleich null aufweisen. Wenn sie null ist, befolge die Vorschläge unter Tipps zur Fehlersuche, um das Problem zu finden.