تخطي إلى المحتوى

التحقق المتبادل K-Fold مع Ultralytics

مقدمة

يوضح هذا الدليل الشامل تنفيذ التحقق المتقاطع K-Fold لمجموعات بيانات الكشف عن الكائنات داخل نظام Ultralytics البيئي. سنستفيد من تنسيق الكشف YOLO ومكتبات Python الرئيسية مثل sklearn و pandas و PyYaml لإرشادك خلال الإعداد الضروري وعملية إنشاء متجهات الميزات وتنفيذ تقسيم مجموعة بيانات K-Fold.

نظرة عامة على التحقق المتبادل K-Fold

سواء كان مشروعك يتضمن مجموعة بيانات الكشف عن الفاكهة Fruit Detection dataset أو مصدر بيانات مخصص، تهدف هذه الدورة التعليمية إلى مساعدتك على فهم وتطبيق التحقق المتبادل K-Fold لتعزيز موثوقية وقوة التعلم الآلي النماذج. بينما نقوم بتطبيق k=5 طيات لهذا البرنامج التعليمي، ضع في اعتبارك أن العدد الأمثل للطيات يمكن أن يختلف اعتمادًا على مجموعة البيانات الخاصة بك وخصوصيات مشروعك.

دون مزيد من اللغط، هيا بنا نتعمق!

الإعداد

  • يجب أن تكون التعليقات التوضيحية الخاصة بك بتنسيق YOLO للكشف عن الكائنات.

  • يفترض هذا الدليل أن ملفات التعليقات التوضيحية متاحة محليًا.

  • لأغراض العرض التوضيحي، سنستخدم مجموعة بيانات الكشف عن الفاكهة.

    • تحتوي مجموعة البيانات هذه على إجمالي 8479 صورة.
    • يتضمن 6 تسميات فئات، مع سرد إجمالي عدد الحالات لكل منها أدناه.
تسمية الفئة عدد المثيلات
Apple 7049
عنب 7202
أناناس 1613
برتقالي 15549
موز 3536
بطيخ 1976
  • تتضمن حزم Python الضرورية:

    • ultralytics
    • sklearn
    • pandas
    • pyyaml
  • يعمل هذا البرنامج التعليمي مع k=5 طيات. ومع ذلك، يجب عليك تحديد أفضل عدد من الطيات لمجموعة البيانات المحددة الخاصة بك.

  • بدء بيئة افتراضية جديدة لـ python (venv) لمشروعك وقم بتنشيطه. استخدم pip (أو مدير الحزم المفضل لديك) للتثبيت:

    • مكتبة Ultralytics: pip install -U ultralytics. بدلاً من ذلك، يمكنك استنساخ النسخة الرسمية. مستودع.
    • Scikit-learn و pandas و PyYAML: pip install -U scikit-learn pandas pyyaml.
  • تحقق من أن التعليقات التوضيحية الخاصة بك بتنسيق YOLO detection format.

    • في هذا البرنامج التعليمي، توجد جميع ملفات التعليقات التوضيحية في. Fruit-Detection/labels دليل.

إنشاء متجهات الميزات لمجموعة بيانات كشف الكائنات

  1. ابدأ بإنشاء جديد example.py ملف Python للخطوات أدناه.

  2. تابع لاسترداد جميع ملفات التصنيف لمجموعة البيانات الخاصة بك.

    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. الآن، اقرأ محتويات ملف YAML الخاص بمجموعة البيانات واستخرج فهارس تسميات الفئات.

    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. تهيئة فارغة pandas DataFrame.

    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. عدد مثيلات كل علامة تصنيف موجودة في ملفات الشرح.

    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. فيما يلي عرض نموذجي لـ DataFrame المعبأ:

                                                           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
    

تفهرس الصفوف ملفات التصنيف، ويتوافق كل منها مع صورة في مجموعة البيانات الخاصة بك، وتتوافق الأعمدة مع مؤشرات تصنيف الفئات الخاصة بك. يمثل كل صف متجه ميزة زائف، مع عدد كل تصنيف فئة موجود في مجموعة البيانات الخاصة بك. يتيح هيكل البيانات هذا تطبيق التحقق المتبادل K-Fold على مجموعة بيانات الكشف عن الكائنات.

