Ultralytics YOLO27:

Leitfaden zur YAML-Konfiguration von Modellen#

Die YAML-Konfigurationsdatei des Modells dient als architektonischer Bauplan für neuronale Netzwerke von Ultralytics. Sie legt fest, wie Layer verbunden sind, welche Parameter die einzelnen Module verwenden und wie das gesamte Netzwerk über verschiedene Modellgrößen hinweg skaliert wird.

Model YAML configuration workflow.

Konfigurationsstruktur#

YAML-Dateien von Modellen sind in drei Hauptabschnitte gegliedert, die gemeinsam die Architektur definieren.

Abschnitt „Parameter“#

Der Abschnitt parameters 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 kombinierte Skalierungsfaktoren, die Tiefe, Breite und die maximale Kanalanzahl des Modells anpassen, um Varianten verschiedener Größen zu erzeugen (von Nano bis Extra-Large).
  • kpt_shape gilt für Posenschätzungsmodelle. Der Wert kann für (x, y) Keypoints [N, 2] oder für (x, y, visibility) [N, 3] sein.
Redundanz mit `scales` reduzieren

Mit dem Parameter scales kannst du aus einer einzigen Basis-YAML mehrere Modellgrößen erzeugen. Wenn du beispielsweise yolo26n.yaml lädst, liest Ultralytics die Basisdatei yolo26.yaml ein und wendet die Skalierungsfaktoren n (depth=0.50, width=0.25) an, um die Nano-Variante zu erstellen.

`nc` und `kpt_shape` sind datensatzabhängig

Wenn dein Datensatz ein anderes nc oder kpt_shape festlegt, überschreibt Ultralytics die Modellkonfiguration zur Laufzeit automatisch, damit sie zur YAML-Datei des Datensatzes passt.

Architektur von Backbone und Kopf#

Die Modellarchitektur besteht aus den Abschnitten Backbone (Merkmalsextraktion) und Kopf (aufgabenspezifisch):

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

Die Indizes der Layer werden über Backbone und Kopf hinweg fortgeführt, und verkettete Merkmalskarten müssen übereinstimmende räumliche Dimensionen haben.

Format der Layer-Spezifikation#

Jeder Layer folgt dem einheitlichen Muster: [from, repeats, module, args]

KomponenteZweckBeispiele
fromEingangsverbindungen-1 (vorheriger Layer), 6 (Layer 6), [4, 6, 8] (mehrere Eingänge)
repeatsAnzahl der Wiederholungen1 (einzeln), 3 (3-mal wiederholen)
moduleModultypConv, C2f, TorchVision, Detect
argsModulargumente[64, 3, 2] (Kanäle, Kernel, Schrittweite)

Verbindungsmuster#

Das Feld from ermöglicht flexible Datenflussmuster in deinem gesamten Netzwerk:

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

Die Indizierung der Layer beginnt bei 0. Negative Indizes verweisen auf vorherige Layer (-1 = vorheriger Layer), während positive Indizes anhand ihrer Position auf bestimmte Layer verweisen.

Wiederholung von Modulen#

Der Parameter repeats 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 der Konfiguration deiner Modellgröße 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. Im Quellcode sind viele weitere verfügbar:

Grundlegende Operationen#

ModulZweckQuelleArgumente
ConvConvolution + BatchNorm + Aktivierungconv.py[out_ch, kernel, stride, pad, groups]
nn.UpsampleRäumliches UpsamplingPyTorch[size, scale_factor, mode]
nn.IdentityDurchleitungsoperationPyTorch[]

Zusammengesetzte Blöcke#

ModulZweckQuelleArgumente
C2fCSP-Bottleneck mit 2 Convolution-Layernblock.py[out_ch, shortcut, groups, expansion]
SPPFRäumliches Pyramid Pooling (schnell)block.py[out_ch, kernel_size]
ConcatVerkettung entlang der Kanäleconv.py[dimension]

