İçeriğe geç

K-Katlı Çapraz Doğrulama ile Ultralytics

Giriş

This comprehensive guide illustrates the implementation of K-Fold Cross Validation for object detection datasets within the Ultralytics ecosystem. We'll leverage the YOLO detection format and key Python libraries such as sklearn, pandas, and PyYaml to guide you through the necessary setup, the process of generating feature vectors, and the execution of a K-Fold dataset split.

K-Katlı Çapraz Doğrulamaya Genel Bakış

Whether your project involves the Fruit Detection dataset or a custom data source, this tutorial aims to help you comprehend and apply K-Fold Cross Validation to bolster the reliability and robustness of your machine learning models. While we're applying k=5 Bu eğitim için katlama sayısını belirlerken, optimum katlama sayısının veri setinize ve projenizin özelliklerine bağlı olarak değişebileceğini unutmayın.

Lafı daha fazla uzatmadan içeri dalalım!

Kurulum

  • Ek açıklamalarınız YOLO algılama formatında olmalıdır.

  • Bu kılavuz ek açıklama dosyalarının yerel olarak mevcut olduğunu varsayar.

  • Gösterimiz için Meyve Tespiti veri kümesini kullanıyoruz.

    • Bu veri kümesi toplam 8479 görüntü içermektedir.
    • Her biri aşağıda listelenen toplam örnek sayılarıyla birlikte 6 sınıf etiketi içerir.
Sınıf EtiketiÖrnek Sayısı
Elma7049
Üzümler7202
Ananas1613
Turuncu15549
Muz3536
Karpuz1976
  • Gerekli Python paketleri şunları içerir:

    • ultralytics
    • sklearn
    • pandas
    • pyyaml
  • Bu eğitim şu şekilde çalışır k=5 katlar. Ancak, kendi veri kümeniz için en iyi katlama sayısını belirlemelisiniz.

  • Yeni bir Python sanal ortamı başlatın (venv) projeniz için seçin ve etkinleştirin. Kullanım pip (veya tercih ettiğiniz paket yöneticisi) ile yükleyebilirsiniz:

    • Ultralytics kütüphanesi: pip install -U ultralytics. Alternatif olarak, resmi repo.
    • Scikit-learn, pandas ve PyYAML: pip install -U scikit-learn pandas pyyaml.
  • Ek açıklamalarınızın YOLO algılama biçiminde olduğunu doğrulayın.

    • Bu eğitim için, tüm ek açıklama dosyaları Fruit-Detection/labels dizin.

