Bỏ để qua phần nội dung

Xác thực chéo K-Fold với Ultralytics

Giới thiệu

Hướng dẫn toàn diện này minh họa việc triển khai Xác thực chéo K-Fold cho các bộ dữ liệu phát hiện đối tượng trong Ultralytics hệ sinh thái. Chúng tôi sẽ tận dụng YOLO Định dạng phát hiện và khóa Python các thư viện như sklearn, gấu trúc và PyYaml để hướng dẫn bạn thiết lập cần thiết, quy trình tạo vectơ tính năng và thực thi phân tách tập dữ liệu K-Fold.

Tổng quan về xác thực chéo K-Fold

Cho dù dự án của bạn liên quan đến tập dữ liệu Phát hiện trái cây hay nguồn dữ liệu tùy chỉnh, hướng dẫn này nhằm mục đích giúp bạn hiểu và áp dụng Xác thực chéo K-Fold để tăng cường độ tin cậy và mạnh mẽ của các mô hình học máy của bạn. Trong khi chúng tôi đang áp dụng k=5 Nếp gấp Đối với hướng dẫn này, hãy nhớ rằng số lần gấp tối ưu có thể thay đổi tùy thuộc vào tập dữ liệu của bạn và chi tiết cụ thể của dự án của bạn.

Không cần quảng cáo thêm, chúng ta hãy đi sâu vào!

Thiết lập

  • Chú thích của bạn phải nằm trong YOLO định dạng phát hiện.

  • Hướng dẫn này giả định rằng các tệp chú thích có sẵn cục bộ.

  • Để trình diễn, chúng tôi sử dụng bộ dữ liệu Phát hiện trái cây .

    • Tập dữ liệu này chứa tổng cộng 8479 hình ảnh.
    • Nó bao gồm 6 nhãn lớp, mỗi nhãn có tổng số phiên bản được liệt kê bên dưới.
Nhãn lớp học Số lượng phiên bản
Quả táo 7049
Nho 7202
Dứa 1613
Cam 15549
Chuối 3536
Dưa hấu 1976
  • Cần thiết Python Các gói bao gồm:

    • ultralytics
    • sklearn
    • pandas
    • pyyaml
  • Hướng dẫn này hoạt động với k=5 Gấp. Tuy nhiên, bạn nên xác định số lần gấp tốt nhất cho tập dữ liệu cụ thể của mình.

  • Bắt đầu một cái mới Python môi trường ảo (venv) cho dự án của bạn và kích hoạt nó. Dùng pip (hoặc trình quản lý gói ưa thích của bạn) để cài đặt:

    • Các Ultralytics thư viện: pip install -U ultralytics. Ngoài ra, bạn có thể sao chép chính thức Repo.
    • Scikit-learn, gấu trúc và PyYAML: pip install -U scikit-learn pandas pyyaml.
  • Xác minh rằng chú thích của bạn nằm trong YOLO định dạng phát hiện.

    • Đối với hướng dẫn này, tất cả các tệp chú thích được tìm thấy trong Fruit-Detection/labels thư mục.

Tạo vectơ tính năng cho tập dữ liệu phát hiện đối tượng

  1. Bắt đầu bằng cách tạo mới example.py Python tập tin cho các bước dưới đây.

  2. Tiến hành truy xuất tất cả các tệp nhãn cho tập dữ liệu của bạn.

    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. Bây giờ, hãy đọc nội dung của tệp YAML tập dữ liệu và trích xuất các chỉ số của nhãn lớp.

    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. Khởi tạo một trống pandas Khung dữ liệu.

    import pandas as pd
    
    indx = [l.stem for l in labels]  # uses base filename as ID (no extension)
    labels_df = pd.DataFrame([], columns=cls_idx, index=indx)
    
  5. Đếm các trường hợp của mỗi nhãn lớp có trong các tệp chú thích.

    from collections import Counter
    
    for label in labels:
        lbl_counter = Counter()
    
        with open(label, "r") as lf:
            lines = lf.readlines()
    
        for l in lines:
            # classes for YOLO label uses integer at first position of each line
            lbl_counter[int(l.split(" ")[0])] += 1
    
        labels_df.loc[label.stem] = lbl_counter
    
    labels_df = labels_df.fillna(0.0)  # replace `nan` values with `0.0`
    
  6. Sau đây là dạng xem mẫu của DataFrame được điền:

                                                           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
    

