Вопрос или проблема
Я работаю над задачей многометочной классификации и столкнулся с проблемами памяти, поэтому хотел бы использовать метод Keras image_dataset_from_directory
для загрузки всех изображений партиями. Как применить технику многометочной классификации с использованием этого метода?
У меня есть следующие папки:
['Tomato_BacterialSpot', 'Tomato_EarlyBlight', 'Tomato_Healthy', 'Tomato_LateBlight']
Я генерирую названия классов, используя следующий код.
Здесь находится пример кода для многометочной классификации, но они не использовали метод image_dataset_from_directory
.
label = imagePath.split(os.path.sep)[-2].split("_")
И я получил следующий результат, но не знаю, как использовать метод image_dataset_from_directory
для многометочной классификации?
- BacterialSpot
- EarlyBlight
- Healthy
- LateBlight
- Tomato
Вам на самом деле не нужно применять метки классов, они не важны. Keras определяет их автоматически. Это делается путем изучения директории, в которой находятся ваши данные. Убедитесь, что вы указали родительскую папку, где должны находиться все ваши данные. Ваши данные должны быть в следующем формате:
my_data/
...BacterialSpot/
...EarlyBlight/
...Healthy/
...LateBlight/
...Tomato/
где источник данных, на который вы должны указать, — это my_data. Вот реализация:
train = tf.keras.preprocessing.image_dataset_from_directory(
'my_data',
validation_split=0.2,
subset="training",
image_size=(128, 128),
batch_size=128)
val = tf.keras.preprocessing.image_dataset_from_directory(
'my_data',
validation_split=0.2,
subset="validation",
image_size=(128, 128),
batch_size=128)
Затем, когда вы запустите это:
Found 3647 files belonging to 1 classes.
Using 2918 files for training.
Found 3647 files belonging to 1 classes.
Using 729 files for validation.
Keras автоматически определил классы для вас. Я использовал только один класс в своем примере, так что вы должны увидеть что-то, касающееся 5 классов в вашем случае. Смотрите пример реализации здесь от Google:
https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/images/classification.ipynb#scrollTo=iscU3UoVJBXj
Ответ или решение
В вашем вопросе вы описали проблему использования метода image_dataset_from_directory
из библиотеки Keras для загрузки изображений в рамках задачи многометочной классификации. Основной акцент вы сделали на использовании данного метода в условиях ограниченной памяти, а также отметили, что необходимо применить технику многометочной классификации. Давайте подробно рассмотрим, как это сделать, учитывая нюансы вашей задачи.
Теория
image_dataset_from_directory
— это метод, который обеспечивает удобную загрузку изображений из директории, автоматически создавая наборы данных для обучения и валидации. Он автоматически считывает классы изображений на основании структуры папок, что значительно облегчает процесс подготовки данных для задач классификации. Однако, в случае многометочной классификации, структура данных немного меняется, так как одно изображение может относиться сразу к нескольким классам.
Для задач многометочной классификации один возможный подход заключается в использовании бинарных меток. Вместо одной метки, присваивающей изображению один класс, каждому изображению сопоставляется вектор, в котором каждое значение (0 или 1) указывает на принадлежность или отсутствие конкретной метки. Например, если у вас есть классы "BacterialSpot", "EarlyBlight", "Healthy", "LateBlight", и "Tomato", то изображение может одновременно иметь метки "1 0 1 0 1", что означает, что оно принадлежит к "BacterialSpot", "Healthy" и "Tomato".
Пример
Стандартный подход с использованием image_dataset_from_directory
предполагает, что папки с изображениями содержат отдельные классы. Однако, в случае многометочного подхода это может быть недостаточно. Вот как можно организовать процесс:
-
Структура данных: Каждое изображение должно быть связано с текстовым файлом (например, CSV), который содержит информацию о соответствующих метках каждого изображения.
-
Загрузка изображений: Используем метод
image_dataset_from_directory
, чтобы загрузить изображения в виде батчей, но метки будем загружать отдельно. -
Предварительная обработка: Для связывания изображений и меток создайте функцию, которая будет считывать метки из файла и соотносить их с загружаемыми изображениями.
Реализация
import tensorflow as tf
import pandas as pd
import os
# Загрузка изображений
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
'my_data',
validation_split=0.2,
subset="training",
image_size=(128, 128),
batch_size=32,
seed=123
)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
'my_data',
validation_split=0.2,
subset="validation",
image_size=(128, 128),
batch_size=32,
seed=123
)
# Загрузка меток многометочной классификации из CSV
labels_df = pd.read_csv('labels.csv') # Предполагается, что в CSV имеется структура: filename, BacterialSpot, EarlyBlight, Healthy, LateBlight, Tomato
# Примерный вид функции для подготовки данных
def process_path(file_path):
parts = tf.strings.split(file_path, os.path.sep)
img = tf.io.read_file(file_path)
img = tf.image.decode_jpeg(img, channels=3)
img = tf.image.resize(img, [128, 128])
label = labels_df[labels_df['filename']==parts[-1].numpy().decode()]
labels = label.drop(columns=['filename']).values.tolist()[0]
return img, tf.convert_to_tensor(labels, dtype=tf.int32)
# Применение функции к набору данных
AUTOTUNE = tf.data.AUTOTUNE
def prepare_dataset(ds):
labeled_data = ds.map(lambda x, y: process_path(x), num_parallel_calls=AUTOTUNE)
return labeled_data.prefetch(buffer_size=AUTOTUNE)
train_ds = prepare_dataset(train_ds)
val_ds = prepare_dataset(val_ds)
# Компиляция и обучение модели
model = tf.keras.Sequential([
tf.keras.layers.Rescaling(1./255, input_shape=(128, 128, 3)),
tf.keras.layers.Conv2D(32, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(32, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(5, activation='sigmoid') # Пять меток для многометочной классификации
])
model.compile(
optimizer='adam',
loss='binary_crossentropy', # Бинарная кросс-энтропия для многометочной классификации
metrics=['accuracy']
)
model.fit(train_ds, validation_data=val_ds, epochs=10)
Применение
Этот подход позволяет гибко и корректно загружать данные с использованием image_dataset_from_directory
, при этом имея возможность применять многоетомное кодирование меток для многометочных задач. Это может существенно улучшить подготовку данных и повысить эффективность модели, особенно при ограниченных вычислительных ресурсах.
В описанном методе мы связываем изображения и метки через CSV файл, что позволяет легко масштабировать данный подход на более обширные и сложные наборы данных, где количество классов и меток может быть значительным. Таким образом, вы можете настроить ваш проект так, чтобы максимизировать эффективность использования памяти, разграничивать вычислительные ресурсы и поддерживать высокий уровень точности модели.