Генератор Данных Для Увеличения Изображения Keras Семантическая Сегментация
Я устанавливаю полную сверточную сеть на некоторые данные изображения для семантической сегментации с использованием Keras. Тем не менее, у меня есть некоторые проблемы с подгонкой. У меня не так много данных, и я хочу сделать увеличение данных. Однако, поскольку я хочу сделать пиксельную классификацию, мне нужны любые дополнения, такие как сальто, вращения и сдвиги, чтобы применить как к изображениям объектов, так и к изображениям меток. В идеале я хотел бы использовать Keras ImageDataGenerator для преобразований "на лету". Однако, насколько я могу tell, вы не можете выполнять эквивалентные преобразования как для данных объектов, так и для данных меток.
кто-нибудь знает, если это так, а если нет, есть ли у кого-нибудь идеи? В противном случае я буду использовать другие инструменты для создания большего набора данных и просто вводить его сразу.
спасибо!
2 ответов
есть работы по расширению ImageDataGenerator, чтобы быть более гибкими именно для таких случаев (см. в этот вопрос на Github для примера).
кроме того, как упоминал Микаэль Руссон в комментариях, вы можете легко создать свою собственную версию ImageDataGenerator самостоятельно, используя многие из своих встроенных функций, чтобы сделать его проще. Вот пример кода, который я использовал для проблем имиджа шумодав, где я использую случайный культур + аддитивного шума в генерировать чистые и шумные пары изображений на лету. Вы можете легко изменить это, чтобы добавить другие типы дополнений. После чего, вы можете использовать модель.fit_generator обучение с использованием этих методов.
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
вы можете использовать выше, как так:
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)
Да, вы можете. Вот пример из документов Кераса. Вы соединяете два генератора, засеянных одними и теми же семенами, и fit_generator их. 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)