Cómo ajustar YOLO con un conjunto de datos personalizado#
El ajuste fino adapta un modelo preentrenado para reconocer clases nuevas, partiendo de pesos aprendidos en lugar de una inicialización aleatoria. En vez de entrenar desde cero durante cientos de épocas, el ajuste fino aprovecha las características de COCO preentrenado y converge con datos personalizados en mucho menos tiempo.
Esta guía explica cómo ajustar YOLO26 con conjuntos de datos personalizados, desde el uso básico hasta técnicas avanzadas como la congelación de capas y el entrenamiento en dos etapas.
Ajuste fino frente a entrenamiento desde cero#
Un modelo preentrenado ya ha aprendido características visuales generales —detección de bordes, reconocimiento de texturas y comprensión de formas— a partir de millones de imágenes. El aprendizaje por transferencia mediante ajuste fino reutiliza esos conocimientos y solo enseña al modelo el aspecto de las clases nuevas, por lo que converge más rápido y requiere menos datos. El entrenamiento desde cero descarta todo ese aprendizaje y obliga al modelo a aprenderlo todo desde patrones a nivel de píxel, lo que exige muchos más recursos. Consulta la guía de configuración YAML del modelo para descubrir en qué se diferencian los archivos .yaml, que solo definen la arquitectura, de los puntos de control.
| Ajuste fino | Entrenamiento desde cero | |
|---|---|---|
| Pesos iniciales | Preentrenado con COCO (80 clases) | Inicialización aleatoria |
| Comando | YOLO("yolo26n.pt") | YOLO("yolo26n.yaml") |
| Convergencia | Más rápida: el backbone ya está entrenado | Más lenta: todas las capas aprenden desde cero |
| Requisitos de datos | Menores: las características preentrenadas compensan la falta de datos | Mayores: el modelo debe aprender todas las características únicamente a partir del conjunto de datos |
| Cuándo usarlo | Clases personalizadas con imágenes naturales | Dominios muy distintos de COCO (médico, satelital, radar) |
Cuando se carga un archivo .pt con YOLO("yolo26n.pt"), los pesos preentrenados se almacenan en el modelo. Al llamar a .train(data="custom.yaml") después, todos los pesos compatibles se transfieren automáticamente a la nueva arquitectura del modelo, se reinicializan las capas que no coinciden (como la capa de clasificación final cuando cambia el número de clases) y comienza el entrenamiento. No hace falta cargar los pesos manualmente, manipular capas ni escribir código personalizado de aprendizaje por transferencia.
Cómo funciona la transferencia de pesos preentrenados#
Cuando se ajusta un modelo preentrenado con un conjunto de datos que tiene un número de clases distinto (por ejemplo, las 80 clases de COCO frente a 5 clases personalizadas), Ultralytics realiza una transferencia de pesos teniendo en cuenta las dimensiones:
- El backbone y el neck se transfieren por completo: estas capas extraen características visuales generales y sus dimensiones son independientes del número de clases.
- La cabeza de detección se reinicializa parcialmente: solo la convolución final de cada rama de clasificación (
cv3,one2one_cv3) tiene una forma vinculada al número de clases (80 frente a 5); las capas ocultas de la rama se transfieren cuando ambos modelos comparten una escala. Las filas compatibles cuyos nombres de clase coinciden se reasignan antes de inicializar las filas sin correspondencia. Las capas de regresión de cajas (cv2,one2one_cv2) de la cabeza tienen formas fijas, independientemente del número de clases, por lo que se transfieren con normalidad. - Se transfiere la gran mayoría de los pesos al cambiar el número de clases. Por ejemplo, al ajustar YOLO26n de COCO (80 clases) a un conjunto de datos de 5 clases, se transfieren 696 de los 708 tensores de pesos, además de las filas de clasificación compatibles que coinciden por nombre.
En conjuntos de datos con el mismo número de clases que el modelo preentrenado (por ejemplo, al ajustar pesos preentrenados con COCO usando otro conjunto de datos de 80 clases), se transfiere el 100 % de los pesos, incluido el cabezal de detección.
Transferencia de clases con alias de nombre#
Ultralytics transfiere las filas coincidentes del cabezal de clasificación entre conjuntos de datos según el nombre de la clase, sin distinguir entre mayúsculas y minúsculas y omitiendo los espacios en blanco iniciales y finales. Si las clases equivalentes tienen nombres distintos, cambia en memoria los nombres de las clases del punto de control de origen antes de cargarlo. Así se conservan los pesos de clasificación preentrenados de los conceptos compartidos que, de otro modo, se considerarían clases no coincidentes y se inicializarían aleatoriamente.
Este ejemplo de Objects365 v2 a COCO cambia los nombres de las clases de origen en el punto de control cargado, que después train() utiliza como pesos preentrenados:
from ultralytics import YOLO
# Nombre de origen de Objects365 v2 (en minúsculas) -> nombre de destino de COCO
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")
# Los nombres de las clases de Objects365 usan mayúsculas iniciales; por eso, la coincidencia se busca con el nombre en minúsculas
model.model.names = {i: ALIASES.get(name.lower(), name) for i, name in model.model.names.items()}
model.train(data="coco.yaml", epochs=100, imgsz=640)El ajuste cls_remap activa esta transferencia basada en nombres de forma predeterminada. Durante el entrenamiento se muestra Remapped N/M cls head rows from pretrained weights by class name cuando se copian filas compatibles; establece cls_remap=False para desactivarla.
Ejemplo básico de ajuste fino#
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # cargar el modelo preentrenado
model.train(data="custom.yaml", epochs=50, imgsz=640)Elección del tamaño del modelo#
Los modelos más grandes tienen más capacidad, pero también más parámetros que actualizar, lo que puede aumentar el riesgo de sobreajuste cuando hay pocos datos de entrenamiento. Empezar con un modelo más pequeño (YOLO26n o YOLO26s) y ampliarlo solo si las métricas de validación se estancan es una opción práctica. 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 la implementación. Consulta la página completa del modelo YOLO26 para ver los tamaños disponibles y las métricas de rendimiento.
Selección del optimizador y la tasa de aprendizaje#
El ajuste predeterminado optimizer=auto selecciona el optimizador y la tasa de aprendizaje según el número total de iteraciones de entrenamiento:
- 10 000 iteraciones o menos (conjuntos de datos pequeños o pocas épocas): AdamW con una tasa de aprendizaje baja calculada automáticamente
- Más de 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, el ajuste predeterminado funciona bien sin necesidad de ajustes manuales. Plantéate especificar el optimizador explícitamente en estos casos:
- El entrenamiento es inestable (la pérdida aumenta bruscamente o diverge): prueba
optimizer=AdamW, lr0=0.001para lograr una convergencia más estable - Ajustas un modelo grande con un conjunto de datos pequeño: un optimizador explícito con una tasa de aprendizaje más baja, como
optimizer=AdamW, lr0=0.001, puede ayudar a conservar las características preentrenadas
Cuando se usa optimizer=auto, se ignora el valor lr0. Para controlar la tasa de aprendizaje manualmente, especifica el optimizador: optimizer=SGD, lr0=0.005.
Congelación de capas#
La congelación impide que determinadas capas 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 entero o una lista. El entero freeze=10 congela las 10 primeras capas (índices 0-9), que abarcan la mayor parte del backbone de YOLO26. El backbone comprende las capas 0-10, por lo que freeze=10 deja entrenable el bloque C2PSA final (capa 10); usa freeze=11 para congelar todo el backbone. Una lista puede incluir índices de capa, como freeze=[0, 3, 5], para congelar parcialmente el backbone, o cadenas con nombres de módulos, como freeze=["23.cv2", "23.one2one_cv2"], para controlar con precisión ramas específicas dentro de una capa (en este caso, ambas ramas de regresión de cajas del cabezal de detección).
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=50, freeze=10)La profundidad de congelación adecuada depende de cuánto se parezca el dominio objetivo a los datos de preentrenamiento y de cuántos datos de entrenamiento haya disponibles:
| Escenario | Recomendación | Justificación |
|---|---|---|
| Conjunto de datos grande, dominio similar | freeze=None (predeterminado) | Hay datos suficientes para adaptar todas las capas sin sobreajustar |
| Conjunto de datos pequeño, dominio similar | freeze=10 | Conserva las características del backbone y reduce los parámetros entrenables |
| Conjunto de datos muy pequeño | freeze=23 | Solo se entrena el cabezal de detección, lo que minimiza el riesgo de sobreajuste |
| Dominio muy distinto de COCO | freeze=None | Es posible que las características del backbone no se transfieran bien y haya que volver a entrenarlas |
La profundidad de congelación también se puede tratar como un hiperparámetro: probar varios valores (0, 5, 10) y comparar el mAP de validación es una forma práctica de encontrar la configuración óptima para un conjunto de datos concreto.
Hiperparámetros clave para el ajuste fino#
Por lo general, el ajuste fino requiere menos cambios en los hiperparámetros que el entrenamiento desde cero. Los parámetros más importantes son:
epochs: El ajuste fino converge más rápido que el entrenamiento desde cero. Empieza con un valor moderado y utilizapatiencepara detener el entrenamiento pronto cuando las métricas de validación se estanquen.patience: El valor predeterminado de 100 está pensado para entrenamientos largos. Reducirlo a 10-20 evita perder tiempo en ejecuciones que ya han convergido.warmup_epochs: El calentamiento ajusta gradualmente la tasa de aprendizaje hasta el valor programado durante las primeras épocas, lo que reduce la probabilidad de que los primeros lotes alteren las características preentrenadas. Mantenlo distinto de cero durante el ajuste fino, pero no hace falta usar el valor predeterminado completo de 3 épocas: la búsqueda evolutiva utilizada en el ajuste fino oficial de YOLO26 con COCO —una continuación de varias épocas a partir de los pesos de Objects365— se decantó por aproximadamente una época para cada tamaño de modelo.
Para ver la lista completa de parámetros de entrenamiento, consulta la referencia de configuración del entrenamiento. Si necesitas un comportamiento que los parámetros no ofrecen —tasas de aprendizaje por capa, recorte del gradiente o métricas de validación personalizadas—, crea una subclase del entrenador.
Ajuste fino en dos etapas#
El ajuste fino en dos etapas divide el entrenamiento en dos fases. En la primera, se congela el backbone y solo se entrenan el cuello y el cabezal, lo que permite que las capas de detección se adapten a las nuevas clases sin alterar las características preentrenadas. En la segunda, se descongelan todas las capas y se entrena el modelo completo con una tasa de aprendizaje menor para refinar el backbone para el dominio objetivo.
Este enfoque resulta especialmente útil cuando el dominio objetivo difiere mucho de COCO (imágenes médicas, imágenes aéreas o microscopía), ya que quizá haya que adaptar el backbone, pero entrenarlo todo a la vez puede causar inestabilidad. Para descongelar capas automáticamente mediante una estrategia basada en callbacks, consulta Congelar y descongelar el backbone.
from ultralytics import YOLO
# Etapa 1: congelar el backbone y entrenar el cabezal y el cuello
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=20, freeze=10, name="stage1", exist_ok=True)
# Etapa 2: descongelar todo y ajustar con una tasa de aprendizaje menor
model = YOLO("runs/detect/stage1/weights/best.pt")
model.train(data="custom.yaml", epochs=30, optimizer="AdamW", lr0=0.001, name="stage2", exist_ok=True)Problemas habituales#
El modelo no genera predicciones#
-
Datos de entrenamiento insuficientes: entrenar con muy pocas muestras es la causa más habitual; el modelo no puede aprender ni generalizar con tan pocos datos. Asegúrate de tener suficientes ejemplos variados por clase antes de investigar otras causas.
-
Comprueba las rutas del conjunto de datos: las rutas de imagen no válidas generan un error del conjunto de datos. Los archivos de etiquetas individuales que faltan o están vacíos se tratan como imágenes de fondo y se notifican durante el análisis; si una partición de entrenamiento no contiene etiquetas, se produce un error. Valida el conjunto de datos antes de entrenar:
yolo detect val model=yolo26n.pt data=custom.yaml -
Reduce el umbral de confianza: si hay predicciones, pero se filtran, prueba
conf=0.1durante la inferencia. -
Comprueba el número de clases: asegúrate de que
ncendata.yamlcoincida con el número real de clases de los archivos de etiquetas.
El mAP de validación se estanca pronto#
- Añade más datos: el ajuste fino mejora mucho con más datos de entrenamiento, especialmente con ejemplos variados que incluyan distintos ángulos, condiciones de iluminación y fondos.
- Comprueba el equilibrio entre clases: las clases infrarrepresentadas tendrán un AP bajo. Añade más ejemplos o ajusta
cls_pwen el conjunto de validación. - Reduce el aumento de datos: en conjuntos de datos muy pequeños, un aumento de datos intenso puede perjudicar más que ayudar. Prueba
mosaic=0.5omosaic=0.0. - Aumenta la resolución: si el conjunto de datos contiene objetos pequeños, prueba
imgsz=1280para conservar los detalles.
El rendimiento en las clases originales empeora tras el ajuste fino#
Esto se conoce como olvido catastrófico: el modelo pierde conocimientos aprendidos previamente al ajustarlo exclusivamente con datos nuevos. El olvido es prácticamente inevitable si no se incluyen imágenes del conjunto de datos original junto con los datos nuevos. Para mitigarlo:
- Combina los conjuntos de datos: incluye ejemplos de las clases originales junto con las nuevas durante el ajuste fino. Esta es la única forma fiable de evitar el olvido.
- Congela el backbone y el cuello: congelar ambos para que solo se entrene el cabezal de detección ayuda en los ajustes finos breves con una tasa de aprendizaje muy baja.
- Entrena durante menos épocas: cuanto más tiempo se entrena el modelo exclusivamente con datos nuevos, mayor es el olvido.
Preguntas frecuentes#
No hay un mínimo fijo: los resultados dependen de la complejidad de la tarea, el número de clases y la similitud del dominio con COCO. La variedad de las imágenes (distintas condiciones de iluminación, ángulos y fondos) importa más que la cantidad total. Empieza con lo que tengas y amplía el conjunto si las métricas de validación no son suficientes.
Carga un archivo
.ptpreentrenado y llama a.train()con la ruta a undata.yamlpersonalizado. Ultralytics gestiona automáticamente la transferencia de pesos, la reinicialización de la capa de clasificación y la selección del optimizador. Consulta la sección Ajuste fino básico para ver el ejemplo de código completo.Las causas más habituales son rutas de imagen no válidas, archivos de etiquetas inexistentes o vacíos, una discrepancia entre
ncen el YAML y los archivos de etiquetas reales, o un umbral de confianza demasiado alto. Consulta Problemas habituales para ver una lista completa de comprobaciones para resolver problemas.Depende del tamaño del conjunto de datos y de la similitud entre dominios. En conjuntos de datos pequeños con un dominio similar a COCO, congelar el backbone (
freeze=10) evita el sobreajuste. En dominios muy distintos de COCO, dejar todas las capas descongeladas (freeze=None) permite que el backbone se adapte. Consulta Congelar capas para ver recomendaciones detalladas.Incluye ejemplos de las clases originales en los datos de entrenamiento junto con las clases nuevas. Si no es posible, congelar más capas (
freeze=10o más) y usar una tasa de aprendizaje menor ayuda a conservar los conocimientos preentrenados. Consulta El rendimiento en las clases originales empeora para obtener más información.