Anleitung zur YAML-Konfiguration von Modellen
Die Modell YAML-Konfigurationsdatei dient als architektonische Blaupause für Ultralytics neuronale Netze. Sie definiert, wie Schichten verbunden sind, welche Parameter jedes Modul verwendet und wie das gesamte Netzwerk über verschiedene Modellgrößen skaliert.
Konfigurationsstruktur
Modell YAML-Dateien sind in drei Hauptabschnitte unterteilt, die zusammenarbeiten, um die Architektur zu definieren.
Parameter-Abschnitt
Der Abschnitt Parameter spezifiziert die globalen Eigenschaften und das Skalierungsverhalten des Modells:
# 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 only
nc
legt die Anzahl der Klassen fest, die das Modell vorhersagt.scales
definiert zusammengesetzte Skalierungsfaktoren, die die Modelltiefe, -breite und maximalen Kanäle anpassen, um verschiedene Größenvarianten zu erzeugen (Nano bis Extra-Large).kpt_shape
gilt für Pose-Modelle. Es kann sein[N, 2]
für(x, y)
Keypoints oder[N, 3]
für(x, y, visibility)
.
Reduzieren Sie Redundanz mit scales
Die scales
Mit dem Parameter können Sie mehrere Modellgrößen aus einer einzigen Basis-YAML-Datei generieren. Wenn Sie beispielsweise yolo11n.yaml
laden, liest Ultralytics die Basis yolo11.yaml
und wendet die n
Skalierungsfaktoren (depth=0.50
, width=0.25
) an, um die Nano-Variante zu erstellen.
nc
und kpt_shape
sind datensatzabhängig
Wenn Ihr Datensatz eine andere nc
oder kpt_shape
angibt, überschreibt Ultralytics die Modellkonfiguration zur Laufzeit automatisch, um sie an die Datensatz-YAML-Datei anzupassen.
Backbone- und Head-Architektur
Die Modellarchitektur besteht aus Backbone- (Merkmalsextraktion) und Head- (aufgabenspezifisch) Abschnitten:
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 layer
Format der Layer-Spezifikation
Jede Schicht folgt dem gleichen Muster: [from, repeats, module, args]
Komponente | Zweck | Beispiele |
---|---|---|
von | Eingangsverbindungen | -1 (vorherige), 6 (Schicht 6), [4, 6, 8] (Mehrfacheingabe) |
Wiederholungen | Anzahl der Wiederholungen | 1 (einzeln), 3 (3 mal wiederholen) |
Modul | Modultyp | Conv , C2f , TorchVision , Detect |
args | Modulargumente | [64, 3, 2] (Kanäle, Kernel, Schrittweite) |
Verbindungsmuster
Die from
Feld erzeugt flexible Datenflussmuster in Ihrem gesamten Netzwerk:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layer
- [[-1, 6], 1, Concat, [1]] # Combines current layer with layer 6
- [[4, 6, 8], 1, Detect, [nc]] # Detection head using 3 feature scales
Schichtindizierung
Schichten werden ab 0 indiziert. Negative Indizes beziehen sich auf vorherige Schichten (-1
= vorherige Schicht), während positive Indizes sich auf bestimmte Schichten anhand ihrer Position beziehen.
Modulwiederholung
Die repeats
Parameter erzeugt tiefere Netzwerkabschnitte:
- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layer
Die tatsächliche Anzahl der Wiederholungen wird mit dem Tiefenskalierungsfaktor aus Ihrer Modellgrößenkonfiguration multipliziert.
Verfügbare Module
Module sind nach Funktionalität organisiert und im Ultralytics-Modulverzeichnis definiert. Die folgenden Tabellen zeigen häufig verwendete Module nach Kategorie, wobei im Quellcode noch 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 |
Pass-Through-Operation | PyTorch | [] |
Zusammengesetzte Blöcke
Modul | Zweck | Quelle | Argumente |
---|---|---|---|
C2f |
CSP-Bottleneck mit 2 Convolutionen | block.py | [out_ch, shortcut, expansion] |
SPPF |
Spatial Pyramid Pooling (schnell) | block.py | [out_ch, kernel_size] |
Concat |
Kanalweise Verkettung | conv.py | [dimension] |
Spezielle Module
Modul | Zweck | Quelle | Argumente |
---|---|---|---|
TorchVision |
Beliebiges Torchvision-Modell laden | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index |
Bestimmten Tensor aus Liste extrahieren | block.py | [out_ch, index] |
Detect |
YOLO-Detektionskopf | head.py | [nc, anchors, ch] |
Vollständige Modulliste
Dies stellt eine Untermenge der verfügbaren Module dar. Die vollständige Liste der Module und ihrer Parameter finden Sie im Modulverzeichnis.
Erweiterte Funktionen
TorchVision-Integration
Das TorchVision-Modul ermöglicht die nahtlose Integration eines beliebigen 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)
backbone:
- [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, False]]
head:
- [-1, 1, Classify, [nc]]
Parameteraufschlüsselung:
768
: Erwartete Ausgabekanäleconvnext_tiny
: Modellarchitektur (verfügbare Modelle)DEFAULT
: Vordefinierte Gewichte verwendenTrue
: Klassifikationskopf entfernen2
: Letzte 2 Schichten abschneidenFalse
: Einzelnen Tensor zurückgeben (keine Liste)
Multi-Scale-Funktionen
Setzen Sie den letzten Parameter auf True
, um Zwischen-Feature-Maps für die Multi-Scale-Erkennung zu erhalten.
Indexmodul für die Merkmalsauswahl
Bei der Verwendung von Modellen, die mehrere Feature-Maps ausgeben, wählt das Index-Modul bestimmte 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 detection
Modulauflösungssystem
Das Verständnis, wie Ultralytics Module findet und importiert, ist entscheidend für die Anpassung:
Modul-Lookup-Prozess
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-Modulen: Namen, die mit
'nn.'
→torch.nn
Namespace beginnen - TorchVision-Operationen: Namen, die mit
'ops.'
→torchvision.ops
Namespace beginnen - Ultralytics-Module: Alle anderen Namen → globaler Namespace über Importe
Modul-Importkette
Standardmodule werden durch Importe in tasks.py
:
from ultralytics.nn.modules import ( # noqa: F401, E501
SPPF,
C2f,
Conv,
Detect,
# ... many more modules
Index,
TorchVision,
)
Benutzerdefinierte Modulintegration
Modifikation des Quellcodes
Die Modifizierung des Quellcodes ist die vielseitigste Möglichkeit, Ihre benutzerdefinierten Module zu integrieren, kann aber knifflig sein. Um ein benutzerdefiniertes Modul zu definieren und zu verwenden, befolgen Sie diese Schritte:
-
Installieren Sie Ultralytics im Entwicklungsmodus unter Verwendung der Git-Klon-Methode aus der Schnellstartanleitung.
-
Definieren Sie Ihr 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)
-
Stellen Sie Ihr Modul auf Paketebene bereit 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
-
Spezielle Argumente behandeln (falls erforderlich) innerhalb
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:]]
-
Verwenden Sie das Modul in Ihrer Modell-YAML:
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]]
-
FLOPs prüfen, 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]] # 7
TorchVision 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 detection
Klassifikationsmodell
# 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 Verfahren
Tipps zum Architekturdesign
Einfach anfangen: Beginnen Sie mit bewährten Architekturen, bevor Sie Anpassungen vornehmen. Verwenden Sie bestehende YOLO-Konfigurationen als Vorlagen und modifizieren Sie diese schrittweise, anstatt von Grund auf neu zu entwickeln.
Inkrementell testen: Validieren Sie jede Modifikation Schritt für Schritt. Fügen Sie jeweils ein benutzerdefiniertes Modul hinzu und verifizieren Sie, dass es funktioniert, bevor Sie mit der nächsten Änderung fortfahren.
Kanäle überwachen: Stellen Sie sicher, dass die Kanaldimensionen zwischen verbundenen Layern übereinstimmen. Die Ausgabekanäle (c2
) eines Layers müssen mit den Eingangskanälen (c1
) des nächsten Layers in der Sequenz übereinstimmen.
Skip-Verbindungen nutzen: Nutzen Sie die Wiederverwendung von Features mit [[-1, N], 1, Concat, [1]]
-Mustern. Diese Verbindungen helfen beim Gradientenfluss und ermöglichen es dem Modell, Features aus verschiedenen Skalen zu kombinieren.
Passende Skalierung: Wählen Sie Modellskalen basierend auf Ihren Rechenbeschränkungen. Verwenden Sie Nano (n
) für Edge-Geräte, Small (s
) für eine ausgewogene Leistung und größere Skalen (m
, l
, x
) für maximale Genauigkeit.
Performance-Überlegungen
Tiefe vs. Breite: Tiefe Netzwerke erfassen komplexe hierarchische Merkmale durch mehrere Transformationsschichten, während breite Netzwerke mehr Informationen parallel in jeder Schicht verarbeiten. Balancieren Sie diese basierend auf Ihrer Aufgabenkomplexität.
Skip-Verbindungen: Verbessern Sie den Gradientenfluss während des Trainings und ermöglichen Sie die Wiederverwendung von Features im gesamten Netzwerk. Sie sind besonders wichtig in tieferen Architekturen, um verschwindende Gradienten zu verhindern.
Bottleneck-Blöcke: Reduzieren Sie die Rechenkosten und erhalten Sie gleichzeitig die Ausdruckskraft des Modells. Module wie C2f
verwenden weniger Parameter als Standard-Faltungen und erhalten gleichzeitig die Fähigkeit zum Feature-Lernen.
Multi-Scale-Features: Essentiell für die Erkennung von Objekten unterschiedlicher Größe im selben Bild. Verwenden Sie Feature Pyramid Network (FPN)-Muster mit mehreren Erkennungsköpfen in verschiedenen Maßstäben.
Fehlerbehebung
Häufige Probleme
Problem | Ursache | Lösung |
---|---|---|
KeyError: 'ModuleName' |
Modul nicht importiert | Hinzufügen zu tasks.py Importe |
Kanal-Dimensions-Fehlpaarung | Falsche args Spezifikation |
Überprüfen Sie die Kompatibilität der Eingangs- / Ausgangskanäle |
AttributeError: 'int' object has no attribute |
Falscher Argumenttyp | Überprüfen Sie die Moduldokumentation auf korrekte Argumenttypen |
Modell konnte nicht erstellt werden | Ungültig from Referenz |
Stellen Sie sicher, dass referenzierte Layer existieren |
Debugging-Tipps
Bei der Entwicklung benutzerdefinierter Architekturen hilft systematisches Debugging, Probleme frühzeitig zu erkennen:
Verwenden Sie Identity Head zum Testen
Ersetzen Sie komplexe Heads durch nn.Identity
um Backbone-Probleme zu isolieren:
nc: 1
backbone:
- [-1, 1, CustomBlock, [64]]
head:
- [-1, 1, nn.Identity, []] # Pass-through for debugging
Dies ermöglicht die direkte Inspektion 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
Inspektion der Modellarchitektur
Das Überprüfen der FLOPs-Anzahl und das Ausgeben jedes Layers kann ebenfalls helfen, Probleme mit Ihrer 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 Pass sollte den genauen Fehler anzeigen, 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 beginnen: Testen Sie zuerst mit der einfachsten möglichen Architektur
- Inkrementell hinzufügen: Bauen Sie die Komplexität Schicht für Schicht auf
- Abmessungen prüfen: Überprüfen Sie die Kompatibilität von Kanal- und Raumgröße
- Skalierung validieren: Testen Sie mit verschiedenen Modellskalen (
n
,s
,m
)
FAQ
Wie kann ich die Anzahl der Klassen in meinem Modell ändern?
Setzen Sie den nc
Parameter oben in Ihrer YAML-Datei, um ihn an die Anzahl der Klassen Ihres Datensatzes anzupassen.
nc: 5 # 5 classes
Kann ich ein benutzerdefiniertes Backbone in meiner Modell-YAML-Datei verwenden?
Ja. Sie können jedes unterstützte Modul verwenden, einschließlich TorchVision Backbones, oder Ihr eigenes benutzerdefiniertes Modul definieren und es wie unter Benutzerdefinierte Modulintegration beschrieben importieren.
Wie skaliere ich mein Modell für verschiedene Größen (Nano, Small, Medium, usw.)?
Verwenden Sie den scales
Abschnitt in Ihrer YAML-Datei, um Skalierungsfaktoren für Tiefe, Breite und maximale Kanäle zu definieren. Das Modell wendet diese automatisch an, wenn Sie die Basis-YAML-Datei mit dem an den Dateinamen angehängten Maßstab laden (z. B. yolo11n.yaml
), oder Auto-Modus mit angegebener Auslastungsfraktion (
Was bedeutet das [from, repeats, module, args]
Format?
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 Fehler aufgrund von Kanal-Fehlpaarungen?
Überprüfen Sie, ob die Ausgabekanäle einer Schicht mit den erwarteten Eingangskanälen der nächsten übereinstimmen. Verwenden Sie print(model.model.model)
, um die Architektur Ihres Modells zu überprüfen.
Wo finde ich eine Liste der verfügbaren Module und ihrer Argumente?
Überprüfen Sie den Quellcode im ultralytics/nn/modules
Verzeichnis für alle verfügbaren Module und deren Argumente.
Wie füge ich meiner YAML-Konfiguration ein benutzerdefiniertes Modul hinzu?
Definieren Sie Ihr Modul im Quellcode, importieren Sie es wie unter Quellcode-Modifikation gezeigt, und referenzieren Sie es namentlich in Ihrer YAML-Datei.
Kann ich vortrainierte Gewichte mit einer benutzerdefinierten YAML-Datei verwenden?
Ja, Sie können model.load("path/to/weights")
verwenden, um Gewichte aus einem vortrainierten Checkpoint zu laden. Allerdings werden nur Gewichte für übereinstimmende Schichten erfolgreich geladen.
Wie validiere ich meine Modellkonfiguration?
Verwenden Sie model.info()
, um zu überprüfen, ob die Anzahl der FLOPs ungleich Null ist. Ein gültiges Modell sollte eine Anzahl von FLOPs ungleich Null aufweisen. Wenn sie Null ist, befolgen Sie die Vorschläge in Debugging-Tipps , um das Problem zu finden.