تقسيم مجموعة بيانات K-Fold

  1. الآن سوف نستخدم KFold فئة من sklearn.model_selection لإنشاء k تقسيمات مجموعة البيانات.

    • هام:
      • إعداد shuffle=True يضمن توزيعًا عشوائيًا للفئات في التقسيمات الخاصة بك.
      • عن طريق تعيين random_state=M حيث M هو عدد صحيح تم اختياره، يمكنك الحصول على نتائج قابلة للتكرار.
    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. تم الآن تقسيم مجموعة البيانات إلى k طيات، لكل منها قائمة بـ train و val المؤشرات. سنقوم بإنشاء DataFrame لعرض هذه النتائج بشكل أكثر وضوحًا.

    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. الآن سنقوم بحساب توزيع تسميات الفئات لكل طية كنسبة للفئات الموجودة في val لأولئك الحاضرين في 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
    

    السيناريو المثالي هو أن تكون جميع نسب الفئات متشابهة إلى حد معقول لكل تقسيم وعبر الفئات. ومع ذلك، سيخضع هذا لخصوصيات مجموعة البيانات الخاصة بك.

  4. بعد ذلك، نقوم بإنشاء الدلائل وملفات YAML لمجموعة البيانات لكل تقسيم.

    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. أخيرًا، انسخ الصور والتسميات إلى الدليل الخاص بكل منها ('train' أو 'val') لكل تقسيم.

    • ملاحظة: سيختلف الوقت المطلوب لهذا الجزء من التعليمات البرمجية بناءً على حجم مجموعة البيانات الخاصة بك وأجهزة النظام لديك.
    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)
    

حفظ السجلات (اختياري)

اختياريًا، يمكنك حفظ سجلات تقسيم K-Fold وجداول بيانات توزيع التسميات كملفات CSV للرجوع إليها في المستقبل.

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

تدريب YOLO باستخدام تقسيم البيانات K-Fold

  1. أولاً، قم بتحميل نموذج YOLO.

    from ultralytics import YOLO
    
    weights_path = "path/to/weights.pt"  # use yolo11n.pt for a small model
    model = YOLO(weights_path, task="detect")
    
  2. بعد ذلك، قم بالتكرار على ملفات YAML الخاصة بمجموعة البيانات لتشغيل التدريب. سيتم حفظ النتائج في دليل تحدده project و name الوسائط. بشكل افتراضي، هذا الدليل هو 'runs/detect/train#' حيث # هو فهرس عدد صحيح.

    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. يمكنك أيضًا استخدام الدالة Ultralytics data.utils.autosplit لتقسيم مجموعة البيانات تلقائيًا:

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

الخلاصة

في هذا الدليل، استكشفنا عملية استخدام التحقق المتبادل K-Fold لتدريب نموذج الكشف عن الكائنات YOLO. لقد تعلمنا كيفية تقسيم مجموعة البيانات الخاصة بنا إلى K من الأقسام، مما يضمن توزيعًا متوازنًا للفئات عبر الطيات المختلفة.

لقد استكشفنا أيضًا إجراء إنشاء DataFrames للتقرير لتصور تقسيمات البيانات وتوزيعات التسميات عبر هذه التقسيمات، مما يوفر لنا نظرة ثاقبة واضحة على هيكل مجموعات التدريب والتحقق الخاصة بنا.

اختياريًا، قمنا بحفظ سجلاتنا للرجوع إليها في المستقبل، والتي يمكن أن تكون مفيدة بشكل خاص في المشاريع واسعة النطاق أو عند استكشاف أداء النموذج وإصلاحه.

أخيرًا، قمنا بتنفيذ التدريب الفعلي للنموذج باستخدام كل جزء في حلقة، وحفظ نتائج التدريب الخاصة بنا لمزيد من التحليل والمقارنة.

تعتبر هذه التقنية الخاصة بالتحقق المتبادل K-Fold طريقة قوية لتحقيق أقصى استفادة من البيانات المتاحة لديك، وتساعد على ضمان أن أداء النموذج الخاص بك موثوق به ومتسق عبر مجموعات فرعية مختلفة من البيانات. ينتج عن هذا نموذج أكثر قابلية للتعميم وموثوقية وأقل عرضة للتجاوز لأنماط بيانات معينة.

