Validation croisée K-Fold avec Ultralytics
Introduction
Ce guide complet illustre la mise en œuvre de la validation croisée K-Fold pour les ensembles de données de détection d'objets dans l'écosystème Ultralytics . Nous nous appuierons sur le format de détection YOLO et les principales bibliothèques Python telles que sklearn, pandas et PyYaml pour vous guider dans la configuration nécessaire, le processus de génération de vecteurs de caractéristiques et l'exécution d'un fractionnement K-Fold de l'ensemble de données.
Que votre projet implique le jeu de données Fruit Detection ou une source de données personnalisée, ce tutoriel a pour but de vous aider à comprendre et à appliquer la validation croisée K-Fold pour renforcer la fiabilité et la robustesse de votre projet. apprentissage automatique modèles. Alors que nous appliquons k=5
pour ce tutoriel, gardez à l'esprit que le nombre optimal de plis peut varier en fonction de votre ensemble de données et des spécificités de votre projet.
Sans plus attendre, plongeons dans le vif du sujet !
Mise en place
-
Vos annotations doivent être au format de détectionYOLO .
-
Ce guide suppose que les fichiers d'annotation sont disponibles localement.
-
Pour notre démonstration, nous utilisons l'ensemble de données Fruit Detection.
- Cet ensemble de données contient un total de 8479 images.
- Il comprend 6 étiquettes de classe, chacune avec son nombre total d'instances indiqué ci-dessous.
Étiquette de la classe | Nombre d'instances |
---|---|
Pomme | 7049 |
Raisins | 7202 |
Ananas | 1613 |
Orange | 15549 |
Banane | 3536 |
Pastèque | 1976 |
-
Les paquets nécessaires Python comprennent
ultralytics
sklearn
pandas
pyyaml
-
Ce tutoriel fonctionne avec
k=5
plis. Cependant, vous devez déterminer le meilleur nombre de plis pour votre ensemble de données spécifique. -
Créer un nouvel environnement virtuel Python (
venv
) pour votre projet et l'activer. Utiliserpip
(ou votre gestionnaire de paquets préféré) pour l'installer :- La bibliothèque Ultralytics :
pip install -U ultralytics
. Vous pouvez Ă©galement cloner la version officielle de repo. - Scikit-learn, pandas et PyYAML :
pip install -U scikit-learn pandas pyyaml
.
- La bibliothèque Ultralytics :
-
Vérifiez que vos annotations sont au format de détectionYOLO .
- Pour ce tutoriel, tous les fichiers d'annotation se trouvent dans le dossier
Fruit-Detection/labels
répertoire.
- Pour ce tutoriel, tous les fichiers d'annotation se trouvent dans le dossier
Génération de vecteurs de caractéristiques pour l'ensemble de données de détection d'objets
-
Commencez par créer un nouveau
example.py
Python pour les Ă©tapes ci-dessous. -
Procédez à la récupération de tous les fichiers d'étiquettes pour votre ensemble de données.
-
Maintenant, lisez le contenu du fichier YAML de l'ensemble de données et extrayez les indices des étiquettes de classe.
-
Initialisation d'un
pandas
DataFrame. -
Compter les instances de chaque étiquette de classe présente dans les fichiers d'annotation.
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`
-
Voici un exemple d'affichage du DataFrame rempli :
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
Les lignes indexent les fichiers d'étiquettes, chacun correspondant à une image de votre ensemble de données, et les colonnes correspondent à vos indices d'étiquettes de classe. Chaque ligne représente un pseudo-vecteur de caractéristiques, avec le nombre de chaque étiquette de classe présente dans votre ensemble de données. Cette structure de données permet d'appliquer la validation croisée K-Fold à un ensemble de données de détection d'objets.
Fractionnement de l'ensemble de données K-Fold
-
Nous allons maintenant utiliser le
KFold
de la classesklearn.model_selection
pour générerk
de l'ensemble de données.- Important :
- Paramètres
shuffle=True
garantit une distribution aléatoire des classes dans vos divisions. - En fixant
random_state=M
oĂąM
est un nombre entier choisi, vous pouvez obtenir des résultats reproductibles.
- Paramètres
- Important :
-
L'ensemble des données a été divisé en
k
chacun ayant une liste detrain
etval
indices. Nous construirons un DataFrame pour afficher ces résultats plus clairement. -
Nous allons maintenant calculer la distribution des étiquettes de classe pour chaque pli sous la forme d'un rapport entre les classes présentes dans
val
aux personnes présentes 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
Le scénario idéal est que tous les rapports de classe soient raisonnablement similaires pour chaque fractionnement et pour toutes les classes. Cela dépend toutefois des spécificités de votre ensemble de données.
-
Ensuite, nous créons les répertoires et les fichiers YAML des jeux de données pour chaque fractionnement.
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, )
-
Enfin, copiez les images et les étiquettes dans le répertoire respectif ("train" ou "val") pour chaque division.
- REMARQUE : le temps nécessaire pour cette partie du code varie en fonction de la taille de votre ensemble de données et du matériel de votre système.
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)
Sauvegarder les enregistrements (facultatif)
En option, vous pouvez enregistrer les enregistrements des DataFrames de fractionnement K-Fold et de distribution d'étiquettes sous forme de fichiers CSV pour référence ultérieure.
folds_df.to_csv(save_path / "kfold_datasplit.csv")
fold_lbl_distrb.to_csv(save_path / "kfold_label_distribution.csv")
Former YOLO Ă l'aide de K-Fold Data Splits
-
Commencez par charger le modèle YOLO .
-
Ensuite, itérer sur les fichiers YAML de l'ensemble de données pour exécuter l'entraînement. Les résultats seront enregistrés dans un répertoire spécifié par l'option
project
etname
arguments. Par défaut, ce répertoire est 'exp/runs#' où # est un index entier.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
Conclusion
Dans ce guide, nous avons exploré le processus d'utilisation de la validation croisée K-Fold pour l'entraînement du modèle de détection d'objets YOLO . Nous avons appris à diviser notre ensemble de données en K partitions, en veillant à ce que la répartition des classes soit équilibrée entre les différents plis.
Nous avons également exploré la procédure de création de rapports DataFrames pour visualiser les divisions de données et les distributions d'étiquettes sur ces divisions, ce qui nous a permis d'avoir un aperçu clair de la structure de nos ensembles de formation et de validation.
En option, nous avons sauvegardé nos enregistrements pour référence ultérieure, ce qui peut s'avérer particulièrement utile dans les projets à grande échelle ou lors du dépannage des performances du modèle.
Enfin, nous avons mis en œuvre l'apprentissage du modèle proprement dit en utilisant chaque fractionnement dans une boucle, en sauvegardant nos résultats d'apprentissage pour une analyse et une comparaison ultérieures.
Cette technique de validation croisée K-Fold est un moyen robuste de tirer le meilleur parti de vos données disponibles, et elle contribue à garantir que les performances de votre modèle sont fiables et cohérentes dans différents sous-ensembles de données. Il en résulte un modèle plus généralisable et plus fiable, moins susceptible de s'adapter de manière excessive à des modèles de données spécifiques.
N'oubliez pas que, bien que nous ayons utilisé YOLO dans ce guide, ces étapes sont en grande partie transférables à d'autres modèles d'apprentissage automatique. La compréhension de ces étapes vous permet d'appliquer efficacement la validation croisée dans vos propres projets d'apprentissage automatique. Bon codage !
FAQ
Qu'est-ce que la validation croisée K-Fold et pourquoi est-elle utile dans la détection d'objets ?
La validation croisée K-Fold est une technique dans laquelle l'ensemble de données est divisé en "k" sous-ensembles (plis) afin d'évaluer les performances du modèle de manière plus fiable. Chaque pli sert à la fois de données de formation et de validation. Dans le contexte de la détection d'objets, l'utilisation de la validation croisée K-Fold permet de s'assurer que les performances de votre modèle Ultralytics YOLO sont robustes et généralisables à travers différents découpages de données, améliorant ainsi sa fiabilité. Pour obtenir des instructions détaillées sur la configuration de la validation croisée K-Fold avec Ultralytics YOLO , reportez-vous à la validation croisée K-Fold avec Ultralytics.
Comment mettre en œuvre la validation croisée K-Fold à l'aide de Ultralytics YOLO ?
Pour mettre en œuvre la validation croisée K-Fold avec Ultralytics YOLO , vous devez suivre les étapes suivantes :
- Vérifier que les annotations sont dans le format de détectionYOLO .
- Utilisez les bibliothèques Python comme
sklearn
,pandas
etpyyaml
. - Créez des vecteurs de caractéristiques à partir de votre ensemble de données.
- Divisez votre ensemble de données en utilisant
KFold
desklearn.model_selection
. - Entraîner le modèle YOLO sur chaque fractionnement.
Pour un guide complet, voir la section K-Fold Dataset Split dans notre documentation.
Pourquoi utiliser Ultralytics YOLO pour la détection d'objets ?
Ultralytics YOLO offre une détection d'objets en temps réel à la pointe de la technologie, avec une précision et une efficacité élevées. Polyvalent, il prend en charge de multiples tâches de vision artificielle telles que la détection, la segmentation et la classification. En outre, il s'intègre parfaitement à des outils tels que Ultralytics HUB pour la formation et le déploiement de modèles sans code. Pour plus de détails, explorez les avantages et les caractéristiques sur notre pageUltralytics YOLO .
Comment puis-je m'assurer que mes annotations sont dans le bon format pour Ultralytics YOLO ?
Vos annotations doivent respecter le format de détection YOLO . Chaque fichier d'annotation doit indiquer la classe de l'objet, ainsi que les coordonnées de sa boîte englobante dans l'image. Le format YOLO garantit un traitement rationalisé et normalisé des données pour l'entraînement des modèles de détection d'objets. Pour plus d'informations sur le formatage correct des annotations, consultez le guide du format de détectionYOLO .
Puis-je utiliser la validation croisée K-Fold avec des ensembles de données personnalisés autres que la détection de fruits ?
Oui, vous pouvez utiliser la validation croisée K-Fold avec n'importe quel ensemble de données personnalisé, à condition que les annotations soient au format de détection YOLO . Remplacez les chemins d'accès à l'ensemble de données et les étiquettes de classe par ceux spécifiques à votre ensemble de données personnalisé. Cette flexibilité garantit que tout projet de détection d'objets peut bénéficier d'une évaluation robuste du modèle à l'aide de la validation croisée K-Fold. Pour un exemple pratique, consultez la section Génération de vecteurs de caractéristiques.