YOLO Vision 2026:

Leitfaden zur Modell-YAML-Konfiguration#

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 hinweg skaliert.

Model YAML configuration workflow.

Konfigurationsstruktur#

Modell-YAML-Dateien sind in drei Hauptabschnitte unterteilt, die zusammenarbeiten, um die Architektur zu definieren.

Abschnitt Parameter#

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 only
  • nc legt die Anzahl der Klassen fest, die das Modell vorhersagt.
  • scales definiert zusammengesetzte Skalierungsfaktoren, die die Modelltiefe, -breite und die maximale Kanalanzahl anpassen, um verschiedene Größenvarianten (von nano bis extra-large) zu erzeugen.
  • kpt_shape gilt für Pose-Modelle. Es kann [N, 2] für (x, y) Schlüsselpunkte oder [N, 3] für (x, y, visibility) sein.
Redundanz reduzieren mit `scales`

Mit dem Parameter scales kannst du mehrere Modellgrößen aus einer einzigen Basis-YAML generieren. Wenn du beispielsweise yolo26n.yaml lädst, liest Ultralytics die Basis-yolo26.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 dein Datensatz einen anderen Wert für nc oder kpt_shape angibt, überschreibt Ultralytics die Modellkonfiguration zur Laufzeit automatisch, damit sie zur Dataset-YAML passt.

Backbone- und Head-Architektur#

Die Modellarchitektur besteht aus Backbone- (Merkmalsextraktion) und Head- (aufgabenspezifische) Abschnitten:

nc: 80

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]] # 3: Upsample
    - [[-1, 0], 1, Concat, [1]] # 4: Spatially compatible skip connection
    - [-1, 3, C2f, [256]] # 5: Process features
    - [[5], 1, Detect, [nc]] # 6: Detection layer

Schichtindizes laufen über das Backbone und den Head hinweg weiter, und verkettete Feature-Maps müssen übereinstimmende räumliche Dimensionen aufweisen.

Format der Schichtspezifikation#

Jede Schicht folgt dem einheitlichen Muster: [from, repeats, module, args]

KomponenteZweckBeispiele
fromEingangsverbindungen-1 (vorherige), 6 (Schicht 6), [4, 6, 8] (Multi-Input)
repeatsAnzahl der Wiederholungen1 (einzeln), 3 (3 Mal wiederholen)
moduleModultypConv, C2f, TorchVision, Detect
argsModulargumente[64, 3, 2] (Kanäle, Kernel, Schrittweite)

Verbindungsmuster#

Das Feld from erzeugt flexible Datenflussmuster in deinem gesamten Netzwerk:

- [-1, 1, Conv, [64, 3, 2]]    # Takes input from previous layer
Schichtindizierung

Schichten werden beginnend bei 0 indiziert. Negative Indizes verweisen auf vorherige Schichten (-1 = vorherige Schicht), während positive Indizes auf bestimmte Schichten über ihre Position verweisen.

Modulwiederholung#

Der Parameter repeats erstellt tiefere Netzwerkabschnitte:

- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layer

Die tatsächliche Wiederholungsanzahl wird mit dem Tiefenskalierungsfaktor aus deiner Modellgrößenkonfiguration multipliziert.

Verfügbare Module#

Module sind nach Funktionalität organisiert und im Ultralytics modules directory definiert. Die folgenden Tabellen zeigen häufig verwendete Module nach Kategorie, wobei viele weitere im Quellcode verfügbar sind:

Grundlegende Operationen#

ModulZweckQuelleArgumente
ConvKonvolution + BatchNorm + Aktivierungconv.py[out_ch, kernel, stride, pad, groups]
nn.UpsampleRäumliches UpsamplingPyTorch[size, scale_factor, mode]
nn.IdentityPass-Through-OperationPyTorch[]

Zusammengesetzte Blöcke#

ModulZweckQuelleArgumente
C2fCSP-Bottleneck mit 2 Konvolutionenblock.py[out_ch, shortcut, groups, expansion]
SPPFSpatial Pyramid Pooling (schnell)block.py[out_ch, kernel_size]
ConcatKanalweise Konkatenationconv.py[dimension]

Spezialisierte Module#

ModulZweckQuelleArgumente
TorchVisionLade ein beliebiges TorchVision-Modellblock.py[out_ch, model_name, weights, unwrap, truncate, split]
IndexExtrahiere einen spezifischen Tensor aus einer Listeconv.py[out_ch, index]
DetectYOLO-Erkennungs-Headhead.py[nc]
Vollständige Modulliste

