未从改组的数据集中选择Keras ImageDataGenerator验证拆分

时间:2020-06-30 16:40:05

标签: python validation tensorflow keras training-data

如何将图像数据集随机分为训练和验证日期集?更具体地说,Keras validation_split函数中的ImageDataGenerator参数不是将我的图像随机分为训练和验证,而是从未经改组的数据集中切片验证样本。

1 个答案:

答案 0 :(得分:3)

在Keras的validation_split中指定ImageDataGenerator自变量时,将在对数据进行混洗之前执行拆分,以便仅获取最后的x个样本。问题在于,最后被选作验证的数据样本可能无法代表训练数据,因此可能会失败。当您的图像数据存储在公共目录中且每个子文件夹均由class命名时,这是一个特别常见的死角。在几篇文章中都提到了

Choose random validation data set

正如您所提到的,Keras只是获取数据集的最后x个样本,因此,如果您要继续使用它,则需要提前对数据集进行洗牌。

The training accuracy is very high, while the validation accuracy is very low?

请在训练之前检查您是否对数据进行了混洗。由于在喀拉拉邦进行的验证拆分是在随机播放之前执行的,因此也许您选择了不平衡数据集作为验证集,所以准确性较低。

Does 'validation split' randomly choose validation sample?

验证数据被选为输入的最后10%(例如,如果validation_split = 0.9)。可以选择在每个时期将训练数据(其余部分)进行混洗(适合混洗参数)。显然,这并不会影响验证数据,因为每个纪元之间的数据集必须相同。

This answer指出了sklearn train_test_split()作为解决方案,但我想提出一种不同的解决方案,以保持keras工作流程的一致性。

使用split-folders软件包,您可以将主数据目录随机分为培训,验证和测试(或只是培训和验证)目录。特定于类的子文件夹将自动复制。

输入文件夹应采用以下格式:

input/
    class1/
        img1.jpg
        img2.jpg
        ...
    class2/
        imgWhatever.jpg
        ...
    ...

为了给你这个:

output/
    train/
        class1/
            img1.jpg
            ...
        class2/
            imga.jpg
            ...
    val/
        class1/
            img2.jpg
            ...
        class2/
            imgb.jpg
            ...
    test/            # optional
        class1/
            img3.jpg
            ...
        class2/
            imgc.jpg
            ...

从文档中:

import split_folders

# Split with a ratio.
# To only split into training and validation set, set a tuple to `ratio`, i.e, `(.8, .2)`.
split_folders.ratio('input_folder', output="output", seed=1337, ratio=(.8, .1, .1)) # default values

# Split val/test with a fixed number of items e.g. 100 for each set.
# To only split into training and validation set, use a single number to `fixed`, i.e., `10`.
split_folders.fixed('input_folder', output="output", seed=1337, fixed=(100, 100), oversample=False) # default values

通过这种新的文件夹结构,您可以轻松地使用keras数据生成器将数据分为训练和验证,并最终训练模型。

import tensorflow as tf
import split_folders
import os

main_dir = '/Volumes/WMEL/Independent Research Project/Data/test_train/Data'
output_dir = '/Volumes/WMEL/Independent Research Project/Data/test_train/output'

split_folders.ratio(main_dir, output=output_dir, seed=1337, ratio=(.7, .3))

train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1./224)

train_generator = train_datagen.flow_from_directory(os.path.join(output_dir,'train'),
                                                    class_mode='categorical',
                                                    batch_size=32,
                                                    target_size=(224,224),
                                                    shuffle=True)

validation_generator = train_datagen.flow_from_directory(os.path.join(output_dir,'val'),
                                                        target_size=(224, 224),
                                                        batch_size=32,
                                                        class_mode='categorical',
                                                        shuffle=True) # set as validation data

base_model = tf.keras.applications.ResNet50V2(
    input_shape=IMG_SHAPE,
    include_top=False,
    weights=None)

maxpool_layer = tf.keras.layers.GlobalMaxPooling2D()
prediction_layer = tf.keras.layers.Dense(4, activation='softmax')

model = tf.keras.Sequential([
    base_model,
    maxpool_layer,
    prediction_layer
])

opt = tf.keras.optimizers.Adam(lr=0.004)
model.compile(optimizer=opt,
              loss=tf.keras.losses.CategoricalCrossentropy(),
              metrics=['accuracy'])

model.fit(
    train_generator,
    steps_per_epoch = train_generator.samples // 32,
    validation_data = validation_generator,
    validation_steps = validation_generator.samples // 32,
    epochs = 20)