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 modelos de aprendizaje autom谩tico. 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
-
Empieza creando un nuevo archivo Python e importa las bibliotecas necesarias.
-
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.
for label in labels: lbl_counter = Counter() with open(label,'r') as lf: lines = lf.readlines() for l in lines: # classes for YOLO label uses integer at first position of each line lbl_counter[int(l.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.
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.
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.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!