Các hàng lập chỉ mục các tệp nhãn, mỗi tệp tương ứng với một hình ảnh trong tập dữ liệu của bạn và các cột tương ứng với các chỉ mục nhãn lớp của bạn. Mỗi hàng đại diện cho một vectơ tính năng giả, với số lượng của mỗi nhãn lớp có trong tập dữ liệu của bạn. Cấu trúc dữ liệu này cho phép áp dụng Xác thực chéo K-Fold cho tập dữ liệu phát hiện đối tượng.

Phân tách tập dữ liệu K-Fold

  1. Bây giờ chúng ta sẽ sử dụng KFold lớp học từ sklearn.model_selection để tạo k phân tách tập dữ liệu.

    • Quan trọng:
      • Khung cảnh shuffle=True Đảm bảo phân phối ngẫu nhiên các lớp trong phần tách của bạn.
      • Bằng cách cài đặt random_state=M đâu M là một số nguyên đã chọn, bạn có thể thu được kết quả lặp lại.
    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. Tập dữ liệu hiện đã được chia thành k nếp gấp, mỗi nếp gấp có một danh sách trainval chỉ số. Chúng ta sẽ xây dựng một DataFrame để hiển thị các kết quả này rõ ràng hơn.

    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. Bây giờ chúng ta sẽ tính toán phân bố nhãn lớp cho mỗi lần gấp theo tỷ lệ của các lớp có trong val cho những người có mặt trong 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
    

    Kịch bản lý tưởng là tất cả các tỷ lệ lớp học phải giống nhau một cách hợp lý cho mỗi lần phân chia và giữa các lớp. Tuy nhiên, điều này sẽ phụ thuộc vào các chi tiết cụ thể của tập dữ liệu của bạn.

  4. Tiếp theo, chúng tôi tạo các thư mục và tệp YAML tập dữ liệu cho mỗi lần tách.

    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. Cuối cùng, sao chép hình ảnh và nhãn vào thư mục tương ứng ('train' hoặc 'val') cho mỗi lần tách.

    • GHI: Thời gian cần thiết cho phần mã này sẽ thay đổi dựa trên kích thước tập dữ liệu và phần cứng hệ thống của bạn.
    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)
    

Lưu bản ghi (Tùy chọn)

Theo tùy chọn, bạn có thể lưu các bản ghi của DataFrames phân tách và phân phối nhãn K-Fold dưới dạng tệp CSV để tham khảo trong tương lai.

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

Xe lửa YOLO sử dụng Chia tách dữ liệu K-Fold

  1. Đầu tiên, tải YOLO mẫu.

    from ultralytics import YOLO
    
    weights_path = "path/to/weights.pt"
    model = YOLO(weights_path, task="detect")
    
  2. Tiếp theo, lặp lại các tệp YAML tập dữ liệu để chạy đào tạo. Kết quả sẽ được lưu vào một thư mục được chỉ định bởi projectname lập luận. Theo mặc định, thư mục này là 'exp/runs#' trong đó # là chỉ mục số nguyên.

    results = {}
    
    # Define your additional arguments here
    batch = 16
    project = "kfold_demo"
    epochs = 100
    
    for k in range(ksplit):
        dataset_yaml = ds_yamls[k]
        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
    

Kết thúc

Trong hướng dẫn này, chúng tôi đã khám phá quá trình sử dụng xác thực chéo K-Fold để đào tạo YOLO Mô hình phát hiện đối tượng. Chúng tôi đã học cách chia tập dữ liệu của mình thành các phân vùng K, đảm bảo phân phối lớp cân bằng trên các nếp gấp khác nhau.

Chúng tôi cũng đã khám phá quy trình tạo DataFrames báo cáo để trực quan hóa việc phân tách dữ liệu và phân phối nhãn trên các phần tách này, cung cấp cho chúng tôi cái nhìn sâu sắc rõ ràng về cấu trúc của các bộ đào tạo và xác thực của chúng tôi.

Theo tùy chọn, chúng tôi đã lưu các bản ghi của mình để tham khảo trong tương lai, điều này có thể đặc biệt hữu ích trong các dự án quy mô lớn hoặc khi khắc phục sự cố hiệu suất mô hình.

Cuối cùng, chúng tôi đã thực hiện đào tạo mô hình thực tế bằng cách sử dụng mỗi lần chia trong một vòng lặp, lưu kết quả đào tạo của chúng tôi để phân tích và so sánh thêm.

Kỹ thuật xác thực chéo K-Fold này là một cách mạnh mẽ để tận dụng tối đa dữ liệu có sẵn của bạn và nó giúp đảm bảo rằng hiệu suất mô hình của bạn đáng tin cậy và nhất quán trên các tập hợp con dữ liệu khác nhau. Điều này dẫn đến một mô hình tổng quát và đáng tin cậy hơn, ít có khả năng phù hợp với các mẫu dữ liệu cụ thể.

