Modèle de configuration YAML
Le fichier de configuration YAML du modèle sert de plan architectural pour les réseaux neuronaux Ultralytics . Il définit le mode de connexion des couches, les paramètres utilisés par chaque module et la manière dont l'ensemble du réseau évolue en fonction de la taille du modèle.
Structure de configuration
Les fichiers YAML du modèle sont organisés en trois sections principales qui collaborent pour définir l'architecture.
Section des paramètres
La section des paramètres spécifie les caractéristiques globales et le comportement de mise à l'échelle du modèle :
# 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
définit le nombre de classes prédites par le modèle.scales
définir des facteurs d'échelle composés qui ajustent la profondeur, la largeur et les canaux maximums du modèle pour produire différentes variantes de taille (de nano à extra-large).kpt_shape
s'applique aux modèles de pose. Il peut être[N, 2]
pour la(x, y)
points clés ou[N, 3]
pour la(x, y, visibility)
.
Réduire la redondance avec scales
L'argument scales
vous permet de générer plusieurs tailles de modèles à partir d'un seul YAML de base. Par exemple, lorsque vous chargez yolo11n.yaml
Ultralytics lit la base yolo11.yaml
et applique le n
les facteurs d'échelle (depth=0.50
, width=0.25
) pour construire la variante nano.
nc
et kpt_shape
dépendent de l'ensemble des données
Si votre jeu de données spécifie un nc
ou kpt_shape
Ultralytics remplacera automatiquement la configuration du modèle au moment de l'exécution pour correspondre au jeu de données YAML.
Architecture de base et de tête
L'architecture du modèle se compose d'une colonne vertébrale (extraction des caractéristiques) et d'une tête (tâches spécifiques) :
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 de spécification de la couche
Chaque couche suit le même schéma : [from, repeats, module, args]
Composant | Objectif | Exemples |
---|---|---|
de | Connexions d'entrée | -1 (précédent), 6 (couche 6), [4, 6, 8] (à entrées multiples) |
répète | Nombre de répétitions | 1 (simple), 3 (répéter 3 fois) |
module | Type de module | Conv , C2f , TorchVision , Detect |
args | Arguments du module | [64, 3, 2] (canaux, kernel, stride) |
Modèles de connexion
L'argument from
permet de créer des schémas de flux de données flexibles dans l'ensemble du réseau :
- [-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
Indexation des couches
Les couches sont indexées à partir de 0. Les indices négatifs font référence aux couches précédentes (-1
= couche précédente), tandis que les indices positifs font référence à des couches spécifiques par leur position.
Répétition du module
L'argument repeats
crée des sections de réseau plus profondes :
- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layer
Le nombre réel de répétitions est multiplié par le facteur d'échelle de profondeur de la configuration de la taille du modèle.
Modules disponibles
Les modules sont organisés par fonctionnalité et définis dans le répertoire des modules d'Ultralytics . Les tableaux suivants présentent les modules les plus couramment utilisés par catégorie, et de nombreux autres sont disponibles dans le code source :
Opérations de base
Module | Objectif | Source | Arguments |
---|---|---|---|
Conv |
Convolution + BatchNorm + Activation | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample |
Suréchantillonnage spatial | PyTorch | [size, scale_factor, mode] |
nn.Identity |
Opération de passage | PyTorch | [] |
Blocs composites
Module | Objectif | Source | Arguments |
---|---|---|---|
C2f |
Goulot d'étranglement CSP avec 2 convolutions | block.py | [out_ch, shortcut, expansion] |
SPPF |
Mise en commun des pyramides spatiales (rapide) | block.py | [out_ch, kernel_size] |
Concat |
Concaténation par canal | conv.py | [dimension] |
Modules spécialisés
Module | Objectif | Source | Arguments |
---|---|---|---|
TorchVision |
Charger n'importe quel modèle torchvision | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index |
Extraire un tensor spécifique de la liste | block.py | [out_ch, index] |
Detect |
Tête de détection YOLO | head.py | [nc, anchors, ch] |
Liste complète des modules
Il s'agit d'un sous-ensemble des modules disponibles. Pour obtenir la liste complète des modules et de leurs paramètres, consultez le répertoire des modules.
Fonctionnalités avancées
Intégration de TorchVision
Le module TorchVision permet l'intégration transparente de n'importe quel modèle TorchVision en tant qu'épine dorsale :
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]]
Ventilation des paramètres :
768
: Canaux de sortie attendusconvnext_tiny
: Architecture du modèle (modèles disponibles)DEFAULT
: Utiliser les poids pré-entraînésTrue
: Retirer la tête de classification2
: Tronquer les 2 dernières couchesFalse
: Retourne un seul tensor (pas une liste)
Caractéristiques multi-échelles
Fixer le dernier paramètre à True
afin d'obtenir des cartes de caractéristiques intermédiaires pour la détection multi-échelle.
Module d'indexation pour la sélection des caractéristiques
Lors de l'utilisation de modèles produisant plusieurs cartes d'entités, le module Index sélectionne des sorties spécifiques :
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
Système de résolution des modules
Comprendre comment Ultralytics localise et importe les modules est crucial pour la personnalisation :
Processus de consultation des modules
Ultralytics utilise un système à trois niveaux en 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]
- Modules PyTorch: Noms commençant par
'nn.'
→torch.nn
espace de noms - Opérations de TorchVision: Noms commençant par
'ops.'
→torchvision.ops
espace de noms - ModulesUltralytics : Tous les autres noms → espace de noms global via les importations
Chaîne d'importation de modules
Les modules standard sont disponibles par le biais d'importations dans tasks.py
:
from ultralytics.nn.modules import ( # noqa: F401, E501
SPPF,
C2f,
Conv,
Detect,
# ... many more modules
Index,
TorchVision,
)
Intégration de modules personnalisés
Modification du code source
La modification du code source est le moyen le plus polyvalent d'intégrer vos modules personnalisés, mais elle peut s'avérer délicate. Pour définir et utiliser un module personnalisé, suivez les étapes suivantes :
-
Définir votre module dans
ultralytics/nn/modules/block.py
:class CustomBlock(nn.Module): def __init__(self, c1, c2): super().__init__() self.layers = nn.Sequential(nn.Conv2d(c1, c2, 3, 1, 1), nn.BatchNorm2d(c2), nn.ReLU()) def forward(self, x): return self.layers(x)
-
Exposer votre module au niveau du paquetage dans
ultralytics/nn/modules/__init__.py
:from .block import CustomBlock # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock
-
Ajouter aux importations dans
ultralytics/nn/tasks.py
:from ultralytics.nn.modules import CustomBlock # noqa
-
Traiter les arguments spéciaux (si nécessaire) à l'intérieur
parse_model()
dansultralytics/nn/tasks.py
:elif m is CustomBlock: c1, c2 = ch[f], args[0] # input channels, output channels args = [c1, c2, *args[1:]]
-
Utilisez le module dans votre modèle YAML :
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]]
-
Vérifier les FLOP pour s'assurer que la passe en avant fonctionne :
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # should print non-zero FLOPs if working
Exemples de configurations
Modèle de détection de base
# 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
Modèle de dorsale TorchVision
# 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
Modèle de classification
# 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]]
Meilleures pratiques
Conseils pour la conception de l'architecture
Commencer simple: Commencez par des architectures éprouvées avant de les personnaliser. Utilisez les configurations YOLO existantes comme modèles et modifiez-les progressivement plutôt que de partir de zéro.
Tester de manière incrémentale: Validez chaque modification étape par étape. Ajoutez un module personnalisé à la fois et vérifiez qu'il fonctionne avant de passer à la modification suivante.
Canaux de surveillance: Veiller à ce que les dimensions des canaux correspondent entre les couches connectées. Les canaux de sortie (c2
) d'une couche doit correspondre aux canaux d'entrée (c1
) de la couche suivante dans la séquence.
Utiliser le saut de connexion: Tirer parti de la réutilisation des fonctionnalités avec [[-1, N], 1, Concat, [1]]
des modèles. Ces connexions facilitent l'écoulement des gradients et permettent au modèle de combiner des caractéristiques à différentes échelles.
Une échelle appropriée: Choisissez les échelles du modèle en fonction de vos contraintes de calcul. Utilisez les nano (n
) pour les dispositifs de bordure, les petites (s
) pour une performance équilibrée, et des échelles plus grandes (m
, l
, x
) pour une précision maximale.
Considérations sur les performances
Profondeur ou largeur: les réseaux profonds capturent des caractéristiques hiérarchiques complexes par le biais de plusieurs couches de transformation, tandis que les réseaux larges traitent davantage d'informations en parallèle à chaque couche. Équilibrez ces deux types de réseaux en fonction de la complexité de votre tâche.
Sauter les connexions: Améliorent le flux de gradient pendant la formation et permettent la réutilisation des caractéristiques dans l'ensemble du réseau. Elles sont particulièrement importantes dans les architectures plus profondes pour éviter la disparition des gradients.
Blocs d'étranglement: Réduire les coûts de calcul tout en maintenant l'expressivité du modèle. Des modules comme C2f
utilisent moins de paramètres que les convolutions standard tout en préservant la capacité d'apprentissage des caractéristiques.
Caractéristiques multi-échelles: Essentielles pour la détection d'objets de tailles différentes sur une même image. Utilisez des modèles de réseau pyramidal de caractéristiques (FPN) avec plusieurs têtes de détection à différentes échelles.
Dépannage
Problèmes courants
Problème | Cause | Solution |
---|---|---|
KeyError: 'ModuleName' |
Module non importé | Ajouter à la liste tasks.py importations |
Inadéquation des dimensions du canal | Incorrect args spécification |
Vérifier la compatibilité des canaux d'entrée et de sortie |
AttributeError: 'int' object has no attribute |
Mauvais type d'argument | Vérifier la documentation du module pour s'assurer que les types d'arguments sont corrects |
Le modèle ne se construit pas | Invalide from référence |
S'assurer de l'existence des couches référencées |
Conseils de débogage
Lors du développement d'architectures personnalisées, le débogage systématique permet d'identifier les problèmes à un stade précoce :
Utiliser la tête d'identité pour les tests
Remplacer les têtes complexes par nn.Identity
afin d'isoler les problèmes liés à l'épine dorsale :
nc: 1
backbone:
- [-1, 1, CustomBlock, [64]]
head:
- [-1, 1, nn.Identity, []] # Pass-through for debugging
Cela permet d'inspecter directement les sorties de l'épine dorsale :
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
Inspection de l'architecture du modèle
La vérification du nombre de FLOPs et l'impression de chaque couche peuvent également aider à déboguer les problèmes liés à la configuration de votre modèle personnalisé. Le nombre de FLOPs doit être différent de zéro pour un modèle valide. Si c'est le cas, il y a probablement un problème avec la passe avant. L'exécution d'une simple passe avant devrait montrer l'erreur exacte rencontrée.
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}")
Validation étape par étape
- Commencez par le minimum: Tester d'abord l'architecture la plus simple possible
- Ajouter de manière incrémentale: Construire la complexité couche par couche
- Vérifier les dimensions: Vérifier la compatibilité des canaux et des dimensions spatiales
- Valider la mise à l'échelle: Test avec différentes échelles de modèles (
n
,s
,m
)
FAQ
Comment modifier le nombre de classes dans mon modèle ?
Régler le nc
au début de votre fichier YAML pour qu'il corresponde au nombre de classes de votre jeu de données.
nc: 5 # 5 classes
Puis-je utiliser une épine dorsale personnalisée dans mon modèle YAML ?
Oui, vous pouvez utiliser n'importe quel module supporté, y compris les backbones TorchVision, ou définir votre propre module personnalisé et l'importer comme décrit dans Intégration des modules personnalisés.
Comment puis-je adapter mon modèle à différentes tailles (nano, petit, moyen, etc.) ?
Utilisez la scales
section dans votre fichier YAML afin de définir les facteurs d'échelle pour les canaux de profondeur, de largeur et de maximum. Le modèle les appliquera automatiquement lorsque vous chargerez le fichier YAML de base avec l'échelle ajoutée au nom du fichier (par ex, yolo11n.yaml
).
Qu'est-ce que la [from, repeats, module, args]
signifie ?
Ce format précise comment chaque couche est construite :
from
Source(s) d'entrée : source(s) d'entréerepeats
Nombre de répétitions : nombre de répétitions du modulemodule
: le type de coucheargs
: arguments pour le module
Comment résoudre les erreurs de non-concordance des canaux ?
Vérifiez que les canaux de sortie d'une couche correspondent aux canaux d'entrée prévus pour la couche suivante. Utiliser print(model.model.model)
pour inspecter l'architecture de votre modèle.
Où puis-je trouver une liste des modules disponibles et de leurs arguments ?
Vérifier le code source dans le ultralytics/nn/modules
répertoire pour tous les modules disponibles et leurs arguments.
Comment ajouter un module personnalisé à ma configuration YAML ?
Définissez votre module dans le code source, importez-le comme indiqué dans Modification du code source, et faites-y référence par son nom dans votre fichier YAML.
Puis-je utiliser des poids pré-entraînés avec un YAML personnalisé ?
Oui, vous pouvez utiliser model.load("path/to/weights")
pour charger les poids à partir d'un point de contrôle pré-entraîné. Cependant, seuls les poids des couches qui correspondent seront chargés avec succès.
Comment valider la configuration de mon modèle ?
Utilisez model.info()
pour vérifier si le nombre de FLOPs est différent de zéro. Un modèle valide doit afficher un nombre de FLOPs non nul. Si c'est le cas, suivez les suggestions de la section Conseils de débogage pour trouver le problème.