Ultralytics YOLO27:
Get Started

Leitfaden zur YAML-Modellkonfiguration#

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

Model YAML configuration workflow.

Aufbau der Konfiguration#

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

Abschnitt „Parameters“#

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 zusammengesetzte Skalierungsfaktoren, mit denen Tiefe, Breite und maximale Kanalanzahl des Modells angepasst werden, um verschiedene Modellgrößen zu erzeugen (von Nano bis Extra Large).
  • kpt_shape gilt für Pose-Modelle. Der Wert kann [N, 2] für (x, y) Keypoints oder [N, 3] für (x, y, visibility) sein.
Redundanz mit `scales` reduzieren

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

`nc` und `kpt_shape` hängen vom Datensatz ab

Wenn dein Datensatz einen anderen Wert für nc oder kpt_shape festlegt, überschreibt Ultralytics die Modellkonfiguration zur Laufzeit automatisch, damit sie mit der YAML-Datei des Datensatzes übereinstimmt.

Architektur von Backbone und Head#

Die Modellarchitektur besteht aus den Abschnitten Backbone (Merkmalsextraktion) und Head (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 Indizierung der Schichten läuft über Backbone und Head hinweg fort. Zusammengeführte Feature-Maps müssen dieselben räumlichen Dimensionen haben.

Format der Schichtdefinition#

Für jede Schicht gilt dasselbe Muster: [from, repeats, module, args]

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

Verbindungsmuster#

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

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

Die Schichten werden ab 0 indiziert. Negative Indizes verweisen auf vorherige Schichten (-1 = vorherige Schicht), positive Indizes auf bestimmte Schichten anhand ihrer Position.

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 Skalierungsfaktor für die Tiefe multipliziert, der in der Konfiguration der Modellgröße festgelegt ist.

Verfügbare Module#

Die Module sind nach Funktion geordnet und im Modulverzeichnis von Ultralytics definiert. Die folgenden Tabellen zeigen häufig verwendete Module nach Kategorie. Im Quellcode stehen viele weitere zur Verfügung:

Grundlegende Operationen#

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

Zusammengesetzte Blöcke#

ModulZweckQuelleArgumente
C2fCSP-Engpass mit 2 Faltungenblock.py[out_ch, shortcut, groups, expansion]
SPPFRäumliches Pyramiden-Pooling (schnell)block.py[out_ch, kernel_size]
ConcatZusammenführung 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-Erkennungs-Headhead.py[nc]
Vollständige Modulliste

Hier ist eine Auswahl der verfügbaren Module zu sehen. Die 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

# Modell mit ConvNeXt-Backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="imagenet10", epochs=100)
Mehrskalige Merkmale

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

Das Index-Modul zur Merkmalsauswahl#

Wenn du Modelle verwendest, die mehrere Feature-Maps 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

Modulauflösungssystem#

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

Ablauf der Modulsuche#

Ultralytics verwendet ein dreistufiges System in parse_model:

# Kernlogik zur Auflösung
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]
)  # Modul abrufen
  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 Namensraum über Importe

Modul-Importkette#

Standardmodule werden über Importe in tasks.py verfügbar:

from ultralytics.nn.modules import (  # noqa: F401
    SPPF,
    C2f,
    Conv,
    Detect,
    # ... viele weitere Module
    Index,
    TorchVision,
)

Integration benutzerdefinierter Module#

Änderungen am Quellcode#

Änderungen am Quellcode bieten die flexibelste Möglichkeit, benutzerdefinierte Module zu integrieren, können aber knifflig sein. Gehe wie folgt vor, um ein benutzerdefiniertes Modul zu definieren und zu verwenden:

  1. Installiere Ultralytics im Entwicklungsmodus mithilfe der Git-Klonmethode aus der Schnellstartanleitung.

  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 Paketebene verfügbar in ultralytics/nn/modules/__init__.py:

    from .block import CustomBlock  # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock
  4. Füge es zu den Importen hinzu in ultralytics/nn/tasks.py:

    from ultralytics.nn.modules import CustomBlock  # noqa
  5. Füge das Modul zu base_modules hinzu in parse_model(). Module in dieser Menge erhalten automatisch Eingangs- und Ausgangskanäle:

    base_modules = frozenset(
        {
            # Vorhandene Module...
            CustomBlock,
        }
    )
  6. Verwende das Modul in deiner Modell-YAML:

    # custom_model.yaml
    nc: 1
    backbone:
        - [-1, 1, CustomBlock, [64]]
    head:
        - [-1, 1, Classify, [nc]]
  7. Prüfe die FLOPs, um sicherzustellen, dass der Forward-Pass funktioniert:

    from ultralytics import YOLO
    
    model = YOLO("custom_model.yaml", task="classify")
    model.info()  # sollte bei erfolgreicher Ausführung ungleich null FLOPs ausgeben

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 durch.

