Guía de configuración de modelos YAML
El archivo de configuración YAML del modelo sirve como el plano arquitectónico para las redes neuronales de Ultralytics. Define cómo se conectan las capas, qué parámetros utiliza cada módulo y cómo se escala toda la red a través de diferentes tamaños de modelo.
Estructura de configuración
Los archivos YAML de modelo están organizados en tres secciones principales que funcionan juntas para definir la arquitectura.
Sección de parámetros
La sección parameters especifica las características globales y el comportamiento de escalado del modelo:
# 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 onlyncestablece el número de clases que predice el modelo.scalesdefine factores de escalado compuestos que ajustan la profundidad, anchura y canales máximos del modelo para producir variantes de diferentes tamaños (desde nano hasta extra-large).kpt_shapese aplica a modelos de pose. Puede ser[N, 2]para keypoints(x, y)o[N, 3]para(x, y, visibility).
El parámetro scales te permite generar múltiples tamaños de modelo a partir de un único YAML base. Por ejemplo, cuando cargas yolo26n.yaml, Ultralytics lee el yolo26.yaml base y aplica los factores de escalado n (depth=0.50, width=0.25) para construir la variante nano.
Si tu dataset especifica un nc o kpt_shape diferente, Ultralytics sobrescribirá automáticamente la configuración del modelo en tiempo de ejecución para que coincida con el YAML del dataset.
Arquitectura de Backbone y Head
La arquitectura del modelo consiste en secciones de backbone (extracción de características) y head (específica para la tarea):
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 layerFormato de especificación de capas
Cada capa sigue el patrón constante: [from, repeats, module, args]
| Componente | Propósito | Ejemplos |
|---|---|---|
| from | Conexiones de entrada | -1 (anterior), 6 (capa 6), [4, 6, 8] (entrada múltiple) |
| repeats | Número de repeticiones | 1 (simple), 3 (repetir 3 veces) |
| module | Tipo de módulo | Conv, C2f, TorchVision, Detect |
| args | Argumentos del módulo | [64, 3, 2] (canales, kernel, stride) |
Patrones de conexión
El campo from crea patrones de flujo de datos flexibles a través de tu red:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layerLas capas se indexan empezando desde 0. Los índices negativos hacen referencia a capas anteriores (-1 = capa anterior), mientras que los índices positivos hacen referencia a capas específicas por su posición.
Repetición de módulos
El parámetro repeats crea secciones de red más profundas:
- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layerEl recuento real de repeticiones se multiplica por el factor de escalado de profundidad de la configuración del tamaño de tu modelo.
Módulos disponibles
Los módulos están organizados por funcionalidad y definidos en el directorio de módulos de Ultralytics. Las siguientes tablas muestran los módulos más utilizados por categoría, con muchos más disponibles en el código fuente:
Operaciones básicas
| Módulo | Propósito | Fuente | Argumentos |
|---|---|---|---|
Conv | Convolución + BatchNorm + Activación | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample | Upsampling espacial | PyTorch | [size, scale_factor, mode] |
nn.Identity | Operación de paso | PyTorch | [] |
Bloques compuestos
| Módulo | Propósito | Fuente | Argumentos |
|---|---|---|---|
C2f | Bottleneck CSP con 2 convoluciones | block.py | [out_ch, shortcut, expansion] |
SPPF | Spatial Pyramid Pooling (rápido) | block.py | [out_ch, kernel_size] |
Concat | Concatenación por canales | conv.py | [dimension] |
Módulos especializados
| Módulo | Propósito | Fuente | Argumentos |
|---|---|---|---|
TorchVision | Cargar cualquier modelo de torchvision | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index | Extraer tensor específico de la lista | block.py | [out_ch, index] |
Detect | Head de detección YOLO | head.py | [nc, anchors, ch] |
Esto representa un subconjunto de los módulos disponibles. Para obtener la lista completa de módulos y sus parámetros, explora el directorio de módulos.
Características avanzadas
Integración con TorchVision
El módulo TorchVision permite la integración fluida de cualquier modelo TorchVision como backbone:
from ultralytics import YOLO
# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="coco8.yaml", epochs=100)Establece el último parámetro en True para obtener mapas de características intermedios para detección multiescala.
Módulo Index para selección de características
Al usar modelos que generan múltiples mapas de características, el módulo Index selecciona salidas específicas:
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 detectionSistema de resolución de módulos
Entender cómo Ultralytics localiza e importa módulos es crucial para la personalización:
Proceso de búsqueda de módulos
Ultralytics utiliza un sistema de tres niveles 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]- Módulos PyTorch: Nombres que empiezan con
'nn.'→ namespacetorch.nn - Operaciones TorchVision: Nombres que empiezan con
'ops.'→ namespacetorchvision.ops - Módulos de Ultralytics: Todos los demás nombres → espacio de nombres global mediante importaciones
Cadena de importación de módulos
Los módulos estándar están disponibles a través de importaciones en tasks.py:
from ultralytics.nn.modules import ( # noqa: F401
SPPF,
C2f,
Conv,
Detect,
# ... many more modules
Index,
TorchVision,
)Integración de módulos personalizados
Modificación del código fuente
Modificar el código fuente es la forma más versátil de integrar tus módulos personalizados, pero puede resultar complicado. Para definir y utilizar un módulo personalizado, sigue estos pasos:
-
Instala Ultralytics en modo de desarrollo utilizando el método de clonación de Git de la guía de inicio rápido.
-
Define tu módulo en
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) -
Expón tu módulo a nivel de paquete en
ultralytics/nn/modules/__init__.py:from .block import CustomBlock # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock -
Añádelo a las importaciones en
ultralytics/nn/tasks.py:from ultralytics.nn.modules import CustomBlock # noqa -
Gestiona los argumentos especiales (si es necesario) dentro de
parse_model()enultralytics/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:]] -
Utiliza el módulo en el YAML de tu modelo:
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]] -
Comprueba los FLOPs para asegurarte de que el paso hacia adelante (forward pass) funciona:
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # should print non-zero FLOPs if working
Ejemplos de configuración
Modelo de detección básico
# 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]] # 7Modelo de backbone de 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 detectionModelo de clasificación
# 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]]Mejores prácticas
Consejos de diseño de arquitectura
Empieza de forma sencilla: Comienza con arquitecturas probadas antes de personalizar. Utiliza configuraciones de YOLO existentes como plantillas y modifícalas de forma incremental en lugar de construir desde cero.
Prueba de forma incremental: Valida cada modificación paso a paso. Añade un módulo personalizado cada vez y verifica que funciona antes de proceder con el siguiente cambio.
Controla los canales: Asegúrate de que las dimensiones de los canales coincidan entre las capas conectadas. Los canales de salida (c2) de una capa deben coincidir con los canales de entrada (c1) de la siguiente capa en la secuencia.
Utiliza conexiones de salto (skip connections): Aprovecha la reutilización de características con patrones [[-1, N], 1, Concat, [1]]. Estas conexiones ayudan al flujo de gradiente y permiten al modelo combinar características de diferentes escalas.
Escala adecuadamente: Elige las escalas del modelo según tus restricciones computacionales. Usa nano (n) para dispositivos de borde (edge devices), small (s) para un rendimiento equilibrado y escalas más grandes (m, l, x) para una precisión máxima.
Consideraciones sobre el rendimiento
Profundidad frente a anchura: Las redes profundas capturan características jerárquicas complejas a través de múltiples capas de transformación, mientras que las redes anchas procesan más información en paralelo en cada capa. Equilíbralas según la complejidad de tu tarea.
Conexiones de salto: Mejoran el flujo de gradiente durante el entrenamiento y permiten la reutilización de características a lo largo de la red. Son especialmente importantes en arquitecturas más profundas para evitar la desaparición de gradientes.
Bloques de cuello de botella (bottleneck blocks): Reducen el coste computacional manteniendo la capacidad de expresión del modelo. Módulos como C2f utilizan menos parámetros que las convoluciones estándar mientras preservan la capacidad de aprendizaje de características.
Características multiescala: Esenciales para detectar objetos de diferentes tamaños en la misma imagen. Utiliza patrones de Feature Pyramid Network (FPN) con múltiples cabezales de detección a diferentes escalas.
Solución de problemas
Problemas comunes
| Problema | Causa | Solución |
|---|---|---|
KeyError: 'ModuleName' | Módulo no importado | Añadir a las importaciones de tasks.py |
| Desajuste en la dimensión del canal | Especificación de args incorrecta | Verificar compatibilidad de canales de entrada/salida |
AttributeError: 'int' object has no attribute | Tipo de argumento incorrecto | Comprobar la documentación del módulo para conocer los tipos de argumentos correctos |
| El modelo no se construye | Referencia from no válida | Asegurarse de que las capas referenciadas existan |
Consejos de depuración
Al desarrollar arquitecturas personalizadas, la depuración sistemática ayuda a identificar problemas pronto:
Utiliza un cabezal de identidad para probar
Reemplaza los cabezales complejos con nn.Identity para aislar los problemas del backbone:
nc: 1
backbone:
- [-1, 1, CustomBlock, [64]]
head:
- [-1, 1, nn.Identity, []] # Pass-through for debuggingEsto permite la inspección directa de las salidas del backbone:
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 dimensionsInspección de la arquitectura del modelo
Comprobar el recuento de FLOPs e imprimir cada capa también puede ayudar a depurar problemas con la configuración de tu modelo personalizado. El recuento de FLOPs no debería ser cero para un modelo válido. Si es cero, es probable que haya un problema con el paso hacia adelante. Ejecutar un paso hacia adelante simple debería mostrar el error exacto que se está encontrando.
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}")Validación paso a paso
- Empieza de forma mínima: Prueba primero con la arquitectura más simple posible
- Añade gradualmente: Construye la complejidad capa a capa
- Comprueba las dimensiones: Verifica la compatibilidad del canal y del tamaño espacial
- Valida el escalado: Prueba con diferentes escalas de modelo (
n,s,m)
Preguntas frecuentes
¿Cómo cambio el número de clases en mi modelo?
Establece el parámetro nc en la parte superior de tu archivo YAML para que coincida con el número de clases de tu conjunto de datos.
nc: 5 # 5 classes¿Puedo utilizar un backbone personalizado en el YAML de mi modelo?
Sí. Puedes utilizar cualquier módulo compatible, incluidos los backbones de TorchVision, o definir tu propio módulo personalizado e importarlo como se describe en Integración de módulos personalizados.
¿Cómo escalo mi modelo para diferentes tamaños (nano, small, medium, etc.)?
Utiliza la sección scales (escalas) en tu YAML para definir los factores de escalado para la profundidad, la anchura y los canales máximos. El modelo los aplicará automáticamente cuando cargues el archivo YAML base con la escala añadida al nombre del archivo (ej. yolo26n.yaml).
¿Qué significa el formato [from, repeats, module, args]?
Este formato especifica cómo se construye cada capa:
from: fuente(s) de entradarepeats: número de veces que se repite el módulomodule: el tipo de capaargs: argumentos para el módulo
¿Cómo soluciono los errores de desajuste de canales?
Comprueba que los canales de salida de una capa coincidan con los canales de entrada esperados de la siguiente. Utiliza print(model.model.model) para inspeccionar la arquitectura de tu modelo.
¿Dónde puedo encontrar una lista de los módulos disponibles y sus argumentos?
Consulta el código fuente en el directorio ultralytics/nn/modules para ver todos los módulos disponibles y sus argumentos.
¿Cómo añado un módulo personalizado a mi configuración YAML?
Define tu módulo en el código fuente, impórtalo como se muestra en Modificación del código fuente y haz referencia a él por su nombre en tu archivo YAML.
¿Puedo utilizar pesos preentrenados con un YAML personalizado?
Sí, puedes usar model.load("path/to/weights") para cargar pesos de un checkpoint preentrenado. Sin embargo, solo se cargarán correctamente los pesos de las capas que coincidan.
¿Cómo valido la configuración de mi modelo?
Usa model.info() para comprobar si el recuento de FLOPs no es cero. Un modelo válido debería mostrar un recuento de FLOPs distinto de cero. Si es cero, sigue las sugerencias en Consejos de depuración para encontrar el problema.