Validación cruzada K-Fold con Ultralytics
Introducción
Esta completa guía ilustra la implementación de la Validación Cruzada K-Fold para conjuntos de datos de detección de objetos dentro del ecosistema Ultralytics . Aprovecharemos el formato de detección YOLO y las bibliotecas clave de Python , como sklearn, pandas y PyYaml, para guiarte por la configuración necesaria, el proceso de generación de vectores de características y la ejecución de una división K-Fold de conjuntos de datos.
Tanto si tu proyecto incluye el conjunto de datos de Fruit Detection como una fuente de datos personalizada, este tutorial pretende ayudarte a comprender y aplicar la Validación Cruzada K-Fold para reforzar la fiabilidad y solidez de tus datos. aprendizaje automático modelos. Mientras aplicamos k=5
pliegues para este tutorial, ten en cuenta que el número óptimo de pliegues puede variar en función de tu conjunto de datos y de las particularidades de tu proyecto.
Sin más preámbulos, ¡vamos a sumergirnos!
Configurar
Tus anotaciones deben estar en el formato de detecciónYOLO .
Esta guía asume que los archivos de anotación están disponibles localmente.
Para nuestra demostración, utilizamos el conjunto de datos Detección de Frutas.
- Este conjunto de datos contiene un total de 8479 imágenes.
- Incluye 6 etiquetas de clase, cada una con su recuento total de instancias indicado a continuación.
Etiqueta de clase | Recuento de instancias |
---|---|
Manzana | 7049 |
Uvas | 7202 |
Piña | 1613 |
Naranja | 15549 |
Plátano | 3536 |
Sandía | 1976 |
Los paquetes necesarios de Python incluyen:
ultralytics
sklearn
pandas
pyyaml
Este tutorial funciona con
k=5
pliegues. Sin embargo, debes determinar el mejor número de pliegues para tu conjunto de datos específico.Inicia un nuevo entorno virtual Python (
venv
) para tu proyecto y actívalo. Utilizapip
(o tu gestor de paquetes preferido) para instalarlo:- La biblioteca Ultralytics :
pip install -U ultralytics
. Alternativamente, puedes clonar el archivo oficial repo. - Scikit-learn, pandas y PyYAML:
pip install -U scikit-learn pandas pyyaml
.
- La biblioteca Ultralytics :
Comprueba que tus anotaciones están en el formato de detecciónYOLO .
- Para este tutorial, todos los archivos de anotación se encuentran en la carpeta
Fruit-Detection/labels
directorio.
- Para este tutorial, todos los archivos de anotación se encuentran en la carpeta
Generación de vectores de características para el conjunto de datos de detección de objetos
Comience por crear un nuevo archivo
example.py
Python para los pasos a continuación.Procede a recuperar todos los archivos de etiquetas de tu conjunto de datos.
Ahora, lee el contenido del archivo YAML del conjunto de datos y extrae los índices de las etiquetas de clase.
Inicializa una casilla vacía
pandas
Marco de datos.Cuenta las instancias de cada clase-etiqueta presentes en los archivos de anotación.
from collections import Counter for label in labels: lbl_counter = Counter() with open(label, "r") as lf: lines = lf.readlines() for line in lines: # classes for YOLO label uses integer at first position of each line lbl_counter[int(line.split(" ")[0])] += 1 labels_df.loc[label.stem] = lbl_counter labels_df = labels_df.fillna(0.0) # replace `nan` values with `0.0`
A continuación se muestra una vista de ejemplo del Marco de Datos rellenado:
0 1 2 3 4 5 '0000a16e4b057580_jpg.rf.00ab48988370f64f5ca8ea4...' 0.0 0.0 0.0 0.0 0.0 7.0 '0000a16e4b057580_jpg.rf.7e6dce029fb67f01eb19aa7...' 0.0 0.0 0.0 0.0 0.0 7.0 '0000a16e4b057580_jpg.rf.bc4d31cdcbe229dd022957a...' 0.0 0.0 0.0 0.0 0.0 7.0 '00020ebf74c4881c_jpg.rf.508192a0a97aa6c4a3b6882...' 0.0 0.0 0.0 1.0 0.0 0.0 '00020ebf74c4881c_jpg.rf.5af192a2254c8ecc4188a25...' 0.0 0.0 0.0 1.0 0.0 0.0 ... ... ... ... ... ... ... 'ff4cd45896de38be_jpg.rf.c4b5e967ca10c7ced3b9e97...' 0.0 0.0 0.0 0.0 0.0 2.0 'ff4cd45896de38be_jpg.rf.ea4c1d37d2884b3e3cbce08...' 0.0 0.0 0.0 0.0 0.0 2.0 'ff5fd9c3c624b7dc_jpg.rf.bb519feaa36fc4bf630a033...' 1.0 0.0 0.0 0.0 0.0 0.0 'ff5fd9c3c624b7dc_jpg.rf.f0751c9c3aa4519ea3c9d6a...' 1.0 0.0 0.0 0.0 0.0 0.0 'fffe28b31f2a70d4_jpg.rf.7ea16bd637ba0711c53b540...' 0.0 6.0 0.0 0.0 0.0 0.0
Las filas indexan los archivos de etiquetas, cada uno de los cuales corresponde a una imagen de tu conjunto de datos, y las columnas corresponden a tus índices de etiquetas de clase. Cada fila representa un pseudovector de características, con el recuento de cada etiqueta de clase presente en tu conjunto de datos. Esta estructura de datos permite aplicar la Validación Cruzada K-Fold a un conjunto de datos de detección de objetos.
Dividir el conjunto de datos K-Fold
Ahora utilizaremos
KFold
clase desklearn.model_selection
para generark
divisiones del conjunto de datos.- Importante:
- Configurar
shuffle=True
garantiza una distribución aleatoria de las clases en tus divisiones. - Estableciendo
random_state=M
dondeM
es un número entero elegido, puedes obtener resultados repetibles.
- Configurar
- Importante:
El conjunto de datos se ha dividido en
k
pliegues, cada uno con una lista detrain
yval
índices. Construiremos un DataFrame para mostrar estos resultados con mayor claridad.Ahora calcularemos la distribución de las etiquetas de clase de cada pliegue como proporción de las clases presentes en
val
a los presentes entrain
.fold_lbl_distrb = pd.DataFrame(index=folds, columns=cls_idx) for n, (train_indices, val_indices) in enumerate(kfolds, start=1): train_totals = labels_df.iloc[train_indices].sum() val_totals = labels_df.iloc[val_indices].sum() # To avoid division by zero, we add a small value (1E-7) to the denominator ratio = val_totals / (train_totals + 1e-7) fold_lbl_distrb.loc[f"split_{n}"] = ratio
El escenario ideal es que todas las proporciones de clase sean razonablemente similares para cada división y entre las clases. Sin embargo, esto dependerá de las características específicas de tu conjunto de datos.
A continuación, creamos los directorios y los archivos YAML del conjunto de datos para cada división.
import datetime supported_extensions = [".jpg", ".jpeg", ".png"] # Initialize an empty list to store image file paths images = [] # Loop through supported extensions and gather image files for ext in supported_extensions: images.extend(sorted((dataset_path / "images").rglob(f"*{ext}"))) # Create the necessary directories and dataset YAML files (unchanged) save_path = Path(dataset_path / f"{datetime.date.today().isoformat()}_{ksplit}-Fold_Cross-val") save_path.mkdir(parents=True, exist_ok=True) ds_yamls = [] for split in folds_df.columns: # Create directories split_dir = save_path / split split_dir.mkdir(parents=True, exist_ok=True) (split_dir / "train" / "images").mkdir(parents=True, exist_ok=True) (split_dir / "train" / "labels").mkdir(parents=True, exist_ok=True) (split_dir / "val" / "images").mkdir(parents=True, exist_ok=True) (split_dir / "val" / "labels").mkdir(parents=True, exist_ok=True) # Create dataset YAML files dataset_yaml = split_dir / f"{split}_dataset.yaml" ds_yamls.append(dataset_yaml) with open(dataset_yaml, "w") as ds_y: yaml.safe_dump( { "path": split_dir.as_posix(), "train": "train", "val": "val", "names": classes, }, ds_y, )
Por último, copia las imágenes y las etiquetas en el directorio respectivo ("tren" o "val") para cada división.
- NOTA: El tiempo necesario para esta parte del código variará en función del tamaño de tu conjunto de datos y del hardware de tu sistema.
import shutil for image, label in zip(images, labels): for split, k_split in folds_df.loc[image.stem].items(): # Destination directory img_to_path = save_path / split / k_split / "images" lbl_to_path = save_path / split / k_split / "labels" # Copy image and label files to new directory (SamefileError if file already exists) shutil.copy(image, img_to_path / image.name) shutil.copy(label, lbl_to_path / label.name)
Guardar registros (Opcional)
Opcionalmente, puedes guardar los registros de los DataFrames de división K-Fold y distribución de etiquetas como archivos CSV para futuras consultas.
folds_df.to_csv(save_path / "kfold_datasplit.csv")
fold_lbl_distrb.to_csv(save_path / "kfold_label_distribution.csv")
Entrena YOLO utilizando K-Divisiones de Datos
Primero, carga el modelo YOLO .
A continuación, itera sobre los archivos YAML del conjunto de datos para ejecutar el entrenamiento. Los resultados se guardarán en un directorio especificado por la opción
project
yname
argumentos. Por defecto, este directorio es 'exp/runs#', donde # es un índice entero.results = {} # Define your additional arguments here batch = 16 project = "kfold_demo" epochs = 100 for k in range(ksplit): dataset_yaml = ds_yamls[k] model = YOLO(weights_path, task="detect") model.train(data=dataset_yaml, epochs=epochs, batch=batch, project=project) # include any train arguments results[k] = model.metrics # save output metrics for further analysis
Conclusión
En esta guía, hemos explorado el proceso de utilizar la validación cruzada de K pliegues para entrenar el modelo de detección de objetos YOLO . Hemos aprendido a dividir nuestro conjunto de datos en K particiones, garantizando una distribución de clases equilibrada en los distintos pliegues.
También exploramos el procedimiento de creación de DataFrames de informes para visualizar las divisiones de datos y las distribuciones de etiquetas en dichas divisiones, lo que nos proporcionó una visión clara de la estructura de nuestros conjuntos de entrenamiento y validación.
Opcionalmente, guardamos nuestros registros para futuras consultas, lo que podría ser especialmente útil en proyectos a gran escala o al solucionar problemas de rendimiento del modelo.
Por último, implementamos el entrenamiento real del modelo utilizando cada división en un bucle, guardando nuestros resultados de entrenamiento para su posterior análisis y comparación.
Esta técnica de validación cruzada K-Fold es una forma sólida de aprovechar al máximo los datos disponibles, y ayuda a garantizar que el rendimiento de tu modelo es fiable y coherente en diferentes subconjuntos de datos. El resultado es un modelo más generalizable y fiable, con menos probabilidades de sobreajustarse a patrones de datos específicos.
Recuerda que, aunque en esta guía hemos utilizado YOLO , estos pasos son en su mayoría transferibles a otros modelos de aprendizaje automático. Comprender estos pasos te permitirá aplicar eficazmente la validación cruzada en tus propios proyectos de aprendizaje automático. ¡Feliz programación!
PREGUNTAS FRECUENTES
¿Qué es la Validación Cruzada K-Fold y por qué es útil en la detección de objetos?
La validación cruzada por K pliegues es una técnica en la que el conjunto de datos se divide en "k" subconjuntos (pliegues) para evaluar el rendimiento del modelo de forma más fiable. Cada pliegue sirve como datos de entrenamiento y de validación. En el contexto de la detección de objetos, utilizar la Validación Cruzada K-Fold ayuda a garantizar que el rendimiento de tu modelo Ultralytics YOLO es robusto y generalizable a través de diferentes divisiones de datos, mejorando su fiabilidad. Para obtener instrucciones detalladas sobre la configuración de la Validación Cruzada K-Fold con Ultralytics YOLO , consulta Validación Cruzada K-Fold con Ultralytics.
¿Cómo aplico la validación cruzada K-Fold utilizando Ultralytics YOLO ?
Para aplicar la Validación Cruzada K-Fold con Ultralytics YOLO , tienes que seguir estos pasos:
- Comprueba que las anotaciones están en el formato de detecciónYOLO .
- Utiliza bibliotecas Python como
sklearn
,pandas
ypyyaml
. - Crea vectores de características a partir de tu conjunto de datos.
- Divide tu conjunto de datos utilizando
KFold
desklearn.model_selection
. - Entrena el modelo YOLO en cada división.
Para obtener una guía completa, consulta la sección Dividir conjuntos de datos K-Fold de nuestra documentación.
¿Por qué debería utilizar Ultralytics YOLO para la detección de objetos?
Ultralytics YOLO ofrece detección de objetos en tiempo real de última generación, con gran precisión y eficacia. Es versátil y admite múltiples tareas de visión por ordenador, como la detección, la segmentación y la clasificación. Además, se integra perfectamente con herramientas como Ultralytics HUB para el entrenamiento y despliegue de modelos sin código. Para más detalles, explora las ventajas y características en nuestra páginaUltralytics YOLO .
¿Cómo puedo asegurarme de que mis anotaciones tienen el formato correcto para Ultralytics YOLO ?
Tus anotaciones deben seguir el formato de detección YOLO . Cada archivo de anotación debe enumerar la clase de objeto, junto con las coordenadas de su cuadro delimitador en la imagen. El formato YOLO garantiza un procesamiento de datos racionalizado y estandarizado para el entrenamiento de modelos de detección de objetos. Para más información sobre el formato adecuado de las anotaciones, visita la guía del formato de detecciónYOLO .
¿Puedo utilizar la Validación Cruzada K-Fold con conjuntos de datos personalizados distintos de la Detección de Frutas?
Sí, puedes utilizar la Validación Cruzada K-Fold con cualquier conjunto de datos personalizado, siempre que las anotaciones estén en el formato de detección YOLO . Sustituye las rutas del conjunto de datos y las etiquetas de clase por las específicas de tu conjunto de datos personalizado. Esta flexibilidad garantiza que cualquier proyecto de detección de objetos pueda beneficiarse de una sólida evaluación del modelo mediante la Validación Cruzada K-Fold. Para ver un ejemplo práctico, consulta nuestra sección Generación de vectores de características.