YOLO Vision 2026:

Cómo realizar un ajuste fino de YOLO en un conjunto de datos personalizado#

La puesta a punto adapta un modelo preentrenado para reconocer nuevas clases partiendo de pesos ya aprendidos en lugar de una inicialización aleatoria. En lugar de entrenar desde cero durante cientos de épocas, la puesta a punto aprovecha las características preentrenadas de COCO y converge en datos personalizados en una fracción del tiempo.

Esta guía cubre la puesta a punto de YOLO26 en conjuntos de datos personalizados, desde el uso básico hasta técnicas avanzadas como el congelamiento de capas y el entrenamiento en dos fases.

Ajuste fino frente al entrenamiento desde cero#

Un modelo preentrenado ya ha aprendido características visuales generales —detección de bordes, reconocimiento de texturas, comprensión de formas— a partir de millones de imágenes. El aprendizaje por transferencia mediante la puesta a punto reutiliza ese conocimiento y solo le enseña al modelo cómo son las nuevas clases, razón por la cual converge más rápido y requiere menos datos. Entrenar desde cero descarta todo eso y obliga al modelo a aprenderlo todo desde los patrones a nivel de píxel, lo que demanda muchos más recursos.

Ajuste finoEntrenamiento desde cero
Pesos inicialesPreentrenado en COCO (80 clases)Inicialización aleatoria
ComandoYOLO("yolo26n.pt")YOLO("yolo26n.yaml")
ConvergenciaMás rápida: el backbone ya está entrenadoMás lenta: todas las capas aprenden desde cero
Requisitos de datosMenores: las características preentrenadas compensan la falta de datosMayores: el modelo debe aprender todas las características solo del conjunto de datos
Cuándo usarloClases personalizadas con imágenes naturalesDominios fundamentalmente diferentes de COCO (médico, satelital, radar)
El ajuste fino no requiere código adicional

Cuando se carga un archivo .pt con YOLO("yolo26n.pt"), los pesos preentrenados quedan almacenados en el modelo. Llamar a .train(data="custom.yaml") después de eso transfiere automáticamente todos los pesos compatibles a la nueva arquitectura del modelo, reinicializa cualquier capa que no coincida (como la cabeza de detección cuando el número de clases difiere) y comienza el entrenamiento. No se requiere cargar pesos manualmente, manipular capas ni escribir código de aprendizaje por transferencia personalizado.

Cómo funciona la transferencia de pesos preentrenados#

Cuando se realiza un ajuste fino de un modelo preentrenado en un conjunto de datos con un número diferente de clases (por ejemplo, de las 80 clases de COCO a 5 clases personalizadas), Ultralytics realiza una transferencia de pesos consciente de la forma:

  1. El backbone y el cuello se transfieren completamente: estas capas extraen características visuales generales y sus formas son independientes del número de clases.
  2. La cabeza de detección se reinicializa parcialmente —las capas de salida de clasificación (cv3, one2one_cv3) tienen formas vinculadas al recuento de clases (80 frente a 5), por lo que no se pueden transferir y se inicializan de forma aleatoria. Las capas de regresión de cajas (cv2, one2one_cv2) en la cabeza tienen formas fijas independientemente del recuento de clases, por lo que se transfieren con normalidad.
  3. La gran mayoría de los pesos se transfieren al cambiar el recuento de clases. Por ejemplo, al realizar un ajuste fino de YOLO26n de COCO (80 clases) a un conjunto de datos de 5 clases, se transfieren 606 de 708 tensores de pesos: solo se reinicializan las capas de clasificación dependientes del número de clases, mientras que el backbone, el cuello y las ramas de regresión de cajas permanecen intactos.

Para conjuntos de datos con el mismo número de clases que el modelo preentrenado (por ejemplo, al realizar un ajuste fino de pesos preentrenados en COCO en otro conjunto de datos de 80 clases), el 100% de los pesos se transfieren, incluida la cabeza de detección.

