Как сбалансировать набор данных, извлеченный с помощью image_dataset_from_directory

Вопрос или проблема

Я новичок в tensorflow, и сейчас я пытаюсь найти лучший способ сбалансировать классы в наборе данных, который я загружаю с помощью image_dataset_from_directory. Но я не нашёл способ это сделать. Я видел из разных источников, что SMOTE может помочь, но я не смог найти способ заставить его работать с image_dataset_from_directory.

Набор данных содержит 4 разных класса, один из которых сильно несбалансирован. Ниже показан способ, которым я извлекаю набор данных. Набор данных, который я использую, находится на Kaggle (https://www.kaggle.com/datasets/tourist55/alzheimers-dataset-4-class-of-images/data).

from keras.utils import image_dataset_from_directory as IDFD
IMAGE_SIZE = (176, 208)
BATCH_SIZE = 32
BASE_DIR = '/content/drive/' #это путь к папке на диске, где сохранены изображения

train_ds = IDFD(DATASET_DIR+"/train",
                seed=7891,
                validation_split=0.13,
                subset="training",
                labels="inferred",
                label_mode="categorical",
                interpolation="bilinear",
                image_size=IMAGE_SIZE,
                batch_size=BATCH_SIZE,
                color_mode="rgb")

Я читал документацию по image_dataset_from_directory и искал примеры, но пока не нашёл ничего, что бы работало. Даже Gemini и ChatGPT не приближают меня к ответу.

Очень надеюсь, что кто-то сможет мне помочь с этим. Я был бы очень благодарен за вашу помощь.

Вы не можете сделать это напрямую с image_dataset_from_directory, так как эта функция предназначена только для создания набора данных из ваших файлов. Тем не менее, вы можете преобразовать свой набор данных train_ds, чтобы получить другой набор данных с некоторым балансом, если захотите. Посмотрите на tf.data.Dataset, в частности, метод rejection_resample может быть тем, что вам нужно. Он позволяет вам проводить выборку из данного набора данных таким образом, чтобы достичь определенного целевого распределения классов, например $[0.25, 0.25, 0.25, 0.25]$ в случае четырех классов.

.

Ответ или решение

Для балансировки набора данных, извлеченного с помощью функции image_dataset_from_directory в TensorFlow, вам потребуется использовать различные методы, поскольку сама функция не предоставляет встроенные механизмы для балансировки классов. Ваша ситуация, при которой в наборе данных несколько классов, причем один из них имеет значительно меньшее количество изображений, требует особого подхода. Рассмотрим несколько способов решения этой проблемы.

Шаг 1: Создание набора данных

Ваш код для извлечения данных выглядит корректно. Вы загружаете изображения, которое автоматически разбивается на наборы для обучения и проверки. Таким образом, мы начнем с загрузки данных:

from keras.utils import image_dataset_from_directory as IDFD

IMAGE_SIZE = (176, 208)
BATCH_SIZE = 32
DATASET_DIR = '/content/drive/'  # Путь к папке с изображениями

train_ds = IDFD(DATASET_DIR+"/train",
                seed=7891,
                validation_split=0.13,
                subset="training",
                labels="inferred",
                label_mode="categorical",
                interpolation="bilinear",
                image_size=IMAGE_SIZE,
                batch_size=BATCH_SIZE,
                color_mode="rgb")

Шаг 2: Балансировка классов после извлечения данных

После того как вы извлекли данные, мы можем использовать несколько стратегий для балансировки классов:

  1. Повторяющаяся выборка классов: Вы можете создавать примеры для классов с минимальным количеством данных, продублировав их в вашем наборе, чтобы достичь желаемого баланса. Например, вы можете использовать метод tf.data.Dataset и flat_map для увеличения представительства классов с меньшей выборкой.

  2. rejection_resample: Этот метод позволяет реформировать набор данных так, чтобы достичь желаемой пропорции классов. Однако, он может оказаться не самым простым в реализации.

Реализация повтора выборки классов

Вот пример, как можно реализовать повтора выборки:

import tensorflow as tf

# Подсчет количества экземпляров каждого класса
class_counts = tf.constant([count_class_0, count_class_1, count_class_2, count_class_3])  # замените на свои значения
target_count = tf.reduce_max(class_counts)

# Функция для увеличения экземпляров классов
def oversample(dataset):
    sampled_ds = dataset.flat_map(lambda x, y: tf.data.Dataset.from_tensor_slices((x, y)).repeat(target_count // tf.reduce_max(class_counts)))
    return sampled_ds

balanced_train_ds = oversample(train_ds)

Шаг 3: Создание и обучение модели

После создания сбалансированного набора данных вы можете приступить к обучению модели как обычно:

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

model.fit(balanced_train_ds, epochs=epochs)

Заключение

Балансировка классов в наборе данных, созданном с помощью image_dataset_from_directory, может потребовать дополнительных усилий, но с помощью методов повторной выборки вы сможете достичь желаемых результатов. Используйте приведенные шаги и адаптируйте их к вашим данным. Это обеспечит более качественное обучение вашей модели и улучшит её производительность на различных классах.

Оцените материал
Добавить комментарий

Капча загружается...