Nesne Algılama Veri Kümesi için Özellik Vektörleri Oluşturma

  1. Yeni bir oluşturarak başlayın example.py Python Aşağıdaki adımlar için dosya.

  2. Veri setiniz için tüm etiket dosyalarını almaya devam edin.

    from pathlib import Path
    
    dataset_path = Path("./Fruit-detection")  # replace with 'path/to/dataset' for your custom data
    labels = sorted(dataset_path.rglob("*labels/*.txt"))  # all data in 'labels'
    
  3. Şimdi, veri kümesi YAML dosyasının içeriğini okuyun ve sınıf etiketlerinin indekslerini çıkarın.

    yaml_file = "path/to/data.yaml"  # your data YAML with data directories and names dictionary
    with open(yaml_file, "r", encoding="utf8") as y:
        classes = yaml.safe_load(y)["names"]
    cls_idx = sorted(classes.keys())
    
  4. Boş bir başlatma pandas DataFrame.

    import pandas as pd
    
    indx = [label.stem for label in labels]  # uses base filename as ID (no extension)
    labels_df = pd.DataFrame([], columns=cls_idx, index=indx)
    
  5. Ek açıklama dosyalarında bulunan her sınıf etiketinin örneklerini sayı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`
    
  6. Aşağıda, doldurulmuş DataFrame'in örnek bir görünümü yer almaktadır:

                                                           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
    

Satırlar, her biri veri kümenizdeki bir görüntüye karşılık gelen etiket dosyalarını indeksler ve sütunlar sınıf-etiket indekslerinize karşılık gelir. Her satır, veri kümenizde bulunan her sınıf etiketinin sayısıyla birlikte sözde bir özellik vektörünü temsil eder. Bu veri yapısı, bir nesne algılama veri kümesine K-Kat Çapraz Doğrulama uygulanmasını sağlar.

K-Katlı Veri Kümesi Bölme

  1. Şimdi kullanacağımız KFold sınıfından sklearn.model_selection üretmek için k veri kümesinin bölünmesi.

    • Önemli:
      • Ayar shuffle=True bölünmelerinizde sınıfların rastgele dağılımını sağlar.
      • Ayarlayarak random_state=M nerede M seçilen bir tamsayı ise, tekrarlanabilir sonuçlar elde edebilirsiniz.
    from sklearn.model_selection import KFold
    
    ksplit = 5
    kf = KFold(n_splits=ksplit, shuffle=True, random_state=20)  # setting random_state for repeatable results
    
    kfolds = list(kf.split(labels_df))
    
  2. Veri kümesi şimdi şu bölümlere ayrılmıştır k katlar, her biri bir train ve val endeksler. Bu sonuçları daha net bir şekilde görüntülemek için bir DataFrame oluşturacağız.

    folds = [f"split_{n}" for n in range(1, ksplit + 1)]
    folds_df = pd.DataFrame(index=indx, columns=folds)
    
    for idx, (train, val) in enumerate(kfolds, start=1):
        folds_df[f"split_{idx}"].loc[labels_df.iloc[train].index] = "train"
        folds_df[f"split_{idx}"].loc[labels_df.iloc[val].index] = "val"
    
  3. Şimdi her bir kat için sınıf etiketlerinin dağılımını, mevcut sınıfların bir oranı olarak hesaplayacağız. val orada bulunanlara train.

    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
    

    İdeal senaryo, tüm sınıf oranlarının her bölünme için ve sınıflar arasında makul ölçüde benzer olmasıdır. Ancak bu, veri setinizin özelliklerine bağlı olacaktır.

  4. Ardından, her bir bölünme için dizinleri ve veri kümesi YAML dosyalarını oluşturuyoruz.

    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,
            )
    
  5. Son olarak, görüntüleri ve etiketleri her bir bölünme için ilgili dizine ('train' veya 'val') kopyalayın.

    • NOT: Kodun bu kısmı için gereken süre, veri kümenizin boyutuna ve sistem donanımınıza bağlı olarak değişecektir.
    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)
    

Kayıtları Kaydet (İsteğe Bağlı)

İsteğe bağlı olarak, K-Fold bölme ve etiket dağıtım DataFrame'lerinin kayıtlarını ileride başvurmak üzere CSV dosyaları olarak kaydedebilirsiniz.

folds_df.to_csv(save_path / "kfold_datasplit.csv")
fold_lbl_distrb.to_csv(save_path / "kfold_label_distribution.csv")

K-Katlı Veri Bölmeleri kullanarak YOLO 'u eğitin

  1. İlk olarak YOLO modelini yükleyin.

    from ultralytics import YOLO
    
    weights_path = "path/to/weights.pt"
    model = YOLO(weights_path, task="detect")
    
  2. Ardından, eğitimi çalıştırmak için veri kümesi YAML dosyaları üzerinde yineleyin. Sonuçlar şu şekilde belirtilen bir dizine kaydedilecektir project ve name argümanlar. Varsayılan olarak bu dizin 'exp/runs#' şeklindedir ve burada # bir tamsayı dizinidir.

    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
    

Sonuç

Bu kılavuzda, YOLO nesne algılama modelini eğitmek için K-Kat çapraz doğrulama kullanma sürecini inceledik. Farklı katlar arasında dengeli bir sınıf dağılımı sağlayarak veri kümemizi K bölümlerine nasıl ayıracağımızı öğrendik.

Ayrıca, eğitim ve doğrulama setlerimizin yapısı hakkında net bir fikir edinmemizi sağlayan veri bölünmelerini ve bu bölünmelerdeki etiket dağılımlarını görselleştirmek için rapor DataFrames oluşturma prosedürünü de araştırdık.

İsteğe bağlı olarak, kayıtlarımızı ileride başvurmak üzere kaydettik; bu, özellikle büyük ölçekli projelerde veya model performansında sorun giderirken yararlı olabilir.

Son olarak, her bir bölünmeyi bir döngü içinde kullanarak gerçek model eğitimini uyguladık ve eğitim sonuçlarımızı daha fazla analiz ve karşılaştırma için kaydettik.

Bu K-Kat çapraz doğrulama tekniği, elinizdeki verilerden en iyi şekilde yararlanmanın sağlam bir yoludur ve model performansınızın farklı veri alt kümeleri arasında güvenilir ve tutarlı olmasını sağlamaya yardımcı olur. Bu, belirli veri modellerine aşırı uyum sağlama olasılığı daha düşük olan daha genelleştirilebilir ve güvenilir bir modelle sonuçlanır.

Bu kılavuzda YOLO adresini kullanmamıza rağmen, bu adımların çoğunlukla diğer makine öğrenimi modellerine de aktarılabileceğini unutmayın. Bu adımları anlamak, kendi makine öğrenimi projelerinizde çapraz doğrulamayı etkili bir şekilde uygulamanıza olanak tanır. Mutlu kodlamalar!

SSS

K-Kat Çapraz Doğrulama nedir ve nesne algılamada neden yararlıdır?

K-Fold Cross Validation is a technique where the dataset is divided into 'k' subsets (folds) to evaluate model performance more reliably. Each fold serves as both training and validation data. In the context of object detection, using K-Fold Cross Validation helps to ensure your Ultralytics YOLO model's performance is robust and generalizable across different data splits, enhancing its reliability. For detailed instructions on setting up K-Fold Cross Validation with Ultralytics YOLO, refer to K-Fold Cross Validation with Ultralytics.

Ultralytics YOLO adresini kullanarak K-Katlamalı Çapraz Doğrulamayı nasıl uygulayabilirim?

Ultralytics YOLO ile K-Katlamalı Çapraz Doğrulamayı uygulamak için aşağıdaki adımları izlemeniz gerekir:

  1. Ek açıklamaların YOLO algılama biçiminde olduğunu doğrulayın.
  2. Python gibi kütüphaneleri kullanın sklearn, pandasve pyyaml.
  3. Veri kümenizden özellik vektörleri oluşturun.
  4. kullanarak veri kümenizi bölün KFold gelen sklearn.model_selection.
  5. YOLO modelini her bir bölünme üzerinde eğitin.

Kapsamlı bir kılavuz için belgelerimizdeki K-Fold Veri Kümesi Bölme bölümüne bakın.

Nesne algılama için neden Ultralytics YOLO adresini kullanmalıyım?

Ultralytics YOLO offers state-of-the-art, real-time object detection with high accuracy and efficiency. It's versatile, supporting multiple computer vision tasks such as detection, segmentation, and classification. Additionally, it integrates seamlessly with tools like Ultralytics HUB for no-code model training and deployment. For more details, explore the benefits and features on our Ultralytics YOLO page.

Ek açıklamalarımın Ultralytics YOLO için doğru formatta olmasını nasıl sağlayabilirim?

Your annotations should follow the YOLO detection format. Each annotation file must list the object class, alongside its bounding box coordinates in the image. The YOLO format ensures streamlined and standardized data processing for training object detection models. For more information on proper annotation formatting, visit the YOLO detection format guide.

K-Fold Cross Validation'ı Meyve Tespiti dışındaki özel veri kümeleriyle kullanabilir miyim?

Evet, ek açıklamalar YOLO algılama biçiminde olduğu sürece K-Fold Çapraz Doğrulamayı herhangi bir özel veri kümesiyle kullanabilirsiniz. Veri kümesi yollarını ve sınıf etiketlerini özel veri kümenize özgü olanlarla değiştirin. Bu esneklik, herhangi bir nesne algılama projesinin K-Fold Cross Validation kullanarak sağlam model değerlendirmesinden yararlanabilmesini sağlar. Pratik bir örnek için Özellik Vektörleri Oluşturma bölümümüzü inceleyin.

📅 1 yıl önce oluşturuldu ✏️ 12 gün önce güncellendi

Yorumlar