Dies stellt einen Ausschnitt der verfügbaren Module dar. Eine vollständige Liste der Module und ihrer Parameter findest du im modules directory.

Erweiterte Funktionen#

TorchVision-Integration#

Das TorchVision-Modul ermöglicht die nahtlose Integration jedes TorchVision model als Backbone:

from ultralytics import YOLO

# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="imagenet10", epochs=100)
Multiskalen-Merkmale

Setze den letzten Parameter auf True, um Zwischen-Feature-Maps für die Multiskalen-Erkennung zu erhalten.

Index-Modul zur Merkmalsauswahl#

Wenn du Modelle verwendest, die mehrere Feature-Maps ausgeben, wählt das Index-Modul spezifische Ausgaben aus:

nc: 80

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 darüber, wie Ultralytics Module findet und importiert, ist entscheidend für Anpassungen:

Modul-Lookup-Prozess#

Ultralytics verwendet ein dreistufiges System in parse_model:

# Core resolution logic
m = (
    getattr(torch.nn, m[3:])
    if m.startswith("nn.")
    else getattr(__import__("torchvision").ops, m[16:])
    if m.startswith("torchvision.ops.")
    else globals()[m]
)  # get module
  1. PyTorch-Module: Namen, die mit 'nn.' beginnen → Namensraum torch.nn
  2. TorchVision-Operationen: Namen, die mit 'torchvision.ops.' beginnen → Namensraum torchvision.ops
  3. Ultralytics-Module: Alle anderen Namen → globaler Namespace über Importe

Modul-Importkette#

Standardmodule werden über 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 deine eigenen Module zu integrieren, kann aber kompliziert sein. Um ein benutzerdefiniertes Modul zu definieren und zu verwenden, befolge diese Schritte:

  1. Installiere Ultralytics im Entwicklungsmodus über die Git-Klon-Methode aus dem Quickstart guide.

  2. 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)
  3. Mache dein Modul auf Pakete-Ebene verfügbar in ultralytics/nn/modules/__init__.py:

    from .block import CustomBlock  # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock
  4. Zu Importen hinzufügen in ultralytics/nn/tasks.py:

    from ultralytics.nn.modules import CustomBlock  # noqa
  5. Füge das Modul zu base_modules hinzu innerhalb von parse_model(). Module in diesem Set erhalten automatisch Eingabe- und Ausgabekanäle:

    base_modules = frozenset(
        {
            # Existing modules...
            CustomBlock,
        }
    )
  6. Verwende das Modul in deinem Modell-YAML:

    # custom_model.yaml
    nc: 1
    backbone:
        - [-1, 1, CustomBlock, [64]]
    head:
        - [-1, 1, Classify, [nc]]
  7. Ü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]] # 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

Klassifizierungsmodell#

# 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]]

head:
    - [-1, 1, Classify, [nc]]

Classify führt bereits intern ein adaptives Average Pooling aus.

Best Practices#

Tipps für den Architekturentwurf#

Starte einfach: Beginne mit bewährten Architekturen, bevor du sie anpasst. Verwende bestehende YOLO-Konfigurationen als Vorlagen und nimm schrittweise Änderungen vor, anstatt von Grund auf neu zu bauen.

Teste schrittweise: Überprüfe jede Modifikation Schritt für Schritt. Füge jeweils ein benutzerdefiniertes Modul hinzu und stelle sicher, dass es funktioniert, bevor du zum nächsten Schritt übergehst.

Kanäle überwachen: Stelle sicher, dass die Kanaldimensionen zwischen verbundenen Schichten übereinstimmen. Die Ausgabekanäle (c2) einer Schicht müssen mit den Eingangskanälen (c1) der nächsten Schicht in der Sequenz übereinstimmen.

Skip-Verbindungen nutzen: Nutze die Wiederverwendung von Features mit [[-1, N], 1, Concat, [1]]-Mustern. Diese Verbindungen unterstützen den Gradientenfluss und ermöglichen es dem Modell, Merkmale aus verschiedenen Skalen zu kombinieren.

