Как разделить папки на 3 набора данных с помощью ImageDataGenerator?
Параметр validation_split может позволить ImageDataGenerator разделить наборы данных, считываемые из папки, на 2 разных непересекающихся набора. Есть ли способ создать 3 набора - наборов данных для обучения, проверки и оценки, используя его?
Я думаю о разделении набора данных на 2 набора данных, а затем о разделении второго набора данных на еще 2 набора данных.
datagen = ImageDataGenerator(validation_split=0.5, rescale=1./255)
train_generator = datagen.flow_from_directory(
TRAIN_DIR,
subset='training'
)
val_generator = datagen.flow_from_directory(
TRAIN_DIR,
subset='validation'
)
Здесь я думаю о разделении набора данных проверки на 2 набора с помощью val_generator. Один для проверки, а другой для оценки? Как я должен это делать?
2 ответа
мне нравится работать с
flow_from_dataframe()
метод
ImageDataGenerator
, где я взаимодействую с простым Pandas DataFrame (возможно, содержащим другие функции), а не с каталогом. Но вы можете легко изменить мой код, если настаиваете на
flow_from_directory()
.
Так что это моя основная функция, например, для задачи регрессии, где мы пытаемся предсказать непрерывный :
def get_generators(train_samp, test_samp, validation_split = 0.1):
train_datagen = ImageDataGenerator(validation_split=validation_split, rescale = 1. / 255)
test_datagen = ImageDataGenerator(rescale = 1. / 255)
train_generator = train_datagen.flow_from_dataframe(
dataframe = images_df[images_df.index.isin(train_samp)],
directory = images_dir,
x_col = 'img_file',
y_col = 'y',
target_size = (IMG_HEIGHT, IMG_WIDTH),
class_mode = 'raw',
batch_size = batch_size,
shuffle = True,
subset = 'training',
validate_filenames = False
)
valid_generator = train_datagen.flow_from_dataframe(
dataframe = images_df[images_df.index.isin(train_samp)],
directory = images_dir,
x_col = 'img_file',
y_col = 'y',
target_size = (IMG_HEIGHT, IMG_WIDTH),
class_mode = 'raw',
batch_size = batch_size,
shuffle = False,
subset = 'validation',
validate_filenames = False
)
test_generator = test_datagen.flow_from_dataframe(
dataframe = images_df[images_df.index.isin(test_samp)],
directory = images_dir,
x_col = 'img_file',
y_col = 'y',
target_size = (IMG_HEIGHT, IMG_WIDTH),
class_mode = 'raw',
batch_size = batch_size,
shuffle = False,
validate_filenames = False
)
return train_generator, valid_generator, test_generator
На что следует обратить внимание:
- Я использую два генератора
- Входными данными для функции являются индексы поезда/теста (например, полученные от Sklearn's
train_test_split
), которые используются для фильтрации индекса DataFrame. - Функция также принимает
validation_split
параметр для обучающего генератора -
images_df
это DataFrame где-то в глобальной памяти с соответствующими столбцами, такими какimg_file
а такжеy
. - Не нужно
shuffle
генераторы проверки и тестирования
Это может быть дополнительно обобщено для нескольких выходов, классификации, что у вас есть.
В основном я разбивал данные на 80/10/10 для обучения, проверки и тестирования соответственно.
При работе с keras я предпочитаюtf.data
API , поскольку он обеспечивает хорошую абстракцию для сложных входных конвейеров.
Он не обеспечивает простой
tf.data.DataSet.split
хотя функциональность
У меня есть эта функция (которую я нашел в чьем-то коде, а мой источник отсутствует), которую я постоянно использую
def get_dataset_partitions_tf(ds: tf.data.Dataset, ds_size, train_split=0.8, val_split=0.1, test_split=0.1, shuffle=True, shuffle_size=10000):
assert (train_split + test_split + val_split) == 1
if shuffle:
# Specify seed to always have the same split distribution between runs
ds = ds.shuffle(shuffle_size, seed=12)
train_size = int(train_split * ds_size)
val_size = int(val_split * ds_size)
train_ds = ds.take(train_size)
val_ds = ds.skip(train_size).take(val_size)
test_ds = ds.skip(train_size).skip(val_size)
return train_ds, val_ds, test_ds
Сначала прочитайте свой набор данных и получите его размер (с помощью метода Cardianlity ), затем передайте его в функцию, и все готово!
Этой функции можно задать флаг для перемешивания исходного набора данных перед созданием разбиений, это полезно для более реалистичных показателей проверки и тестирования.
Семя для перетасовки фиксировано, поэтому мы можем запускать одну и ту же функцию, а разбиения остаются прежними, что нам нужно для согласованных результатов.