Hãy nhớ rằng mặc dù chúng tôi đã sử dụng YOLO Trong hướng dẫn này, các bước này hầu hết có thể chuyển sang các mô hình học máy khác. Hiểu các bước này cho phép bạn áp dụng xác thực chéo một cách hiệu quả trong các dự án học máy của riêng bạn. Mã hóa vui vẻ!

FAQ

Xác thực chéo K-Fold là gì và tại sao nó lại hữu ích trong việc phát hiện đối tượng?

Xác thực chéo K-Fold là một kỹ thuật trong đó tập dữ liệu được chia thành các tập hợp con 'k' (nếp gấp) để đánh giá hiệu suất mô hình đáng tin cậy hơn. Mỗi lần gấp đóng vai trò là cả dữ liệu đào tạo và xác nhận. Trong bối cảnh phát hiện đối tượng, sử dụng Xác thực chéo K-Fold giúp đảm bảo Ultralytics YOLO Hiệu suất của mô hình mạnh mẽ và có thể khái quát hóa trên các phân tách dữ liệu khác nhau, nâng cao độ tin cậy của nó. Để được hướng dẫn chi tiết về cách thiết lập Xác thực chéo K-Fold với Ultralytics YOLO, tham khảo Xác thực chéo K-Fold với Ultralytics.

Làm cách nào để triển khai Xác thực chéo K-Fold bằng cách sử dụng Ultralytics YOLO?

Để triển khai Xác thực chéo K-Fold với Ultralytics YOLO, bạn cần làm theo các bước sau:

  1. Xác minh chú thích nằm trong YOLO định dạng phát hiện.
  2. Dùng Python Các thư viện như sklearn, pandaspyyaml.
  3. Tạo vectơ tính năng từ tập dữ liệu của bạn.
  4. Chia nhỏ tập dữ liệu của bạn bằng cách sử dụng KFold từ sklearn.model_selection.
  5. Đào tạo YOLO mô hình trên mỗi lần tách.

Để có hướng dẫn toàn diện, hãy xem phần Phân tách tập dữ liệu K-Fold trong tài liệu của chúng tôi.

Tại sao tôi nên sử dụng Ultralytics YOLO để phát hiện đối tượng?

Ultralytics YOLO Cung cấp khả năng phát hiện đối tượng hiện đại, theo thời gian thực với độ chính xác và hiệu quả cao. Nó rất linh hoạt, hỗ trợ nhiều tác vụ thị giác máy tính như phát hiện, phân đoạn và phân loại. Ngoài ra, nó tích hợp hoàn hảo với các công cụ như Ultralytics HUB để đào tạo và triển khai mô hình không mã. Để biết thêm chi tiết, hãy khám phá các lợi ích và tính năng trên Ultralytics YOLO trang.

Làm cách nào để đảm bảo chú thích của tôi ở định dạng chính xác cho Ultralytics YOLO?

Chú thích của bạn phải tuân theo YOLO định dạng phát hiện. Mỗi tệp chú thích phải liệt kê lớp đối tượng, cùng với tọa độ hộp giới hạn của nó trong hình ảnh. Các YOLO Định dạng đảm bảo xử lý dữ liệu hợp lý và chuẩn hóa cho các mô hình phát hiện đối tượng đào tạo. Để biết thêm thông tin về định dạng chú thích thích hợp, hãy truy cập YOLO Hướng dẫn định dạng phát hiện.

Tôi có thể sử dụng Xác thực chéo K-Fold với các bộ dữ liệu tùy chỉnh khác ngoài Phát hiện trái cây không?

Có, bạn có thể sử dụng Xác thực chéo K-Fold với bất kỳ tập dữ liệu tùy chỉnh nào miễn là các chú thích nằm trong YOLO định dạng phát hiện. Thay thế đường dẫn tập dữ liệu và nhãn lớp bằng những đường dẫn cụ thể cho tập dữ liệu tùy chỉnh của bạn. Tính linh hoạt này đảm bảo rằng bất kỳ dự án phát hiện đối tượng nào cũng có thể hưởng lợi từ việc đánh giá mô hình mạnh mẽ bằng cách sử dụng Xác thực chéo K-Fold. Để có ví dụ thực tế, hãy xem lại phần Tạo vectơ tính năng của chúng tôi.



Đã tạo 2023-11-12, Cập nhật 2024-07-05
Tác giả: glenn-jocher (10), IvorZhu331 (1), Burhan-Q (1)

Ý kiến