将数据目录拆分为训练和测试目录,并保留子目录结构

时间:2017-10-12 19:47:40

标签: python machine-learning neural-network keras deep-learning

我有兴趣在Keras中使用ImageDataGenerator进行数据扩充。但它要求具有类子目录的训练和验证目录分别如下所示(这来自Keras文档)。我有一个目录,包含2个子目录(2个类(Data / Class1和Data / Class2)。如何将其随机分成训练和验证目录

    train_datagen = ImageDataGenerator(
    rescale=1./255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

    test_datagen = ImageDataGenerator(rescale=1./255)

    train_generator = train_datagen.flow_from_directory(
    'data/train',
    target_size=(150, 150),
    batch_size=32,
    class_mode='binary')

   validation_generator = test_datagen.flow_from_directory(
    'data/validation',
    target_size=(150, 150),
    batch_size=32,
    class_mode='binary')

   model.fit_generator(
    train_generator,
    steps_per_epoch=2000,
    epochs=50,
    validation_data=validation_generator,
    validation_steps=800)

我有兴趣通过随机培训和验证数据拆分多次重新运行我的算法。

7 个答案:

答案 0 :(得分:10)

谢谢你们!我能够编写自己的函数来创建训练和测试数据集。这是所有正在寻找的人的代码。

exec echo abc

答案 1 :(得分:3)

https://stackoverflow.com/a/52372042/10111155提供了最简单的方法:ImageDataGenerator现在支持从具有子目录的单个目录直接拆分为训练/测试。

这是直接从该答案复制而没有任何更改。我不相信我试过了,效果很好。

请注意,train_data_dirtrain_generator中的validation_generator是相同的。如果要使用ImageDataGenerator进行三向拆分(训练/测试/有效),则需要修改源代码---有不错的说明here

train_datagen = ImageDataGenerator(rescale=1./255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    validation_split=0.2) # set validation split

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary',
    subset='training') # set as training data

validation_generator = train_datagen.flow_from_directory(
    train_data_dir, # same directory as training data
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary'
    subset='validation') # set as validation data

model.fit_generator(
    train_generator,
    steps_per_epoch = train_generator.samples // batch_size,
    validation_data = validation_generator, 
    validation_steps = validation_generator.samples // batch_size,
    epochs = nb_epochs)

答案 2 :(得分:2)

不幸的是,目前keras.preprocessing.image.ImageDataGenerator的实施(2017年10月14日)是不可能的,但由于它是一个真正需要的功能,我希望它能在最近的将来添加。

但是你可以使用标准的Python os操作来做到这一点。根据数据集的大小,您还可以尝试首先将所有图片加载到RAM,然后使用经典的fit方法,该方法可以随机拆分数据。

答案 3 :(得分:1)

您需要手动复制一些训练数据并将其粘贴到验证目录中,或创建一个程序将数据从训练目录随机移动到验证目录。使用这些选项中的任何一个,您都需要将验证目录传递给验证ImageDataGenerator().flow_from_directory()作为路径。

this video中介绍了在目录结构中组织数据的详细信息。

答案 4 :(得分:0)

这是我的方法:

# Create temporary validation set.
with TemporaryDirectory(dir=train_image_folder) as valid_image_folder, TemporaryDirectory(dir=train_label_folder) as valid_label_folder:
    train_images = os.listdir(train_image_folder)
    train_labels = os.listdir(train_label_folder)

    for img_name in train_images:
        single_name, ext = os.path.splitext(img_name)
        label_name = single_name + '.png'
        if label_name not in train_labels:
            continue
        if random.uniform(0, 1) <= train_val_split:
            # Move the files.
            shutil.move(os.path.join(train_image_folder, img_name), os.path.join(valid_image_folder, img_name))
            shutil.move(os.path.join(train_label_folder, label_name), os.path.join(valid_label_folder, img_name))

不要忘记把所有东西都搬回来。

答案 5 :(得分:0)

你的解决方案有效,谢谢。

   import os
   import shutil
   import numpy as np

   sourceN = base_dir + "\\train\\NORMAL\\"
   destN = base_dir + "\\val\\NORMAL"
   sourceP = base_dir + "\\train\\PNEUMONIA"
   destP = base_dir + "\\val\\PNEUMONIA"

   filesN = os.listdir(sourceN)
   filesP = os.listdir(sourceP)       

   for f in filesN:
       if np.random.rand(1) < 0.2:
       shutil.move(sourceN + '\\'+ f, destN + '\\'+ f)

   for i in filesP:
       if np.random.rand(1) < 0.2:
       shutil.move(sourceP + '\\'+ i, destP + '\\'+ i)

   print(len(os.listdir(sourceN)))
   print(len(os.listdir(sourceP)))
   print(len(os.listdir(destN)))
   print(len(os.listdir(destP)))

答案 6 :(得分:0)

如果只想分割图像数据而不对图像应用任何变换,请使用以下代码。

from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(
        validation_split=0.4)

train_generator = train_datagen.flow_from_directory(
        'path_to_data_directory',
        subset='training')

validation_generator = train_datagen.flow_from_directory(
        'path_to_data_directory', #same as in train generator
        subset='validation')

这将获取给定的“数据目录路径” ,并从该目录的子文件夹中获取图像,并分配相应的子文件夹名称作为图像的类名

样本输出

Found 43771 images belonging to 9385 classes.
Found 22490 images belonging to 9385 classes.

您可以使用model.fit_generator将此数据加载到模型中。

有关详细信息,请参见https://keras.io/preprocessing/image/