Augmentation Des Données Générateur De Données Keras Segmentation Sémantique
j'installe un réseau convolutionnel complet sur certaines données d'image pour la segmentation sémantique en utilisant Keras. Cependant, je vais avoir quelques problèmes de surapprentissage. Je n'ai pas beaucoup de données et je veux les augmenter. Cependant, comme je veux faire une classification par pixel-Sage, j'ai besoin de n'importe quelles augmentations comme des flips, des rotations, et des décalages pour appliquer à la fois les images de trait et les images d'étiquette. Idéalement, J'aimerais utiliser le Générateur Keras ImageDataGenerator pour les transformations à la volée. Cependant, autant que je peux tell, vous ne pouvez pas effectuer des transformations équivalentes sur les données feature et label.
est ce que quelqu'un sait si c'est le cas et si non, quelqu'un aurait-il des idées? Sinon, je vais utiliser d'autres outils pour créer un ensemble de données plus grand et juste l'alimenter en tout à la fois.
Merci!
2 réponses
il y a des travaux sur l'extension de ImageDataGenerator pour être plus flexible pour exactement ce type de cas (voir dans ce numéro sur Github pour les exemples).
en outre, comme mentionné par Mikael Rousson dans les commentaires, vous pouvez facilement créer votre propre version de ImageDataGenerator vous-même, tout en tirant parti de plusieurs de ses fonctions intégrées pour le rendre plus facile. Voici un exemple de code que j'ai utilisé pour un problème de dénoisage d'image, où j'utilise des cultures aléatoires + bruit additif pour générer des paires d'images propres et bruyantes à la volée. Vous pouvez facilement le modifier pour ajouter d'autres types de renforcements. Après quoi, vous pouvez utiliser Modèle.fit_generator pour le train à l'aide de ces méthodes.
from keras.preprocessing.image import load_img, img_to_array, list_pictures
def random_crop(image, crop_size):
height, width = image.shape[1:]
dy, dx = crop_size
if width < dx or height < dy:
return None
x = np.random.randint(0, width - dx + 1)
y = np.random.randint(0, height - dy + 1)
return image[:, y:(y+dy), x:(x+dx)]
def image_generator(list_of_files, crop_size, to_grayscale=True, scale=1, shift=0):
while True:
filename = np.random.choice(list_of_files)
try:
img = img_to_array(load_img(filename, to_grayscale))
except:
return
cropped_img = random_crop(img, crop_size)
if cropped_img is None:
continue
yield scale * cropped_img - shift
def corrupted_training_pair(images, sigma):
for img in images:
target = img
if sigma > 0:
source = img + np.random.normal(0, sigma, img.shape)/255.0
else:
source = img
yield (source, target)
def group_by_batch(dataset, batch_size):
while True:
try:
sources, targets = zip(*[next(dataset) for i in xrange(batch_size)])
batch = (np.stack(sources), np.stack(targets))
yield batch
except:
return
def load_dataset(directory, crop_size, sigma, batch_size):
files = list_pictures(directory)
generator = image_generator(files, crop_size, scale=1/255.0, shift=0.5)
generator = corrupted_training_pair(generator, sigma)
generator = group_by_batch(generator, batch_size)
return generator
vous pouvez alors utiliser ce qui précède comme suit:
train_set = load_dataset('images/train', (patch_height, patch_width), noise_sigma, batch_size)
val_set = load_dataset('images/val', (patch_height, patch_width), noise_sigma, batch_size)
model.fit_generator(train_set, samples_per_epoch=batch_size * 1000, nb_epoch=nb_epoch, validation_data=val_set, nb_val_samples=1000)
Oui, vous pouvez. Voici un exemple tiré des documents de Keras. Vous zip ensemble deux générateurs ensemencés avec les mêmes graines et le fit_generator eux. https://keras.io/preprocessing/image/
# we create two instances with the same arguments
data_gen_args = dict(featurewise_center=True,
featurewise_std_normalization=True,
rotation_range=90.,
width_shift_range=0.1,
height_shift_range=0.1,
zoom_range=0.2)
image_datagen = ImageDataGenerator(**data_gen_args)
mask_datagen = ImageDataGenerator(**data_gen_args)
# Provide the same seed and keyword arguments to the fit and flow methods seed = 1
image_datagen.fit(images, augment=True, seed=seed)
mask_datagen.fit(masks, augment=True, seed=seed)
image_generator = image_datagen.flow_from_directory(
'data/images',
class_mode=None,
seed=seed)
mask_generator = mask_datagen.flow_from_directory(
'data/masks',
class_mode=None,
seed=seed)
# combine generators into one which yields image and masks
train_generator = zip(image_generator, mask_generator)
model.fit_generator(
train_generator,
samples_per_epoch=2000,
nb_epoch=50)