تذكر أنه على الرغم من أننا استخدمنا YOLO في هذا الدليل، إلا أن هذه الخطوات قابلة للتحويل في الغالب إلى نماذج تعلم آلي أخرى. إن فهم هذه الخطوات يسمح لك بتطبيق التحقق المتبادل بشكل فعال في مشاريع التعلم الآلي الخاصة بك. ترميز سعيد!

الأسئلة الشائعة

ما هو التحقق المتبادل K-Fold ولماذا هو مفيد في الكشف عن الأجسام؟

التحقق المتبادل K-Fold هو أسلوب يتم فيه تقسيم مجموعة البيانات إلى 'k' من المجموعات الفرعية (الطيات) لتقييم أداء النموذج بشكل أكثر موثوقية. تعمل كل طية كبيانات تدريب و تحقق. في سياق الكشف عن الكائنات، يساعد استخدام التحقق المتبادل K-Fold على ضمان أن أداء نموذج Ultralytics YOLO الخاص بك قوي وقابل للتعميم عبر تقسيمات بيانات مختلفة، مما يعزز موثوقيته. للحصول على إرشادات مفصلة حول إعداد التحقق المتبادل K-Fold مع Ultralytics YOLO، راجع التحقق المتبادل K-Fold مع Ultralytics.

كيف يمكنني تطبيق التحقق المتقاطع K-Fold باستخدام Ultralytics YOLO؟

لتنفيذ التحقق المتبادل K-Fold مع Ultralytics YOLO، تحتاج إلى اتباع الخطوات التالية:

  1. تحقق من أن التعليقات التوضيحية بتنسيق YOLO detection format.
  2. استخدم مكتبات Python مثل sklearn, pandas، و pyyaml.
  3. إنشاء متجهات الميزات من مجموعة البيانات الخاصة بك.
  4. قسّم مجموعة البيانات الخاصة بك باستخدام KFold من sklearn.model_selection.
  5. تدريب نموذج YOLO على كل تقسيم.

للحصول على دليل شامل، راجع قسم تقسيم مجموعة بيانات K-Fold في وثائقنا.

لماذا يجب عليّ استخدام Ultralytics YOLO لاكتشاف الأجسام؟

توفر Ultralytics YOLO أحدث التقنيات في الكشف عن الأجسام في الوقت الفعلي مع دقة وكفاءة عالية. إنها متعددة الاستخدامات، وتدعم مهام الرؤية الحاسوبية المتعددة مثل الكشف والتقسيم والتصنيف. بالإضافة إلى ذلك، تتكامل بسلاسة مع أدوات مثل Ultralytics HUB لتدريب النماذج ونشرها بدون تعليمات برمجية. لمزيد من التفاصيل، استكشف المزايا والميزات في صفحة Ultralytics YOLO الخاصة بنا.

كيف يمكنني التأكد من أن الترميزات الخاصة بي بالتنسيق الصحيح لـ Ultralytics YOLO؟

يجب أن تتبع التعليقات التوضيحية الخاصة بك تنسيق YOLO للكشف عن الكائنات. يجب أن يسرد كل ملف تعليق توضيحي فئة الكائن، جنبًا إلى جنب مع إحداثيات المربع المحيط به في الصورة. يضمن تنسيق YOLO معالجة بيانات مبسطة وموحدة لتدريب نماذج الكشف عن الكائنات. لمزيد من المعلومات حول تنسيق التعليقات التوضيحية المناسب، تفضل بزيارة دليل تنسيق YOLO للكشف عن الكائنات.

هل يمكنني استخدام K-Fold Cross Validation مع مجموعات بيانات مخصصة أخرى غير Fruit Detection؟

نعم، يمكنك استخدام K-Fold Cross Validation مع أي مجموعة بيانات مخصصة طالما أن التعليقات التوضيحية بتنسيق الكشف عن YOLO. استبدل مسارات مجموعة البيانات وتسميات الفئات بتلك الخاصة بمجموعة البيانات المخصصة الخاصة بك. تضمن هذه المرونة إمكانية استفادة أي مشروع للكشف عن الكائنات من تقييم النموذج القوي باستخدام K-Fold Cross Validation. للحصول على مثال عملي، راجع قسم إنشاء متجهات الميزات.



📅 أُنشئ منذ سنة واحدة ✏️ تم التحديث منذ 23 يومًا

تعليقات