Ultralytics ile K-Fold Çapraz Doğrulama

Giriş

Bu kapsamlı rehber, Ultralytics ekosistemi içinde nesne algılama veri kümeleri için K-Fold Çapraz Doğrulama uygulamasını göstermektedir. Gerekli kurulum, öznitelik vektörleri oluşturma süreci ve K-Fold veri kümesi ayrıştırma işlemini gerçekleştirmek için YOLO algılama formatından ve sklearn, pandas ve PyYAML gibi temel Python kütüphanelerinden yararlanacağız.

K-fold cross validation data splitting

Projeniz ister Fruit Detection veri kümesini isterse özel bir veri kaynağını içersin, bu eğitim makine öğrenimi modellerinizin güvenilirliğini ve sağlamlığını artırmak için K-Fold Çapraz Doğrulama'yı anlamanıza ve uygulamanıza yardımcı olmayı amaçlar. Bu eğitimde k=5 katman kullanıyor olsak da, optimum katman sayısının veri kümenize ve projenizin özelliklerine göre değişebileceğini unutmayın.

Başlayalım.

Kurulum

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

  • Bu rehber, açıklama dosyalarının yerel olarak mevcut olduğunu varsayar.

  • Gösterimimiz için Fruit Detection veri kümesini kullanıyoruz.

    • Bu veri kümesi toplam 8479 görüntü içerir.
    • Aşağıda toplam örnek sayıları listelenen 6 sınıf etiketi içerir.