Bewährte Vorgehensweisen#

Tipps zum Architekturdesign#

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

Schrittweise testen: Überprüfe jede Änderung Schritt für Schritt. Füge jeweils ein eigenes Modul hinzu und stelle sicher, dass es funktioniert, bevor du mit der nächsten Änderung fortfährst.

Kanäle überwachen: Achte darauf, 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.

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

Passend skalieren: Wähle die Modellgrößen entsprechend deinen Rechenkapazitäten. Verwende 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 im Vergleich zur Breite: Tiefe Netzwerke erfassen komplexe hierarchische Merkmale durch mehrere Transformationsschichten, während breite Netzwerke auf jeder Schicht mehr Informationen parallel verarbeiten. Stimme beides auf die Komplexität deiner Aufgabe ab.

Skip Connections: 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: Senken die Rechenkosten und bewahren dabei die Ausdrucksfähigkeit des Modells. Module wie C2f verwenden weniger Parameter als Standardfaltungen und erhalten gleichzeitig die Fähigkeit, Merkmale zu lernen.

Merkmale verschiedener Maßstäbe: Sie sind unverzichtbar, wenn Objekte unterschiedlicher Größe im selben Bild erkannt werden sollen. Verwende Muster eines Feature Pyramid Network (FPN) mit mehreren Erkennungsköpfen auf verschiedenen Maßstäben.

Fehlerbehebung#

Häufige Probleme#

ProblemUrsacheLösung
KeyError: 'ModuleName'Modul nicht importiertZu den Imports in tasks.py hinzufügen
Abweichende KanalabmessungenFalsche Spezifikation von argsKompatibilität der Ein- und Ausgabekanäle überprüfen
AttributeError: 'int' object has no attributeFalscher ArgumenttypIn der Moduldokumentation nach den korrekten Argumenttypen suchen
Modell lässt sich nicht erstellenUngültiger Verweis auf fromSicherstellen, dass die referenzierten Schichten vorhanden sind

Tipps zur Fehlersuche#

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

Identity-Kopf zum Testen verwenden

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

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

So lassen sich die Backbone-Ausgaben direkt untersuchen:

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 untersuchen

Die FLOPs zu prüfen und jede Schicht auszugeben, kann ebenfalls helfen, Probleme mit deiner eigenen Modellkonfiguration zu beheben. Bei einem gültigen Modell sollte der FLOPs-Wert größer als null sein. Ist er null, liegt wahrscheinlich ein Problem beim Forward-Pass vor. Ein einfacher Forward-Pass sollte den genauen 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 überprüfen

  1. Mit dem Minimum beginnen: Zuerst mit der einfachstmöglichen Architektur testen
  2. Schrittweise erweitern: Die Komplexität Schicht für Schicht erhöhen
  3. Abmessungen prüfen: Kompatibilität der Kanalanzahl und der räumlichen Größe überprüfen
  4. Skalierung überprüfen: Mit verschiedenen Modellgrößen testen (n, s, m)

Häufig gestellte Fragen#

  • Lege den Parameter nc am Anfang deiner YAML-Datei so fest, dass er der Anzahl der Klassen in deinem Datensatz entspricht.

    nc: 5 # 5 classes
  • Ja. Du kannst jedes unterstützte Modul verwenden, darunter TorchVision-Backbones, oder ein eigenes Modul definieren und es wie unter Integration eigener Module beschrieben importieren.

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

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

    • from: Eingabequelle(n)
    • repeats: Anzahl der Wiederholungen des Moduls
    • module: Typ der Schicht
    • args: Argumente für das Modul
  • Prü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.

  • Im Quellcodeverzeichnis ultralytics/nn/modules findest du alle verfügbaren Module und ihre Argumente.

  • Definiere dein Modul im Quellcode, importiere es wie unter Quellcode ändern beschrieben und verweise in deiner YAML-Datei mit seinem Namen darauf.

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

  • Verwende model.info(), um zu prüfen, ob der FLOPs-Wert größer als null ist. Bei einem gültigen Modell sollte der FLOPs-Wert größer als null sein. Ist er null, befolge die Vorschläge unter Tipps zur Fehlersuche, um das Problem zu finden.

Kommentare