Spezialisierte Module#

ModulZweckQuelleArgumente
TorchVisionBeliebiges torchvision-Modell ladenblock.py[out_ch, model_name, weights, unwrap, truncate, split]
IndexBestimmten Tensor aus einer Liste extrahierenconv.py[out_ch, index]
DetectYOLO-Erkennungskopfhead.py[nc]
Vollständige Modulliste

Dies stellt eine Auswahl der verfügbaren Module dar. Eine vollständige Liste der Module und ihrer Parameter findest du im 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="imagenet10", epochs=100)
Merkmale auf mehreren Maßstabsebenen

Setze den letzten Parameter auf True, um Zwischenmerkmalskarten für die Erkennung auf mehreren Maßstabsebenen zu erhalten.

Index-Modul zur Merkmalsauswahl#

Bei Modellen, die mehrere Merkmalskarten ausgeben, wählt das Index-Modul bestimmte 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

System zur Modulauflösung#

Für Anpassungen ist es entscheidend zu verstehen, wie Ultralytics Module findet und importiert:

Prozess zur Modulsuche#

Ultralytics verwendet in parse_model ein dreistufiges System:

# 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 → Namespace torch.nn
  2. TorchVision-Operationen: Namen, die mit 'torchvision.ops.' beginnen → Namespace torchvision.ops
  3. Ultralytics-Module: Alle anderen Namen → globaler Namespace über Importe

Importkette für Module#

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 die vielseitigste Möglichkeit, eigene Module zu integrieren, kann aber knifflig sein. Um ein benutzerdefiniertes Modul zu definieren und zu verwenden, befolge diese Schritte:

  1. Ultralytics im Entwicklungsmodus installieren mithilfe der Git-Klonmethode aus dem Schnellstartleitfaden.

  2. Dein Modul definieren 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. Dein Modul auf Paketebene verfügbar machen in ultralytics/nn/modules/__init__.py:

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

    from ultralytics.nn.modules import CustomBlock  # noqa
  5. Das Modul zu base_modules hinzufügen in parse_model(). Module in dieser Gruppe erhalten automatisch Eingangs- und Ausgangskanäle:

    base_modules = frozenset(
        {
            # Existing modules...
            CustomBlock,
        }
    )
  6. Das Modul in deiner Modell-YAML verwenden:

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

Grundlegendes 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

Modell mit TorchVision-Backbone#

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

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

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

Bewährte Vorgehensweisen#

Tipps zur Architekturentwicklung#

Einfach anfangen: Beginne mit bewährten Architekturen, bevor du Anpassungen vornimmst. Verwende vorhandene YOLO-Konfigurationen als Vorlagen und ändere sie schrittweise, anstatt von Grund auf neu zu beginnen.

Schrittweise testen: Überprüfe jede Änderung Schritt für Schritt. Füge jeweils nur ein benutzerdefiniertes Modul 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 Ausgangskanäle (c2) einer Schicht müssen mit den Eingangskanälen (c1) der nächsten Schicht in der Sequenz übereinstimmen.

Skip Connections verwenden: Nutze die Wiederverwendung von Merkmalen mit Mustern wie [[-1, N], 1, Concat, [1]]. Diese Verbindungen verbessern den Gradientenfluss und ermöglichen es dem Modell, Merkmale aus verschiedenen Maßstäben zu kombinieren.

Passend skalieren: Wähle die Modellskalierung entsprechend deinen Rechenressourcen. Verwende Nano (n) für Edge-Geräte, Small (s) für ein ausgewogenes Verhältnis von Leistung und Genauigkeit sowie größere Skalierungen (m, l, x) für maximale Genauigkeit.

Überlegungen zur Leistung#

Tiefe vs. Breite: Tiefe Netzwerke erfassen komplexe hierarchische Merkmale über mehrere Transformationsschichten, während breite Netzwerke auf jeder Schicht mehr Informationen parallel verarbeiten. Stimme beides auf die Komplexität deiner Aufgabe ab.

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

