Comment utiliser correctement ImageDataGenerator dans Keras?

0

La question

Je suis à jouer avec des renforts de données dans Keras dernièrement, et je suis l'aide de la base ImageDataGenerator. J'ai appris à la dure, il est en fait un générateur, pas d'itérateur (parce que type(train_aug_ds) donne <class 'keras.preprocessing.image.DirectoryIterator'> J'ai pensé que c'est un itérateur). J'ai aussi vérifié quelques blogs au sujet de l'aide, mais ils ne répondent pas à toutes mes questions.

Donc, j'ai chargé mes données comme ceci:

train_aug = ImageDataGenerator(
    rescale=1./255,
    horizontal_flip=True,
    height_shift_range=0.1,
    width_shift_range=0.1,
    brightness_range=(0.5,1.5),
    zoom_range = [1, 1.5],
)
train_aug_ds = train_aug.flow_from_directory(
    directory='./train',
    target_size=image_size,
    batch_size=batch_size,
)

Et pour former mon modèle je n'ai suivantes:

model.fit(
    train_aug_ds,
    epochs=150,
    validation_data=(valid_aug_ds,),
)

Et cela a fonctionné. Je suis un peu confus comment il fonctionne, parce que train_aug_ds est générateur, de sorte qu'il devrait donner de l'infiniment grand ensemble de données. Et de la documentation dit:

Lors du passage d'une infinie répétition de jeu de données, vous devez spécifier le steps_per_epoch argument.

Ce que je n'avais pas le faire, et pourtant, il fonctionne. Est-il en quelque sorte en déduire le nombre d'étapes? Aussi, faut-il utiliser uniquement augmentée de données, ou il utilise également la non-augmentée des images dans le lot?

Donc en gros, ma question est comment faire pour utiliser ce générateur correctement avec la fonction fit pour disposer de toutes les données dans ma formation, y compris d'origine, non-augmentée des images et augmentée des images, et pour faire défiler plusieurs fois/étapes (pour l'instant il semble qu'il ne fait qu'une étape pour l'époque)?

keras python tensorflow
2021-11-23 11:26:56
1

La meilleure réponse

1

Je pense que la documentation peut être assez déroutant et j'imagine que le comportement est différent selon votre Tensorflow et Keras version. Par exemple, dans ce post, l'utilisateur est en train de décrire le comportement exact que vous attendiez. Généralement, l' flow_from_directory() la méthode permet de lire les images directement à partir d'un répertoire et de les augmenter, tandis que votre modèle est en train d'être formés et comme déjà dit ici, il effectue une itération pour chaque échantillon dans chaque dossier de chaque époque. À l'aide de l'exemple suivant, vous pouvez vérifier que c'est le cas (sur TF 2.7) en regardant les étapes par la même époque, dans la barre de progression:

import tensorflow as tf

BATCH_SIZE = 64

flowers = tf.keras.utils.get_file(
    'flower_photos',
    'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
    untar=True)

img_gen = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1./255,
    horizontal_flip=True,
)

train_ds = img_gen.flow_from_directory(flowers, batch_size=BATCH_SIZE, shuffle=True, class_mode='sparse')
num_classes = 5

model = tf.keras.Sequential([
  tf.keras.layers.Conv2D(16, 3, padding='same', activation='relu', input_shape=(256, 256, 3)),
  tf.keras.layers.MaxPooling2D(),
  tf.keras.layers.Conv2D(32, 3, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(),
  tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(num_classes)
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True))

epochs=10
history = model.fit(
  train_ds,
  epochs=epochs
)
Found 3670 images belonging to 5 classes.
Epoch 1/10
 6/58 [==>...........................] - ETA: 3:02 - loss: 2.0608

Si vous envelopper flow_from_directory avec tf.data.Dataset.from_generator comme ceci:

train_ds = tf.data.Dataset.from_generator(
    lambda: img_gen.flow_from_directory(flowers, batch_size=BATCH_SIZE, shuffle=True, class_mode='sparse'),
    output_types=(tf.float32, tf.float32))

Vous remarquerez que la barre de progression est comme ça parce que steps_per_epoch n'a pas été explicitement défini:

Epoch 1/10
Found 3670 images belonging to 5 classes.
     29/Unknown - 104s 4s/step - loss: 2.0364

Et si vous ajoutez ce paramètre, vous verrez les étapes de la barre de progression:

history = model.fit(
  train_ds,
  steps_per_epoch = len(from_directory),
  epochs=epochs
)
Found 3670 images belonging to 5 classes.
Epoch 1/10
 3/58 [>.............................] - ETA: 3:19 - loss: 4.1357

Enfin, à votre question:

Comment utiliser ce générateur correctement avec la fonction d'ajustement d'avoir toutes les les données dans ma formation, y compris d'origine, non-augmentée des images et des augmentée des images, et pour faire défiler plusieurs fois/étape?

Vous pouvez simplement augmenter la steps_per_epoch au-delà de number of samples // batch_size en multipliant par un facteur:

history = model.fit(
  train_ds,
  steps_per_epoch = len(from_directory)*2,
  epochs=epochs
)
Found 3670 images belonging to 5 classes.
Epoch 1/10
  1/116 [..............................] - ETA: 12:11 - loss: 1.5885

Maintenant, au lieu de 58 pas par époque vous avez 116.

2021-11-23 17:22:32

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................