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.
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ùngpip
(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
.
- Các Ultralytics thư viện:
-
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.
- Đố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
Tạo vectơ tính năng cho tập dữ liệu phát hiện đối tượng
-
Bắt đầu bằng cách tạo mới Python tệp và nhập các thư viện cần thiết.
-
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.
-
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.
-
Khởi tạo một trống
pandas
Khung dữ liệu. -
Đếm các trường hợp của mỗi nhãn lớp có trong các tệp chú thích.
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`
-
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
-
Bây giờ chúng ta sẽ sử dụng
KFold
lớp học từsklearn.model_selection
để tạok
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
đâuM
là một số nguyên đã chọn, bạn có thể thu được kết quả lặp lại.
- Khung cảnh
- Quan trọng:
-
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áchtrain
vàval
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. -
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 trongtrain
.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.
-
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.
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)
-
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.
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
-
Đầu tiên, tải YOLO mẫu.
-
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
project
vàname
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ẻ!