web-dev-qa-db-fra.com

Fractionner le répertoire de données en répertoire de formation et de test avec la structure de sous-répertoires préservée

Je souhaite utiliser ImageDataGenerator dans Keras pour l’augmentation des données. Mais cela nécessite que les répertoires de formation et de validation avec les sous-répertoires des classes soient alimentés séparément comme indiqué ci-dessous (ceci est dans la documentation de Keras). J'ai un seul répertoire avec 2 sous-répertoires pour 2 classes (Data/Class1 et Data/Class2). Comment puis-je scinder cela au hasard en répertoires de formation et de validation 

    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)

Je suis intéressé à réexécuter mon algorithme plusieurs fois avec des groupes de données de formation et de validation aléatoires.

9

Merci les gars! J'ai pu écrire ma propre fonction pour créer des ensembles de données de formation et de test. Voici le code pour quiconque cherche. 

import os
source1 = "/source_dir"
dest11 = "/dest_dir"
files = os.listdir(source1)
import shutil
import numpy as np
for f in files:
    if np.random.Rand(1) < 0.2:
        shutil.move(source1 + '/'+ f, dest11 + '/'+ f)
10

Malheureusement, il est impossible pour l'implémentation actuelle de keras.preprocessing.image.ImageDataGenerator (comme pour le 14 octobre 2017), mais comme c'est une fonctionnalité très demandée, je m'attends à ce qu'elle soit ajoutée dans un proche avenir.

Mais vous pouvez le faire en utilisant les opérations Python os standard. En fonction de la taille de votre jeu de données, vous pouvez également essayer de charger toutes les images dans RAM, puis utiliser une méthode classique fit permettant de fractionner vos données de manière aléatoire.

2
Marcin Możejko

https://stackoverflow.com/a/52372042/10111155 est le moyen le plus simple: ImageDataGenerator prend désormais en charge le fractionnement en train/test à partir d'un répertoire unique contenant directement des sous-répertoires.

Ceci est directement copié de cette réponse sans aucun changement. Je ne prends aucun crédit. J'ai essayé et cela a fonctionné parfaitement.

Notez que train_data_dir est identique dans les train_generator et validation_generator. Si vous voulez une scission à trois voies (train/test/valide) en utilisant ImageDataGenerator, le code source devra être modifié - il existe des instructions de Nice ici .

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
Beau Hilton

Vous devrez soit copier manuellement certaines de vos données de formation et les coller dans un répertoire de validation, soit créer un programme permettant de déplacer de manière aléatoire des données de votre répertoire de formation dans votre répertoire de validation. Avec l’une ou l’autre de ces options, vous devrez transmettre le répertoire de validation à votre ImageDataGenerator().flow_from_directory() de validation en tant que chemin.

Les détails pour organiser vos données dans la structure de répertoires sont traités dans cette vidéo .

1
blackHoleDetector

Votre solution a fonctionné, merci.

   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)))
0
Jordy

Voici mon approche:

# 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))

N'oubliez pas de tout reculer.

0
Richard