Bottleneck-Blöcke: Sie verringern den Rechenaufwand und erhalten gleichzeitig die Ausdrucksfähigkeit des Modells. Module wie C2f verwenden weniger Parameter als Standardfaltungen und bewahren dabei die Fähigkeit zum Lernen von Merkmalen.

Merkmale über mehrere Maßstäbe: Sie sind unverzichtbar, um Objekte unterschiedlicher Größe im selben Bild zu erkennen. Verwende Muster eines Feature Pyramid Network (FPN) mit mehreren Erkennungsköpfen auf unterschiedlichen Maßstäben.

Fehlerbehebung#

Häufige Probleme#

ProblemUrsacheLösung
KeyError: 'ModuleName'Modul nicht importiertFüge es zu den Imports in tasks.py hinzu
Nicht übereinstimmende KanalabmessungenFalsche Spezifikation von argsÜberprüfe die Kompatibilität der Eingangs- und Ausgangskanäle
AttributeError: 'int' object has no attributeFalscher ArgumenttypPrüfe die Dokumentation des Moduls auf die korrekten Argumenttypen
Modell lässt sich nicht erstellenUngültige Referenz auf fromStelle sicher, dass die referenzierten Schichten vorhanden sind

Tipps zur Fehlersuche#

Bei der Entwicklung benutzerdefinierter Architekturen hilft eine systematische Fehlersuche, Probleme frühzeitig zu erkennen:

Identitätskopf zum Testen verwenden

Ersetze komplexe Köpfe durch nn.Identity, um Probleme im Backbone zu isolieren:

nc: 1
backbone:
    - [-1, 1, CustomBlock, [64]]
head:
    - [-1, 1, nn.Identity, []] # Pass-through for debugging

So kannst du die Ausgaben des Backbones direkt überprüfen:

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

Modellarchitektur überprüfen

Das Überprüfen der FLOPs-Anzahl und die Ausgabe jeder Schicht können ebenfalls dabei helfen, Probleme mit deiner benutzerdefinierten Modellkonfiguration zu finden. Die FLOPs-Anzahl sollte bei einem gültigen Modell ungleich null sein. Wenn sie null ist, liegt wahrscheinlich ein Problem beim Forward-Pass vor. Ein einfacher Forward-Pass sollte den genau auftretenden Fehler anzeigen.

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}")

Schrittweise Validierung

  1. Minimal beginnen: Teste zuerst die einfachstmögliche Architektur
  2. Schrittweise erweitern: Baue die Komplexität Schicht für Schicht auf
  3. Abmessungen überprüfen: Überprüfe die Kompatibilität der Kanal- und räumlichen Abmessungen
  4. Skalierung validieren: Teste verschiedene Modellskalierungen (n, s, m)

FAQ#

  • Setze den Parameter nc am Anfang deiner YAML-Datei auf die Anzahl der Klassen in deinem Datensatz.

    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 unter Integration benutzerdefinierter Module beschrieben importieren.

  • Verwende den scales-Abschnitt in deiner YAML-Datei, um Skalierungsfaktoren für Tiefe, Breite und maximale Kanalanzahl zu definieren. Das Modell wendet diese automatisch an, wenn du die Basis-YAML-Datei mit der an den Dateinamen angehängten Skalierung lädst (z. B. yolo26n.yaml).

  • Dieses Format legt fest, wie jede Schicht erstellt wird:

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

  • Prüfe den Quellcode im ultralytics/nn/modules-Verzeichnis auf alle verfügbaren Module und ihre Argumente.

  • Definiere dein Modul im Quellcode, importiere es wie unter Änderung des Quellcodes gezeigt und verweise in deiner YAML-Datei über seinen Namen darauf.

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

  • Verwende model.info(), um zu überprü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.

Kommentare