Convalida incrociata K-Fold con Ultralytics
Introduzione
Questa guida completa illustra l'implementazione della convalida incrociata K-Fold per i set di dati di rilevamento di oggetti all'interno dell'ecosistema Ultralytics . Sfrutteremo il formato di rilevamento YOLO e le librerie chiave di Python come sklearn, pandas e PyYaml per guidarti attraverso la configurazione necessaria, il processo di generazione dei vettori di caratteristiche e l'esecuzione di una divisione del dataset K-Fold.
Sia che il tuo progetto coinvolga il dataset Fruit Detection o una fonte di dati personalizzata, questo tutorial ha lo scopo di aiutarti a comprendere e ad applicare la convalida incrociata K-Fold per rafforzare l'affidabilità e la robustezza dei tuoi modelli di apprendimento automatico. Mentre applichiamo k=5
Tieni presente che il numero ottimale di pieghe per questo tutorial può variare a seconda del tuo set di dati e delle specifiche del tuo progetto.
Senza ulteriori indugi, tuffiamoci!
Configurazione
-
Le tue annotazioni devono essere nel formato di rilevamentoYOLO .
-
Questa guida presuppone che i file di annotazione siano disponibili localmente.
-
Per la nostra dimostrazione, utilizziamo il dataset Fruit Detection.
- Questo set di dati contiene un totale di 8479 immagini.
- Include 6 etichette di classe, ciascuna con il numero totale di istanze elencate di seguito.
Etichetta di classe | Conteggio delle istanze |
---|---|
Apple | 7049 |
Uva | 7202 |
Ananas | 1613 |
Arancione | 15549 |
Banana | 3536 |
Anguria | 1976 |
-
I pacchetti necessari di Python includono:
ultralytics
sklearn
pandas
pyyaml
-
Questo tutorial opera con
k=5
pieghe. Tuttavia, devi determinare il numero migliore di pieghe per il tuo set di dati specifico. -
Avvia un nuovo ambiente virtuale Python (
venv
) per il tuo progetto e attivarlo. Utilizzapip
(o il tuo gestore di pacchetti preferito) per l'installazione:- La biblioteca di Ultralytics :
pip install -U ultralytics
. In alternativa, puoi clonare il sito ufficiale repo. - Scikit-learn, pandas e PyYAML:
pip install -U scikit-learn pandas pyyaml
.
- La biblioteca di Ultralytics :
-
Verifica che le annotazioni siano nel formato di rilevamentoYOLO .
- Per questo tutorial, tutti i file di annotazione si trovano nella cartella
Fruit-Detection/labels
directory.
- Per questo tutorial, tutti i file di annotazione si trovano nella cartella
Generazione di vettori di caratteristiche per il dataset di rilevamento degli oggetti
-
Inizia creando un nuovo
example.py
Python file per i passaggi seguenti. -
Procedi con il recupero di tutti i file di etichetta per il tuo set di dati.
-
Ora, leggi il contenuto del file YAML del dataset ed estrai gli indici delle etichette delle classi.
-
Inizializza un file vuoto
pandas
DataFrame. -
Conta le istanze di ogni etichetta di classe presenti nei file di annotazione.
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`
-
Di seguito è riportato un esempio di visualizzazione del DataFrame popolato:
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
Le righe indicizzano i file delle etichette, ciascuno corrispondente a un'immagine del tuo set di dati, mentre le colonne corrispondono agli indici delle etichette delle classi. Ogni riga rappresenta uno pseudo vettore di caratteristiche, con il conteggio di ogni etichetta di classe presente nel tuo dataset. Questa struttura di dati consente di applicare la convalida incrociata K-Fold a un set di dati per il rilevamento di oggetti.
Divisione del set di dati K-Fold
-
Ora utilizzeremo l'opzione
KFold
classe dasklearn.model_selection
per generarek
suddivisione del set di dati.- Importante:
- Impostazione
shuffle=True
garantisce una distribuzione randomizzata delle classi negli split. - Impostando
random_state=M
doveM
è un numero intero scelto, puoi ottenere risultati ripetibili.
- Impostazione
- Importante:
-
Il set di dati è stato suddiviso in
k
pieghe, ognuna delle quali ha un elenco ditrain
eval
indici. Costruiremo un DataFrame per visualizzare questi risultati in modo più chiaro. -
Ora calcoleremo la distribuzione delle etichette delle classi per ogni piega come rapporto delle classi presenti in
val
a coloro che sono presenti intrain
.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
Lo scenario ideale è che tutti i rapporti tra le classi siano ragionevolmente simili per ogni divisione e tra le classi. Questo, tuttavia, dipende dalle caratteristiche specifiche del tuo set di dati.
-
Successivamente, creiamo le directory e i file YAML del dataset per ogni suddivisione.
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, )
-
Infine, copia le immagini e le etichette nella rispettiva directory ("train" o "val") per ogni divisione.
- NOTA: il tempo richiesto per questa parte del codice varia in base alle dimensioni del set di dati e all'hardware del 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)
Salva i record (opzionale)
Opzionalmente, puoi salvare i record dei DataFrames della divisione K-Fold e della distribuzione delle etichette come file CSV per riferimenti futuri.
folds_df.to_csv(save_path / "kfold_datasplit.csv")
fold_lbl_distrb.to_csv(save_path / "kfold_label_distribution.csv")
Addestrare YOLO utilizzando K-Fold Data Splits
-
Per prima cosa, carica il modello YOLO .
-
Quindi, itera sui file YAML del set di dati per eseguire l'addestramento. I risultati verranno salvati in una directory specificata dall'opzione
project
ename
argomenti. Per impostazione predefinita, questa directory è 'exp/runs#' dove # è un indice intero.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
Conclusione
In questa guida abbiamo esplorato il processo di utilizzo della convalida incrociata K-Fold per l'addestramento del modello di rilevamento degli oggetti di YOLO . Abbiamo imparato a dividere il nostro set di dati in K partizioni, assicurando una distribuzione bilanciata delle classi nelle diverse pieghe.
Abbiamo anche esplorato la procedura per la creazione di DataFrames di report per visualizzare le suddivisioni dei dati e le distribuzioni delle etichette tra queste suddivisioni, fornendoci una chiara visione della struttura dei nostri set di formazione e convalida.
Opzionalmente, abbiamo salvato i nostri record per riferimenti futuri, il che potrebbe essere particolarmente utile in progetti su larga scala o per la risoluzione di problemi legati alle prestazioni del modello.
Infine, abbiamo implementato l'addestramento vero e proprio del modello utilizzando ogni split in un ciclo, salvando i risultati dell'addestramento per ulteriori analisi e confronti.
Questa tecnica di convalida incrociata K-Fold è un modo robusto per sfruttare al meglio i dati a disposizione e aiuta a garantire che le prestazioni del modello siano affidabili e coerenti tra i diversi sottoinsiemi di dati. In questo modo si ottiene un modello più generalizzabile e affidabile che ha meno probabilità di adattarsi eccessivamente a modelli di dati specifici.
Ricorda che, sebbene in questa guida abbiamo utilizzato YOLO , questi passaggi sono per lo più trasferibili ad altri modelli di apprendimento automatico. La comprensione di questi passaggi ti permette di applicare la convalida incrociata in modo efficace nei tuoi progetti di apprendimento automatico. Buona programmazione!
DOMANDE FREQUENTI
Cos'è la convalida incrociata K-Fold e perché è utile nel rilevamento degli oggetti?
La convalida incrociata K-Fold è una tecnica in cui il set di dati viene suddiviso in "k" sottoinsiemi (fold) per valutare le prestazioni del modello in modo più affidabile. Ogni piega serve sia come dati di formazione che di validazione. Nel contesto del rilevamento di oggetti, l'uso della convalida incrociata K-Fold aiuta a garantire che le prestazioni del modello Ultralytics YOLO siano robuste e generalizzabili attraverso diverse suddivisioni dei dati, migliorandone l'affidabilità. Per istruzioni dettagliate sull'impostazione della convalida incrociata K-Fold con Ultralytics YOLO , consulta la sezione Convalida incrociata K-Fold con Ultralytics.
Come posso implementare la convalida incrociata K-Fold utilizzando Ultralytics YOLO ?
Per implementare la convalida incrociata K-Fold con Ultralytics YOLO , devi seguire i seguenti passaggi:
- Verifica che le annotazioni siano nel formato di rilevamentoYOLO .
- Usa le librerie di Python come
sklearn
,pandas
, epyyaml
. - Crea vettori di caratteristiche dal tuo set di dati.
- Dividi il tuo set di dati utilizzando
KFold
dasklearn.model_selection
. - Addestrare il modello di YOLO su ogni split.
Per una guida completa, consulta la sezione K-Fold Dataset Split nella nostra documentazione.
Perché dovrei utilizzare Ultralytics YOLO per il rilevamento degli oggetti?
Ultralytics YOLO offre un rilevamento di oggetti all'avanguardia e in tempo reale con un'elevata precisione ed efficienza. È versatile e supporta diverse attività di computer vision come il rilevamento, la segmentazione e la classificazione. Inoltre, si integra perfettamente con strumenti come Ultralytics HUB per l'addestramento e la distribuzione di modelli senza codice. Per maggiori dettagli, esplora i vantaggi e le caratteristiche della nostra paginaUltralytics YOLO .
Come posso assicurarmi che le mie annotazioni siano nel formato corretto per Ultralytics YOLO ?
Le annotazioni devono seguire il formato di rilevamento di YOLO . Ogni file di annotazione deve elencare la classe dell'oggetto e le coordinate del suo riquadro di delimitazione nell'immagine. Il formato YOLO garantisce un'elaborazione dei dati semplificata e standardizzata per l'addestramento dei modelli di rilevamento degli oggetti. Per maggiori informazioni sulla corretta formattazione delle annotazioni, visita la guida al formato di rilevamentoYOLO .
Posso utilizzare la convalida incrociata K-Fold con set di dati personalizzati diversi da Fruit Detection?
Sì, puoi utilizzare la convalida incrociata K-Fold con qualsiasi set di dati personalizzato, purché le annotazioni siano nel formato di rilevamento YOLO . Sostituisci i percorsi del dataset e le etichette delle classi con quelle specifiche del tuo dataset personalizzato. Questa flessibilità fa sì che qualsiasi progetto di rilevamento di oggetti possa beneficiare di una solida valutazione del modello utilizzando la K-Fold Cross Validation. Per un esempio pratico, consulta la sezione Generazione di vettori di caratteristiche.