Transfiere clases con alias de nombres#

Ultralytics transfiere las filas de las cabezas de clasificación coincidentes por nombre de clase entre conjuntos de datos, ignorando mayúsculas, minúsculas y espacios en blanco circundantes. Cuando clases equivalentes usen nombres diferentes, cambia el nombre de las clases del punto de control de origen en la memoria antes de cargarlo. Esto preserva los pesos de clasificación preentrenados para conceptos compartidos que de otro modo se tratarían como no coincidentes y se inicializarían de forma aleatoria.

Este ejemplo de Objects365 v2 a COCO cambia el nombre de las clases de origen en el punto de control cargado, que train() pasa posteriormente como los pesos preentrenados:

from ultralytics import YOLO

# Source Objects365 v2 name -> target COCO name
ALIASES = {
    "wild bird": "bird",
    "handbag/satchel": "handbag",
    "luggage": "suitcase",
    "bowl/basin": "bowl",
    "orange/tangerine": "orange",
    "monitor/tv": "tv",
    "stuffed toy": "teddy bear",
    "hair dryer": "hair drier",
}

model = YOLO("path/to/yolo26s-objects365.pt")
model.model.names = {i: ALIASES.get(name, name) for i, name in model.model.names.items()}
model.train(data="coco.yaml", epochs=100, imgsz=640)

Ejemplo básico de ajuste fino#

Ejemplo
from ultralytics import YOLO

model = YOLO("yolo26n.pt")  # load pretrained model
model.train(data="custom.yaml", epochs=50, imgsz=640)

Elección del tamaño del modelo#

Los modelos más grandes tienen mayor capacidad pero también más parámetros que actualizar, lo que puede aumentar el riesgo de sobreajuste cuando los datos de entrenamiento son limitados. Empezar con un modelo más pequeño (YOLO26n o YOLO26s) y escalar solo si las métricas de validación se estancan es un enfoque práctico. El tamaño óptimo del modelo depende de la complejidad de la tarea, el número de clases, la diversidad del conjunto de datos y el hardware disponible para el despliegue. Consulta la página del modelo YOLO26 completa para conocer los tamaños disponibles y las pruebas de rendimiento.

Selección del optimizador y la tasa de aprendizaje#

La configuración predeterminada de optimizer=auto selecciona el optimizador y la tasa de aprendizaje en función del número total de iteraciones de entrenamiento:

  • < 10,000 iteraciones (conjuntos de datos pequeños o pocas épocas): AdamW con una tasa de aprendizaje baja calculada automáticamente
  • > 10 000 iteraciones (conjuntos de datos grandes): MuSGD (un optimizador híbrido Muon+SGD) con lr=0.01

Para la mayoría de las tareas de ajuste fino, la configuración predeterminada funciona bien sin necesidad de ajustes manuales. Considera configurar el optimizador explícitamente cuando:

  • El entrenamiento es inestable (los picos de pérdida suben o divergen): prueba optimizer=AdamW, lr0=0.001 para lograr una convergencia más estable
  • Puesta a punto de un modelo grande en un conjunto de datos pequeño: una tasa de aprendizaje más baja como lr0=0.001 ayuda a preservar las características preentrenadas
El optimizador automático anula el lr0 manual

Cuando optimizer=auto, los valores de lr0 y momentum se ignoran. Para controlar la tasa de aprendizaje manualmente, establece el optimizador de forma explícita: optimizer=SGD, lr0=0.005.

Congelado de capas#

El congelamiento evita que capas específicas se actualicen durante el entrenamiento. Esto acelera el entrenamiento y reduce el sobreajuste cuando el conjunto de datos es pequeño en relación con la capacidad del modelo.

