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 degli oggetti all'interno dell'ecosistema Ultralytics . Sfrutteremo il formato di rilevamento YOLO e le librerie chiave di Python , come sklearn, pandas e PyYaml, per guidarvi 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 vostro progetto coinvolga il dataset di Fruit Detection o una fonte di dati personalizzata, questa esercitazione ha lo scopo di aiutarvi a comprendere e ad applicare la convalida incrociata K-Fold per rafforzare l'affidabilità e la solidità del vostro progetto. apprendimento automatico modelli. Mentre applichiamo k=5
Tenete presente che il numero ottimale di pieghe per questa esercitazione può variare a seconda del vostro set di dati e delle specifiche del vostro progetto.
Senza ulteriori indugi, tuffiamoci!
Impostazione
-
Le 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 |
---|---|
Mela | 7049 |
Uva | 7202 |
Ananas | 1613 |
Arancione | 15549 |
Banana | 3536 |
Anguria | 1976 |
-
I pacchetti necessari di Python includono:
ultralytics
sklearn
pandas
pyyaml
-
Questa esercitazione opera con
k=5
pieghe. Tuttavia, è necessario determinare il numero migliore di pieghe per il proprio set di dati specifico. -
Avviare un nuovo ambiente virtuale Python (
venv
) per il progetto e attivarlo. Utilizzarepip
(o il vostro gestore di pacchetti preferito) per l'installazione:- La biblioteca di Ultralytics :
pip install -U ultralytics
. In alternativa, è possibile clonare il file ufficiale repo. - Scikit-learn, pandas e PyYAML:
pip install -U scikit-learn pandas pyyaml
.
- La biblioteca di Ultralytics :
-
Verificare che le annotazioni siano nel formato di rilevamentoYOLO .
- Per questa esercitazione, tutti i file di annotazione si trovano nella cartella
Fruit-Detection/labels
directory.
- Per questa esercitazione, tutti i file di annotazione si trovano nella cartella
Generazione di vettori di caratteristiche per il set di dati per il rilevamento di oggetti
-
Iniziare creando un nuovo file
example.py
Python per i passi successivi. -
Procedere al recupero di tutti i file di etichetta per il set di dati.
-
Ora, leggere il contenuto del file YAML del dataset ed estrarre gli indici delle etichette delle classi.
-
Inizializza un file vuoto
pandas
DataFrame. -
Conta le istanze di ciascuna 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 è riportata una vista di esempio 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 dataset, mentre le colonne corrispondono agli indici delle etichette di classe. Ogni riga rappresenta uno pseudo-vettore di caratteristiche, con il conteggio di ogni etichetta di classe presente nel 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, è possibile 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 di classe per ogni piega come rapporto delle classi presenti in
val
a quelli 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 vostro set di dati.
-
Successivamente, si creano le directory e i file YAML del set di dati per ciascuna 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, copiare 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)
Salvare i record (facoltativo)
Opzionalmente, è possibile 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 usando le suddivisioni dei dati K-Fold
-
Per prima cosa, caricare il modello YOLO .
-
Quindi, iterare i file YAML del set di dati per eseguire l'addestramento. I risultati saranno salvati in una cartella 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 = 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
Conclusione
In questa guida, abbiamo esplorato il processo di utilizzo della convalida incrociata K-Fold per l'addestramento del modello di rilevamento degli oggetti 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 addestramento e di validazione.
In alternativa, 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 relativi 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 disponibili e per 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.
Ricordate 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 consente di applicare efficacemente la convalida incrociata nei propri progetti di apprendimento automatico. Buona codifica!
FAQ
Che 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. Ciascuna piega serve sia come dati di addestramento 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 , consultare la sezione Convalida incrociata K-Fold con Ultralytics.
Come si implementa la convalida incrociata K-Fold utilizzando Ultralytics YOLO ?
Per implementare la convalida incrociata K-Fold con Ultralytics YOLO , è necessario seguire i seguenti passaggi:
- Verificare che le annotazioni siano nel formato di rilevamentoYOLO .
- Utilizzare le librerie Python come
sklearn
,pandas
, epyyaml
. - Creare vettori di caratteristiche dal set di dati.
- Dividere il set di dati utilizzando
KFold
dasklearn.model_selection
. - Addestrare il modello YOLO su ciascuna frazione.
Per una guida completa, si veda la sezione K-Fold Dataset Split nella nostra documentazione.
Perché utilizzare Ultralytics YOLO per il rilevamento degli oggetti?
Ultralytics YOLO offre un rilevamento degli oggetti all'avanguardia e in tempo reale con un'elevata precisione ed efficienza. È versatile e supporta diverse attività di visione artificiale, 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, esplorate i vantaggi e le caratteristiche nella 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 YOLO . Ogni file di annotazione deve elencare la classe dell'oggetto e le coordinate del suo rettangolo di selezione nell'immagine. Il formato YOLO garantisce un'elaborazione dei dati semplificata e standardizzata per l'addestramento dei modelli di rilevamento degli oggetti. Per ulteriori informazioni sulla corretta formattazione delle annotazioni, visitare la guida al formato di rilevamentoYOLO .
È possibile utilizzare la convalida incrociata K-Fold con set di dati personalizzati diversi da Fruit Detection?
Sì, è possibile utilizzare la convalida incrociata K-Fold con qualsiasi set di dati personalizzato, a condizione che le annotazioni siano nel formato di rilevamento YOLO . Sostituire i percorsi del set di dati e le etichette delle classi con quelle specifiche del set di dati personalizzato. Questa flessibilità garantisce che qualsiasi progetto di rilevamento di oggetti possa beneficiare di una solida valutazione del modello utilizzando la convalida incrociata K-Fold. Per un esempio pratico, consultare la sezione Generazione di vettori di funzioni.