Angemessen skalieren: Wähle Modellskalen basierend auf deinen Rechenbeschränkungen. Verwende Nano (n) für Edge-Geräte, Klein (s) für ausgewogene Leistung und größere Skalen (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 pro Schicht verarbeiten. Wäge dies basierend auf deiner Aufgabenkomplexität ab.

Skip-Connections: Verbessern den Gradientenfluss während des Trainings und ermöglichen die Wiederverwendung von Merkmalen im gesamten Netzwerk. Sie sind besonders in tieferen Architekturen wichtig, um verschwindende Gradienten zu verhindern.

Bottleneck-Blöcke: Reduziere die Rechenkosten bei gleichzeitiger Beibehaltung der Modellausdruckskraft. Module wie C2f verwenden weniger Parameter als Standardkonvolutionen und bewahren gleichzeitig die Fähigkeit zum Merkmalslernen.

Multi-Scale-Merkmale: Essenziell für die Erkennung von Objekten unterschiedlicher Größe im selben Bild. Verwende Feature Pyramid Network (FPN)-Muster mit mehreren Detektionsköpfen auf verschiedenen Skalen.

Fehlerbehebung#

Häufige Probleme#

ProblemUrsacheLösung
KeyError: 'ModuleName'Modul nicht importiertZu den Importen von tasks.py hinzufügen
Kanalabmessungen stimmen nicht übereinFalsche Spezifikation von argsKompatibilität der Ein-/Ausgabekanäle prüfen
AttributeError: 'int' object has no attributeFalscher ArgumenttypÜberprüfe die Moduldokumentation auf korrekte Argumenttypen
Modell lässt sich nicht erstellenUngültige Referenz für fromStelle sicher, dass die referenzierten Schichten existieren

Debugging-Tipps#

Bei der Entwicklung benutzerdefinierter Architekturen hilft systematisches Debugging, Probleme frühzeitig zu erkennen:

Verwende Identity Head zum Testen

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 debugging

Dies ermöglicht die direkte Inspektion der Backbone-Ausgaben:

import torch

from ultralytics import YOLO

model = YOLO("debug_model.yaml", task="detect")
output = model.model(torch.randn(1, 3, 640, 640))
print(f"Output shape: {output.shape}")  # Should match expected dimensions

Inspektion der Modellarchitektur

Die Überprüfung der FLOPs-Anzahl und das Ausdrucken jeder Schicht können ebenfalls beim Debuggen von Problemen mit deiner benutzerdefinierten Modellkonfiguration helfen. Die FLOPs-Anzahl sollte bei einem gültigen Modell ungleich Null sein. Wenn sie Null ist, liegt wahrscheinlich ein Problem mit dem Forward-Pass vor. Die Ausführung eines einfachen Forward-Pass sollte den genauen Fehler anzeigen, auf den du stößt.

from ultralytics import YOLO

# Build model with verbose output to see layer details
model = YOLO("debug_model.yaml", task="detect", 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}")

Schritt-für-Schritt-Validierung

  1. Minimal starten: Teste zuerst mit der einfachsten möglichen Architektur
  2. Inkrementell hinzufügen: Baue die Komplexität Schicht für Schicht auf
  3. Dimensionen prüfen: Überprüfe die Kompatibilität von Kanal- und räumlicher Größe
  4. Skalierung validieren: Teste mit verschiedenen Modellskalen (n, s, m)

FAQ#

  • Setze den Parameter nc oben in deiner YAML-Datei, damit er mit der Anzahl der Klassen deines Datensatzes übereinstimmt.

    nc: 5 # 5 classes
  • Ja. Du kannst jedes unterstützte Modul verwenden, einschließlich TorchVision backbones, oder dein eigenes benutzerdefiniertes Modul definieren und es wie in Custom Module Integration beschrieben importieren.

  • Verwende den scales section 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 lädst und die Skala an den Dateinamen anhängst (z. B. yolo26n.yaml).

  • Dieses Format legt fest, wie jede Schicht aufgebaut ist:

    • from: Eingangsquelle(n)
    • repeats: Häufigkeit der Wiederholung des Moduls
    • module: Der Schichttyp
    • args: Argumente für das Modul
  • Überprüfe, ob die Ausgabekanäle einer Schicht mit den erwarteten Eingangskanälen der nächsten Schicht übereinstimmen. Verwende print(model.model.model), um die Architektur deines Modells zu untersuchen.

  • Überprüfe den Quellcode im ultralytics/nn/modules directory auf alle verfügbaren Module und deren Argumente.

  • Definiere dein Modul im Quellcode, importiere es wie in Source Code Modification gezeigt und referenziere es namentlich in deiner YAML-Datei.

  • Ja, du kannst model.load("path/to/weights") verwenden, um Gewichte aus einem vortrainierten Checkpoint zu laden. Allerdings werden nur Gewichte für Schichten, die übereinstimmen, erfolgreich geladen.

  • Verwende model.info(), um zu prüfen, ob die Anzahl der FLOPs ungleich Null ist. Ein gültiges Modell sollte eine FLOPs-Anzahl ungleich Null aufweisen. Wenn sie Null ist, befolge die Vorschläge in Debugging Tips, um das Problem zu finden.

Kommentare