Guía de configuración del YAML del modelo#
El archivo de configuración YAML del modelo sirve como 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 escala toda la red en los distintos tamaños de modelo.
Estructura de la configuración#
Los archivos YAML del modelo se organizan en tres secciones principales que funcionan conjuntamente para definir la arquitectura.
Sección de parámetros#
La sección de parámetros 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 compuesto que ajustan la profundidad, la anchura y el número máximo de canales del modelo para producir variantes de distintos tamaños (de nano a extragrande).kpt_shapese aplica a los modelos de pose. Puede ser[N, 2]para(x, y)puntos clave o[N, 3]para(x, y, visibility).
El parámetro scales permite generar varios tamaños de modelo a partir de un único YAML base. Por ejemplo, al cargar yolo26n.yaml, Ultralytics lee el yolo26.yaml base y aplica los factores de escalado n (depth=0.50, width=0.25) para crear la variante nano.
Si tu conjunto de datos especifica un nc o kpt_shape diferente, Ultralytics sobrescribirá automáticamente la configuración del modelo durante la ejecución para que coincida con el YAML del conjunto de datos.
Arquitectura del backbone y de la head#
La arquitectura del modelo consta de las secciones del backbone (extracción de características) y de la head (específica de la tarea):
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 layerLos índices de las capas continúan a lo largo del backbone y de la head, y los mapas de características concatenados deben tener dimensiones espaciales coincidentes.
Formato de especificación de las capas#
Cada capa sigue el patrón uniforme: [from, repeats, module, args]
| Componente | Finalidad | Ejemplos |
|---|---|---|
| from | Conexiones de entrada | -1 (anterior), 6 (capa 6), [4, 6, 8] (entrada múltiple) |
| repeats | Número de repeticiones | 1 (única), 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 flexibles de flujo de datos en toda tu red:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layerLas capas se indexan empezando por 0. Los índices negativos hacen referencia a las capas anteriores (-1 = capa anterior), mientras que los índices positivos hacen referencia a capas concretas según 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 número 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 se organizan por funcionalidad y se definen en el directorio de módulos de Ultralytics. Las tablas siguientes muestran los módulos más utilizados por categoría, aunque hay muchos más disponibles en el código fuente:
Operaciones básicas#
| Módulo | Finalidad | Origen | Argumentos |
|---|---|---|---|
Conv | Convolución + BatchNorm + activación | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample | Aumento de resolución espacial | PyTorch | [size, scale_factor, mode] |
nn.Identity | Operación de paso directo | PyTorch | [] |
Bloques compuestos#
| Módulo | Finalidad | Origen | Argumentos |
|---|---|---|---|
C2f | Cuello de botella CSP con 2 convoluciones | block.py | [out_ch, shortcut, groups, 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 | Finalidad | Origen | Argumentos |
|---|---|---|---|
TorchVision | Cargar cualquier modelo de torchvision | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index | Extraer un tensor específico de una lista | conv.py | [out_ch, index] |
Detect | Head de detección de YOLO | head.py | [nc] |
Esto representa un subconjunto de los módulos disponibles. Para consultar la lista completa de módulos y sus parámetros, explora el directorio de módulos.
Funciones avanzadas#
Integración con TorchVision#
El módulo TorchVision permite integrar sin problemas cualquier modelo de TorchVision como backbone:
from ultralytics import YOLO
# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="imagenet10", epochs=100)Establece el último parámetro en True para obtener mapas de características intermedios para la detección multiescala.
Módulo Index para la selección de características#
Al utilizar modelos que generan varios mapas de características, el módulo Index selecciona salidas específicas:
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 detectionSistema de resolución de módulos#
Comprender cómo Ultralytics localiza e importa los módulos es fundamental 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 m.startswith("nn.")
else getattr(__import__("torchvision").ops, m[16:])
if m.startswith("torchvision.ops.")
else globals()[m]
) # get module- Módulos de PyTorch: los nombres que empiezan por
'nn.'→ espacio de nombrestorch.nn - Operaciones de TorchVision: los nombres que empiezan por
'torchvision.ops.'→ espacio de nombrestorchvision.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 mediante las importaciones de 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 en el nivel del 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 -
Añade el módulo a
base_modulesdentro deparse_model(). Los módulos de este conjunto reciben automáticamente los canales de entrada y salida:base_modules = frozenset( { # Existing modules... CustomBlock, } ) -
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 delante funciona:
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # should print non-zero FLOPs if working
Configuraciones de ejemplo#
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 con 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]]
head:
- [-1, 1, Classify, [nc]]Classify ya realiza internamente un average pooling adaptativo.
Buenas prácticas#
Consejos para diseñar arquitecturas#
Empieza por lo sencillo: Comienza con arquitecturas probadas antes de personalizarlas. Usa configuraciones de YOLO existentes como plantillas y modifícalas progresivamente en lugar de construirlas desde cero.
Prueba progresivamente: Valida cada modificación paso a paso. Añade un módulo personalizado cada vez y comprueba que funciona antes de pasar al siguiente cambio.
Supervisa 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 de la secuencia.
Usa conexiones de salto: Aprovecha la reutilización de características con patrones [[-1, N], 1, Concat, [1]]. Estas conexiones ayudan al flujo de gradientes y permiten que el modelo combine características de diferentes escalas.
Escala adecuadamente: Elige las escalas del modelo en función de tus limitaciones computacionales. Usa nano (n) para dispositivos periféricos, small (s) para obtener un rendimiento equilibrado y escalas mayores (m, l, x) para lograr la máxima precisión.
Consideraciones de rendimiento#
Profundidad frente a anchura: Las redes profundas capturan características jerárquicas complejas mediante múltiples capas de transformación, mientras que las redes anchas procesan más información en paralelo en cada capa. Equilibra estos aspectos en función de la complejidad de tu tarea.
Conexiones de salto: Mejoran el flujo de gradientes durante el entrenamiento y permiten reutilizar características en toda la red. Son especialmente importantes en arquitecturas más profundas para evitar la desaparición de gradientes.
Bloques cuello de botella: Reducen el coste computacional manteniendo la capacidad expresiva del modelo. Módulos como C2f usan menos parámetros que las convoluciones estándar y conservan la capacidad de aprendizaje de características.
Características multiescala: Son esenciales para detectar objetos de distintos tamaños en una misma imagen. Usa patrones de Red de pirámide de características (FPN) con varias cabezas de detección en diferentes escalas.
Solución de problemas#
Problemas habituales#
| Problema | Causa | Solución |
|---|---|---|
KeyError: 'ModuleName' | Módulo no importado | Añádelo a las importaciones de tasks.py |
| La dimensión de los canales no coincide | Especificación incorrecta de args | Verifica la compatibilidad de los canales de entrada y salida |
AttributeError: 'int' object has no attribute | Tipo de argumento incorrecto | Consulta la documentación del módulo para comprobar los tipos de argumento correctos |
| El modelo no se puede construir | Referencia no válida de from | Asegúrate de que las capas referenciadas existan |
Consejos para depurar#
Al desarrollar arquitecturas personalizadas, una depuración sistemática ayuda a identificar los problemas desde el principio:
Usa una cabeza de identidad para las pruebas
Sustituye las cabezas complejas por 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 inspeccionar directamente las salidas del backbone:
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 dimensionsInspección de la arquitectura del modelo
Comprobar el número de FLOPs y mostrar cada capa también puede ayudar a depurar problemas con la configuración de tu modelo personalizado. El número de FLOPs debe ser distinto de cero en un modelo válido. Si es cero, es probable que haya un problema con el paso hacia delante. Ejecutar un paso hacia delante sencillo debería mostrar el error exacto que se está produciendo.
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}")Validación paso a paso
- Empieza con lo mínimo: Prueba primero con la arquitectura más sencilla posible
- Añade progresivamente: Construye la complejidad capa a capa
- Comprueba las dimensiones: Verifica la compatibilidad de los canales y del tamaño espacial
- Valida el escalado: Prueba con diferentes escalas del modelo (
n,s,m)
Preguntas frecuentes#
Establece el parámetro
ncen la parte superior de tu archivo YAML para que coincida con el número de clases de tu conjunto de datos.nc: 5 # 5 classesSí. Puedes usar cualquier módulo compatible, incluidos los backbones de TorchVision, o definir tu propio módulo personalizado e importarlo tal como se describe en Integración de módulos personalizados.
Usa la sección
scalesde tu YAML para definir los factores de escalado de la profundidad, la anchura y el número máximo de canales. El modelo los aplicará automáticamente al cargar el archivo YAML base con la escala añadida al nombre del archivo (por ejemplo,yolo26n.yaml).Este formato especifica cómo se construye cada capa:
from: fuente(s) de entradarepeats: número de veces que se repite el módulomodule: tipo de capaargs: argumentos del módulo
Comprueba que los canales de salida de una capa coincidan con los canales de entrada esperados de la siguiente. Usa
print(model.model.model)para inspeccionar la arquitectura de tu modelo.Consulta el código fuente en el directorio
ultralytics/nn/modulespara ver todos los módulos disponibles y sus argumentos.Define el 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.
Sí, puedes usar
model.load("path/to/weights")para cargar pesos desde un checkpoint preentrenado. Sin embargo, solo se cargarán correctamente los pesos de las capas coincidentes.Usa
model.info()para comprobar que el número de FLOPs sea distinto de cero. Un modelo válido debería mostrar un número de FLOPs distinto de cero. Si es cero, sigue las sugerencias de Consejos para depurar para encontrar el problema.