Перекрестная валидация по методу K-Fold с Ultralytics
Введение
Это подробное руководство иллюстрирует реализацию K-Fold Cross Validation для наборов данных обнаружения объектов в экосистеме Ultralytics . Мы используем формат обнаружения YOLO и ключевые библиотеки Python , такие как sklearn, pandas и PyYaml, чтобы провести вас через необходимую настройку, процесс генерации векторов признаков и выполнение K-Fold разбиения набора данных.
Независимо от того, используется ли в вашем проекте набор данных Fruit Detection или пользовательский источник данных, этот учебник поможет вам понять и применить перекрестную валидацию K-Fold для повышения надежности и прочности ваших исследований. машинное обучение модели. Пока мы применяем k=5
в этом руководстве, имейте в виду, что оптимальное количество складок может варьироваться в зависимости от набора данных и особенностей вашего проекта.
Без лишних слов, давайте погрузимся!
Настройка
-
Ваши аннотации должны быть в форматеYOLO detection.
-
В данном руководстве предполагается, что файлы аннотаций доступны локально.
-
Для демонстрации мы используем набор данных Fruit Detection.
- Этот набор данных содержит в общей сложности 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
.
- Библиотека Ultralytics :
-
Убедитесь, что ваши аннотации имеют формат обнаруженияYOLO .
- В этом учебнике все файлы аннотаций находятся в папке
Fruit-Detection/labels
каталог.
- В этом учебнике все файлы аннотаций находятся в папке
Генерация векторов признаков для набора данных обнаружения объектов
-
Начните с создания нового
example.py
Python файл для выполнения следующих шагов. -
Приступайте к получению всех файлов меток для вашего набора данных.
-
Теперь прочитайте содержимое YAML-файла набора данных и извлеките индексы меток классов.
-
Инициализируйте пустой
pandas
DataFrame. -
Подсчитайте количество экземпляров каждого класса-метки, присутствующих в файлах аннотаций.
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(" ")[0])] += 1 labels_df.loc[label.stem] = lbl_counter labels_df = labels_df.fillna(0.0) # replace `nan` values with `0.0`
-
Ниже приведен пример представления заполненного 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 Cross Validation к набору данных для обнаружения объектов.
Разбиение набора данных по методу K-Fold
-
Теперь мы будем использовать
KFold
класс изsklearn.model_selection
генерироватьk
разбиение набора данных на части.- Важно:
- Настройка
shuffle=True
обеспечивает случайное распределение классов в ваших сплитах. - По настройке
random_state=M
гдеM
является выбранным целым числом, вы можете получить воспроизводимые результаты.
- Настройка
- Важно:
-
Теперь набор данных разделен на
k
складки, каждая из которых имеет списокtrain
иval
индексы. Для более наглядного отображения этих результатов мы построим DataFrame. -
Теперь мы вычислим распределение меток классов для каждой складки как отношение классов, присутствующих в
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
Идеальный сценарий заключается в том, чтобы соотношение всех классов было достаточно близким для каждого разбиения и для всех классов. Однако это зависит от специфики вашего набора данных.
-
Далее мы создаем каталоги и 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, )
-
Наконец, скопируйте изображения и метки в соответствующую директорию ("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 сплита и распределения этикеток DataFrames в виде CSV-файлов для дальнейшего использования.
folds_df.to_csv(save_path / "kfold_datasplit.csv")
fold_lbl_distrb.to_csv(save_path / "kfold_label_distribution.csv")
Обучение YOLO с использованием K-кратных разбиений данных
-
Сначала загрузите модель YOLO .
-
Затем выполните итерации по 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
-
Вы также можете использовать функцию Ultralytics data.utils.autosplit для автоматического разделения наборов данных:
Заключение
В этом руководстве мы рассмотрели процесс использования перекрестной валидации K-Fold для обучения модели обнаружения объектов YOLO . Мы узнали, как разделить наш набор данных на K разделов, обеспечив сбалансированное распределение классов по разным сложениям.
Мы также изучили процедуру создания отчетов DataFrames для визуализации разбиения данных и распределений меток по этим разбиениям, что позволило нам получить четкое представление о структуре обучающих и проверочных наборов.
По желанию мы сохраняли наши записи для дальнейшего использования, что может быть особенно полезно в масштабных проектах или при устранении неполадок в работе модели.
Наконец, мы реализовали фактическое обучение модели, используя каждый сплит в цикле, сохраняя результаты обучения для дальнейшего анализа и сравнения.
Техника перекрестной проверки K-Fold - это надежный способ извлечь максимум пользы из имеющихся данных, который позволяет обеспечить надежность и согласованность работы модели в различных подмножествах данных. В результате получается более обобщенная и надежная модель, которая с меньшей вероятностью будет подстраиваться под конкретные модели данных.
Помните, что хотя в данном руководстве мы использовали YOLO , эти шаги в основном применимы и к другим моделям машинного обучения. Понимание этих шагов позволит вам эффективно применять кросс-валидацию в своих собственных проектах машинного обучения. Счастливого кодинга!
ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ
Что такое K-Fold Cross Validation и почему он полезен при обнаружении объектов?
K-Fold Cross Validation - это метод, при котором набор данных делится на "k" подмножеств (складок) для более надежной оценки эффективности модели. Каждая складка служит как обучающими, так и проверочными данными. В контексте обнаружения объектов использование K-Fold Cross Validation помогает гарантировать, что производительность вашей модели Ultralytics YOLO будет устойчивой и обобщаемой при различных разбиениях данных, что повышает ее надежность. Подробные инструкции по настройке K-Fold Cross Validation с Ultralytics YOLO , см. в разделе K-Fold Cross Validation с Ultralytics.
Как реализовать перекрестную проверку K-Fold с помощью Ultralytics YOLO ?
Чтобы реализовать перекрестную проверку K-Fold с помощью Ultralytics YOLO , необходимо выполнить следующие шаги:
- Убедитесь, что аннотации представлены в формате обнаруженияYOLO .
- Используйте библиотеки Python , такие как
sklearn
,pandas
, иpyyaml
. - Создайте векторы признаков из вашего набора данных.
- Разделите набор данных с помощью
KFold
с сайтаsklearn.model_selection
. - Обучите модель YOLO на каждом сплите.
Полное руководство см. в разделе K-Fold Dataset Split в нашей документации.
Почему для обнаружения объектов следует использовать 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. Для практического примера ознакомьтесь с разделом "Генерация векторов признаков ".