El parámetro freeze acepta un número entero o una lista. Un número entero freeze=10 congela las primeras 10 capas (índices 0-9), lo que abarca la mayor parte del espinazo (backbone) de YOLO26. El espinazo abarca las capas 0-10, por lo que freeze=10 deja el bloque C2PSA final (capa 10) entrenable; usa freeze=11 para congelar todo el espinazo. Una lista puede contener índices de capa como freeze=[0, 3, 5] para un congelamiento parcial del espinazo, o cadenas de nombres de módulos como freeze=["23.cv2", "23.one2one_cv2"] para un control detallado sobre ramas específicas dentro de una capa (aquí, ambas ramas de regresión de cajas de la cabeza de detección).

Ejemplo
model.train(data="custom.yaml", epochs=50, freeze=10)

La profundidad de congelado adecuada depende de qué tan similar sea el dominio objetivo a los datos preentrenados y de cuántos datos de entrenamiento haya disponibles:

EscenarioRecomendaciónJustificación
Conjunto de datos grande, dominio similarfreeze=None (por defecto)Suficientes datos para adaptar todas las capas sin sobreajuste
Conjunto de datos pequeño, dominio similarfreeze=10Preserva las características del backbone, reduce los parámetros entrenables
Conjunto de datos muy pequeñofreeze=23Solo se entrena la cabeza de detección, minimizando el riesgo de sobreajuste
Dominio lejano a COCOfreeze=NoneEs posible que las características del backbone no se transfieran bien y necesiten un reentrenamiento

La profundidad de congelado también puede tratarse como un hiperparámetro: probar algunos valores (0, 5, 10) y comparar el mAP de validación es una forma práctica de encontrar la mejor configuración para un conjunto de datos específico.

Hiperparámetros clave para el ajuste fino#

El ajuste fino generalmente requiere menos ajustes de hiperparámetros que el entrenamiento desde cero. Los parámetros que más importan son:

  • epochs: La puesta a punto converge más rápido que entrenar desde cero. Empieza con un valor moderado y utiliza patience para detenerte antes cuando las métricas de validación se estanquen.
  • patience: El valor predeterminado de 100 está diseñado para ejecuciones de entrenamiento largas. Reducir esto a 10-20 evita perder tiempo en ejecuciones que ya han convergido.
  • warmup_epochs: El calentamiento predeterminado (3 épocas) aumenta gradualmente la tasa de aprendizaje desde cero, lo que evita que las grandes actualizaciones de gradientes dañen las características preentrenadas en las primeras iteraciones. Se recomienda mantener el valor predeterminado incluso para la puesta a punto.

Para ver la lista completa de parámetros de entrenamiento, consulta la referencia de configuración de entrenamiento.

Ajuste fino en dos etapas#

El ajuste fino en dos etapas divide el entrenamiento en dos fases. La primera etapa congela el backbone y entrena solo el cuello y la cabeza, lo que permite que las capas de detección se adapten a las nuevas clases sin alterar las características preentrenadas. La segunda etapa descongela todas las capas y entrena el modelo completo con una tasa de aprendizaje más baja para refinar el backbone para el dominio objetivo.

Este enfoque es especialmente útil cuando el dominio de destino difiere significativamente de COCO (imágenes médicas, imágenes aéreas, microscopía), donde puede ser necesario adaptar el espinazo pero entrenar todo a la vez causa inestabilidad. Para un desacoplamiento automático con un enfoque basado en devoluciones de llamada (callbacks), consulta Congelar y descongelar el espinazo.

Ajuste fino en dos etapas
from ultralytics import YOLO

# Stage 1: freeze backbone, train head and neck
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=20, freeze=10, name="stage1", exist_ok=True)

# Stage 2: unfreeze all, fine-tune with lower lr
model = YOLO("runs/detect/stage1/weights/best.pt")
model.train(data="custom.yaml", epochs=30, lr0=0.001, name="stage2", exist_ok=True)

Errores comunes#