Sınıf EtiketiÖrnek Sayısı
Apple7049
Grapes7202
Pineapple1613
Orange15549
Banana3536
Watermelon1976
  • Gerekli Python paketleri şunlardır:

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

  1. Projeniz için yeni bir Python sanal ortamı (venv) oluşturun ve etkinleştirin. Kurulum için pip (veya tercih ettiğiniz paket yöneticisini) kullanın:

    • Ultralytics kütüphanesi: pip install -U ultralytics. Alternatif olarak, resmi repo adresini klonlayabilirsiniz.
    • Scikit-learn, pandas ve PyYAML: pip install -U scikit-learn pandas pyyaml.
  2. Açıklamalarınızın YOLO algılama formatında olduğunu doğrulayın.

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

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

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

  2. Veri kümeniz için tüm etiket dosyalarını almaya geçin.

    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 dizinlerini çıkarın.

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

    import pandas as pd
    
    index = [label.stem for label in labels]  # uses base filename as ID (no extension)
    labels_df = pd.DataFrame([], columns=cls_idx, index=index)
  5. Açıklama dosyalarında bulunan her bir sınıf etiketinin örneklerini sayın.

    from collections import Counter
    
    for label in labels:
        lbl_counter = Counter()
    
        with open(label) 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(" ", 1)[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ğıdaki, doldurulmuş DataFrame'in örnek bir görünümüdü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 etiket dosyalarını dizinler, bunların her biri veri kümenizdeki bir görüntüye karşılık gelir ve sütunlar sınıf etiketi dizinlerinize karşılık gelir. Her satır, veri kümenizde bulunan her bir sınıf etiketinin sayısını içeren sözde bir öznitelik vektörünü temsil eder. Bu veri yapısı, K-Fold Çapraz Doğrulama işleminin bir nesne algılama veri kümesine uygulanmasını sağlar.

K-Fold Veri Kümesi Ayrıştırma

  1. Now we will use the KFold class from sklearn.model_selection to generate k splits of the dataset.

    • Önemli:
      • shuffle=True ayarını yapmak, ayrıştırmalarınızda sınıfların rastgele dağıtılmasını sağlar.
      • By setting random_state=M where M is a chosen integer, you can obtain repeatable results.
    import random
    
    from sklearn.model_selection import KFold
    
    random.seed(0)  # for reproducibility
    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. The dataset has now been split into k folds, each having a list of train and val indices. We will construct a DataFrame to display these results more clearly.

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

    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 ayrıştırma için ve sınıflar genelinde makul düzeyde benzer olmasıdır. Ancak bu, veri kümenizin özelliklerine bağlı olacaktır.

  4. Ardından, her ayrıştırma 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
    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 ayrıştırma 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
    
    from tqdm import tqdm
    
    for image, label in tqdm(zip(images, labels), total=len(images), desc="Copying files"):
        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ı Sakla (İsteğe bağlı)

İsteğe bağlı olarak, K-Fold ayrıştırma kayıtlarını ve etiket dağılımı DataFrame'lerini 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-Fold Veri Ayrıştırmalarını Kullanarak YOLO Eğitimi

  1. İlk olarak, YOLO modelini yükleyin.

    from ultralytics import YOLO
    
    weights_path = "path/to/weights.pt"  # use yolo26n.pt for a small model
    model = YOLO(weights_path, task="detect")
  2. Ardından, eğitimi çalıştırmak için veri kümesi YAML dosyaları üzerinde yineleme yapın. Sonuçlar, project ve name argümanları tarafından belirtilen bir dizine kaydedilecektir. Varsayılan olarak bu dizin, # bir tamsayı dizini olmak üzere 'runs/detect/train#' şeklindedir.

    results = {}
    
    # Define your additional arguments here
    batch = 16
    project = "kfold_demo"
    epochs = 100
    
    for k, dataset_yaml in enumerate(ds_yamls):
        model = YOLO(weights_path, task="detect")
        results[k] = model.train(
            data=dataset_yaml, epochs=epochs, batch=batch, project=project, name=f"fold_{k + 1}"
        )  # include any additional train arguments
  3. Ayrıca otomatik veri kümesi ayrıştırma için Ultralytics data.utils.autosplit işlevini de kullanabilirsiniz:

    from ultralytics.data.split import autosplit
    
    # Automatically split dataset into train/val/test
    autosplit(path="path/to/images", weights=(0.8, 0.2, 0.0), annotated_only=True)

Sonuç

Bu rehberde, YOLO nesne algılama modelini eğitmek için K-Fold çapraz doğrulama kullanma sürecini inceledik. Veri kümemizi K bölüme ayırmayı ve farklı katmanlar genelinde dengeli bir sınıf dağılımı sağlamayı öğrendik.

Ayrıca, veri ayrıştırmalarını ve bu ayrıştırmalardaki etiket dağılımlarını görselleştirmek için rapor DataFrame'leri oluşturma prosedürünü inceledik; bu, eğitim ve doğrulama kümelerimizin yapısına net bir bakış sağladı.

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

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

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

Bu rehberde YOLO kullansak da, bu adımların çoğunlukla diğer makine öğrenimi modellerine aktarılabilir olduğunu unutmayın. Bu adımları anlamak, çapraz doğrulamayı kendi makine öğrenimi projelerinizde etkili bir şekilde uygulamanıza olanak tanır.

SSS

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

K-Fold Çapraz Doğrulama, model performansını daha güvenilir bir şekilde değerlendirmek için veri kümesinin 'k' alt kümeye (katmana) bölündüğü bir tekniktir. Her katman hem eğitim hem de doğrulama verisi olarak hizmet eder. Nesne algılama bağlamında, K-Fold Çapraz Doğrulama kullanmak, Ultralytics YOLO modelinizin performansının farklı veri ayrıştırmalarında sağlam ve genelleştirilebilir olmasını sağlamaya yardımcı olarak güvenilirliğini artırır. Ultralytics YOLO ile K-Fold Çapraz Doğrulama kurulumu hakkında ayrıntılı talimatlar için Ultralytics ile K-Fold Çapraz Doğrulama bölümüne bakın.

Ultralytics YOLO kullanarak K-Fold Çapraz Doğrulama'yı nasıl uygularım?

Ultralytics YOLO ile K-Fold Çapraz Doğrulama'yı uygulamak için şu adımları izlemeniz gerekir:

  1. Açıklamaların YOLO algılama formatında olduğunu doğrulayın.
  2. sklearn, pandas ve pyyaml gibi Python kütüphanelerini kullanın.
  3. Veri kümenizden öznitelik vektörleri oluşturun.
  4. Split your dataset using KFold from sklearn.model_selection.
  5. YOLO modelini her ayrıştırmada eğitin.

Kapsamlı bir rehber için belgelerimizdeki K-Fold Veri Kümesi Ayrıştırma bölümüne bakın.

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

Ultralytics YOLO, yüksek doğruluk ve verimlilik ile son teknoloji, gerçek zamanlı nesne algılama sunar. Algılama, segmentasyon ve sınıflandırma gibi birçok bilgisayarlı görü görevini destekleyen çok yönlü bir araçtır. Ayrıca, kodsuz model eğitimi ve dağıtımı için Ultralytics Platform gibi araçlarla sorunsuz bir şekilde entegre olur. Daha fazla ayrıntı için Ultralytics YOLO sayfamızdaki avantajları ve özellikleri keşfedin.

Açıklamalarımın Ultralytics YOLO için doğru formatta olduğundan nasıl emin olabilirim?

Açıklamalarınız YOLO algılama formatını izlemelidir. Her açıklama dosyası, görüntüdeki sınırlayıcı kutu koordinatlarıyla birlikte nesne sınıfını listelemelidir. YOLO formatı, nesne algılama modellerini eğitmek için modern ve standartlaştırılmış veri işleme sağlar. Doğru açıklama biçimlendirmesi hakkında daha fazla bilgi için YOLO algılama formatı rehberini ziyaret edin.

Fruit Detection dışındaki özel veri kümeleriyle K-Fold Çapraz Doğrulama kullanabilir miyim?

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

Yorumlar