Guía de configuración YAML del modelo#
El archivo de configuración YAML del modelo sirve como plano arquitectónico de 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 para los distintos tamaños de modelo.
Estructura de la configuración#
Los archivos YAML del modelo se organizan en tres secciones principales que, en conjunto, definen 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, la anchura y el número máximo de canales del modelo para generar variantes de distintos tamaños (desde nano hasta 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 te permite generar varios tamaños de modelo a partir de un único YAML base. Por ejemplo, al cargar yolo26n.yaml, Ultralytics lee el archivo base yolo26.yaml 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 valor distinto para nc o kpt_shape, Ultralytics sobrescribirá automáticamente la configuración del modelo en tiempo de ejecución para que coincida con el YAML del conjunto de datos.
Arquitectura del backbone y del head#
La arquitectura del modelo consta de las secciones backbone (extracción de características) y 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 entre el backbone y el head, y los mapas de características concatenados deben tener las mismas dimensiones espaciales.
Formato de especificación de capas#
Todas las capas siguen el mismo patrón: [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 (una), 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 permite crear patrones flexibles de flujo de datos en toda la red:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layerLas capas se indexan empezando por 0. Los índices negativos hacen referencia a 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 permite crear secciones más profundas de la red:
- [-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 del modelo.
Módulos disponibles#
Los módulos se organizan por funcionalidad y se definen en el directorio de módulos de Ultralytics. Las siguientes tablas muestran los módulos más utilizados por categoría; hay muchos más disponibles en el código fuente:
Operaciones básicas#
| Módulo | Finalidad | Fuente | 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 | Fuente | 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 | Fuente | Argumentos |
|---|---|---|---|
TorchVision | Cargar cualquier modelo de torchvision | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index | Extraer un tensor concreto de una lista | conv.py | [out_ch, index] |
Detect | Head de detección 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 fácilmente cualquier modelo de TorchVision como backbone:
from ultralytics import YOLO
# Modelo con backbone ConvNeXt
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 seleccionar características#
Al utilizar modelos que generan varios mapas de características, el módulo Index selecciona salidas concretas:
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 localiza e importa Ultralytics los módulos es fundamental para personalizarlos:
Proceso de búsqueda de módulos#
Ultralytics utiliza un sistema de tres niveles en parse_model:
# Lógica de resolución principal
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]
) # obtener módulo- 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: el resto de 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,
# ... muchos más módulos
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 mediante 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( { # Módulos existentes... 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 funciona la pasada hacia delante:
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # debería mostrar un valor de FLOPs distinto de cero si funciona
Ejemplos de configuración#
Modelo básico de detección#
# 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]]
head:
- [-1, 1, Classify, [nc]]Classify ya realiza internamente el pooling promedio adaptativo.
Buenas prácticas#
Consejos para diseñar arquitecturas#
Empieza con algo sencillo: comienza con arquitecturas probadas antes de personalizarlas. Usa configuraciones de YOLO existentes como plantillas y modifícalas de forma incremental en lugar de crear una desde cero.
Prueba de forma incremental: 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.
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 de la secuencia.
Usa conexiones de salto: aprovecha la reutilización de características con patrones [[-1, N], 1, Concat, [1]]. Estas conexiones facilitan el flujo del gradiente y permiten al modelo combinar características de distintas escalas.
Elige la escala adecuada: selecciona las escalas del modelo en función de tus limitaciones computacionales. Usa nano (n) para dispositivos periféricos, small (s) para un rendimiento equilibrado y escalas mayores (m, l, x) para obtener la máxima precisión.
Consideraciones sobre el rendimiento#
Profundidad frente a anchura: las redes profundas capturan características jerárquicas complejas mediante varias capas de transformación, mientras que las redes anchas procesan más información en paralelo en cada capa. Busca un equilibrio según la complejidad de tu tarea.
Conexiones de salto: mejoran el flujo del gradiente durante el entrenamiento y permiten reutilizar características en toda la red. Son especialmente importantes en arquitecturas más profundas para evitar que los gradientes se desvanezcan.
Bloques de cuello de botella: reducen el coste computacional sin perder 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 piramidal de características (FPN) con varios cabezales de detección a distintas 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 |
| Dimensiones de los canales incompatibles | Especificación de args incorrecta | Comprueba 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 conocer los tipos de argumento correctos |
| No se puede crear el modelo | Referencia de from no válida | Asegúrate de que existan las capas referenciadas |
Consejos para depurar#
Al desarrollar arquitecturas personalizadas, una depuración sistemática ayuda a detectar los problemas cuanto antes:
Usa un cabezal de identidad para las pruebas
Sustituye los cabezales complejos 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 recuento de FLOPs y mostrar cada capa también puede ayudar a depurar problemas de la configuración personalizada del modelo. Un modelo válido debe tener un recuento de FLOPs distinto de cero. Si es cero, probablemente haya un problema en la pasada hacia delante. Una pasada hacia delante sencilla debería mostrar el error exacto que se produce.
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 elementos de forma incremental: aumenta la complejidad capa a capa
- Comprueba las dimensiones: verifica la compatibilidad de los canales y los tamaños espaciales
- Valida el escalado: prueba con distintas escalas del modelo (
n,s,m)
Preguntas frecuentes#
Configura el parámetro
ncal principio del 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 profundidad, anchura y canales máximos. El modelo los aplicará automáticamente cuando cargues el archivo YAML base con la escala añadida al nombre del archivo (p. ej.,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 por la siguiente. Usa
print(model.model.model)para inspeccionar la arquitectura de tu modelo.Consulta el código fuente del directorio
ultralytics/nn/modulespara ver todos los módulos disponibles y sus argumentos.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.
Sí, puedes usar
model.load("path/to/weights")para cargar pesos desde un punto de control preentrenado. Sin embargo, solo se cargarán correctamente los pesos de las capas que coincidan.Usa
model.info()para comprobar que el recuento de FLOPs sea distinto de cero. Un modelo válido debe mostrar un recuento de FLOPs distinto de cero. Si es cero, sigue las sugerencias de Consejos para depurar para encontrar el problema.