El modelo no produce predicciones#

  • Datos de entrenamiento insuficientes: entrenar con muy pocas muestras es la causa más común: el modelo no puede aprender ni generalizar a partir de muy pocos datos. Asegúrate de tener suficientes ejemplos diversos por clase antes de investigar otras causas.
  • Comprueba las rutas del conjunto de datos: las rutas incorrectas en data.yaml generan silenciosamente cero etiquetas. Ejecuta yolo detect val model=yolo26n.pt data=custom.yaml antes de entrenar para confirmar que las etiquetas se cargan correctamente.
  • Umbral de confianza más bajo: si existen predicciones pero se filtran, prueba conf=0.1 durante la inferencia.
  • Verifica el recuento de clases: asegúrate de que nc en data.yaml coincida con el número real de clases en los archivos de etiquetas.

El mAP de validación se estanca pronto#

  • Añadir más datos: el ajuste fino se beneficia significativamente de datos de entrenamiento adicionales, especialmente ejemplos diversos con ángulos, iluminación y fondos variados.
  • Comprueba el equilibrio de clases: las clases infrarrepresentadas tendrán un AP bajo. Utiliza cls_pw para aplicar la ponderación de clases por frecuencia inversa (empieza con cls_pw=0.25 para desequilibrios moderados y aumenta a 1.0 para desequilibrios graves).
  • Reduce la aumentación: para conjuntos de datos muy pequeños, la aumentación intensa puede perjudicar más que ayudar. Prueba mosaic=0.5 o mosaic=0.0.
  • Aumenta la resolución: para conjuntos de datos con objetos pequeños, prueba imgsz=1280 para preservar los detalles.

El rendimiento se degrada en las clases originales después del ajuste fino#

Esto se conoce como olvido catastrófico: el modelo pierde conocimientos aprendidos previamente cuando se ajusta exclusivamente con nuevos datos. El olvido es prácticamente inevitable sin incluir imágenes del conjunto de datos original junto con los nuevos datos. Para mitigar esto:

  • Fusionar conjuntos de datos: incluye ejemplos de las clases originales junto con las nuevas clases durante el ajuste fino. Esta es la única forma fiable de evitar el olvido.
  • Congelar el backbone y el cuello: congelar tanto el backbone como el cuello para que solo se entrene la cabeza de detección ayuda en ejecuciones cortas de ajuste fino con una tasa de aprendizaje muy baja.
  • Entrenar durante menos épocas: cuanto más tiempo entrene el modelo exclusivamente con nuevos datos, más aumentará el olvido.

FAQ#

  • No existe un mínimo fijo: los resultados dependen de la complejidad de la tarea, el número de clases y qué tan similar sea el dominio a COCO. Imágenes más diversas (iluminación, ángulos, fondos variados) importan más que la cantidad bruta. Comienza con lo que tienes y escala si las métricas de validación no son suficientes.

  • Carga un archivo .pt preentrenado y llama a .train() con la ruta a un data.yaml personalizado. Ultralytics gestiona automáticamente la transferencia de pesos, la reinicialización de la cabeza de detección y la selección del optimizador. Consulta la sección Puesta a punto básica para ver el ejemplo de código completo.

  • Las causas más comunes son rutas incorrectas en data.yaml (lo que produce silenciosamente cero etiquetas), una discrepancia entre nc en el archivo YAML y los archivos de etiquetas reales, o un umbral de confianza demasiado alto. Consulta Errores comunes para ver una lista de comprobación de resolución de problemas completa.

  • Depende del tamaño del conjunto de datos y de la similitud del dominio. Para conjuntos de datos pequeños con un dominio similar a COCO, congelar el espinazo (freeze=10) evita el sobreajuste. Para dominios muy diferentes de COCO, dejar todas las capas sin congelar (freeze=None) permite que el espinazo se adapte. Consulta Congelar capas para obtener recomendaciones detalladas.

  • Incluye ejemplos de las clases originales en los datos de entrenamiento junto con las nuevas clases. Si eso no es posible, congelar más capas (freeze=10 o superior) y utilizar una tasa de aprendizaje más baja ayuda a preservar el conocimiento preentrenado. Consulta El rendimiento disminuye en las clases originales para obtener más detalles.

Comentarios