wake-up-neo.net

Datenverzeichnis in Trainings- und Testverzeichnis aufteilen, wobei die Unterverzeichnisstruktur erhalten bleibt

Ich bin an der Verwendung von ImageDataGenerator in Keras zur Datenerhöhung interessiert. Es ist jedoch erforderlich, dass Schulungs- und Validierungsverzeichnisse mit Unterverzeichnissen für Klassen wie folgt separat eingegeben werden (dies ist aus der Keras-Dokumentation). Ich habe ein einzelnes Verzeichnis mit 2 Unterverzeichnissen für 2 Klassen (Data/Class1 und Data/Class2). Wie spalte ich dies zufällig in Trainings- und Validierungsverzeichnisse auf? 

    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)

Ich bin daran interessiert, meinen Algorithmus mehrmals mit zufälligen Trainings- und Validierungsdatensplits erneut auszuführen.

Danke Jungs! Ich konnte meine eigene Funktion schreiben, um Trainings- und Testdatensätze zu erstellen. Hier ist der Code für jeden, der sucht. 

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

Leider ist dies für die aktuelle Implementierung von keras.preprocessing.image.ImageDataGenerator nicht möglich (Stand 14. Oktober 2017). Da es sich jedoch um eine wirklich gefragte Funktion handelt, erwarte ich, dass sie in naher Zukunft hinzugefügt wird.

Sie können dies jedoch mit Standard-Python os-Vorgängen tun. Abhängig von der Größe Ihres Datensatzes können Sie auch versuchen, zuerst alle Bilder in RAM zu laden und dann eine klassische fit-Methode zu verwenden, die Ihre Daten zufällig aufteilen kann.

2
Marcin Możejko

https://stackoverflow.com/a/52372042/10111155 Der einfachste Weg: ImageDataGenerator unterstützt jetzt die direkte Aufteilung in train/test aus einem einzigen Verzeichnis mit Unterverzeichnissen.

Dies wird ohne Änderungen direkt aus dieser Antwort übernommen. Ich nehme keinen Kredit an. Ich habe es versucht und es hat perfekt funktioniert.

Beachten Sie, dass train_data_dir in train_generator und validation_generator identisch ist. Wenn Sie mit ImageDataGenerator eine dreiteilige Aufteilung (Zug/Test/Gültig) wünschen, muss der Quellcode geändert werden - es gibt Nice-Anweisungen hier .

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

Sie müssen entweder einige Ihrer Trainingsdaten manuell kopieren und in ein Validierungsverzeichnis einfügen oder ein Programm erstellen, um Daten zufällig aus Ihrem Trainingsverzeichnis in Ihr Validierungsverzeichnis zu verschieben. Mit einer dieser Optionen müssen Sie das Validierungsverzeichnis als Pfad an Ihre Validierungsfunktion ImageDataGenerator().flow_from_directory() übergeben.

Details zum Organisieren Ihrer Daten in der Verzeichnisstruktur finden Sie in diesem Video .

1

Wenn Sie nur die Bilddaten teilen möchten, ohne Transformationen auf die Bilder anzuwenden, verwenden Sie den folgenden Code.

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

Dies nimmt das angegebene 'path_to_data_directory' und nimmt Bilder aus den Unterordnern aus diesem Verzeichnis und weist den entsprechenden Unterordnernamen als Klassennamen des Bildes.

Beispielausgabe

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

Mit model.fit_generator können Sie diese Daten in Ihr Modell laden.

Weitere Informationen finden Sie unter https://keras.io/preprocessing/image/ .

0
codeslord

Ihre Lösung hat funktioniert, danke.

   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

Hier ist mein Ansatz:

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

Vergiss nicht, alles zurückzuschieben.

0
Richard