如何解决如何为Keras / tf.Keras构建自定义数据生成器,其中X图像被增强,相应的Y标签也是图像
我正在使用UNet进行图像二值化,并且也有150个图像及其二值化版本的数据集。我的想法是随机放大图像,使它们看起来像不同,所以我制作了一个函数,可以将4-5种类型的噪波,偏度,剪切等中的任何一种插入到图像中。我本来可以轻松使用
ImageDataGenerator(preprocess_function=my_aug_function)
来放大图像,但是问题是我的 y目标也是图像。另外,我本可以使用类似的东西:
train_dataset = (
train_dataset.map(
encode_single_sample,num_parallel_calls=tf.data.experimental.AUTOTUNE
)
.batch(batch_size)
.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
)
但是它有两个问题:
- 对于更大的数据集,由于数据需要已经在内存中,因此它将耗尽内存
- 这是至关重要的部分,我需要在旅途中增加图像以使其看起来像我有一个庞大的数据集。
另一种解决方案是将增强图像保存到目录中,使其大小为30-40K,然后加载它们。这样做很愚蠢。
现在,最重要的部分是我可以使用Sequence
作为父类,但是如何继续动态地使用各自的Y二值化图像来增强和生成新图像呢?
我有一个如下代码的想法。有人可以帮助我增强和生成y图像吗?我有X_DIR,Y_DIR
,其中二值化图像和原始图像名称相同,但存储在不同目录中。
class DataGenerator(tensorflow.keras.utils.Sequence):
def __init__(self,files_path,labels_path,batch_size=32,shuffle=True,random_state=42):
'Initialization'
self.files = files_path
self.labels = labels_path
self.batch_size = batch_size
self.shuffle = shuffle
self.random_state = random_state
self.on_epoch_end()
def on_epoch_end(self):
'Updates indexes after each epoch'
# Shuffle the data here
def __len__(self):
return int(np.floor(len(self.files) / self.batch_size))
def __getitem__(self,index):
# What do I do here?
def __data_generation(self,files):
# I think this is responsible for Augmentation but no idea how should I implement it and how does it works.
解决方法
您可以使用诸如唱片化和imgaug之类的库,两者都很好,但我听说唱片化的随机种子存在问题。 以下是来自文档here的imgaug示例:
seq = iaa.Sequential([
iaa.Dropout([0.05,0.2]),# drop 5% or 20% of all pixels
iaa.Sharpen((0.0,1.0)),# sharpen the image
iaa.Affine(rotate=(-45,45)),# rotate by -45 to 45 degrees (affects segmaps)
iaa.ElasticTransformation(alpha=50,sigma=5) # apply water effect (affects segmaps)
],random_order=True)
# Augment images and segmaps.
images_aug = []
segmaps_aug = []
for _ in range(len(input_data)):
images_aug_i,segmaps_aug_i = seq(image=image,segmentation_maps=segmap)
images_aug.append(images_aug_i)
segmaps_aug.append(segmaps_aug_i)
您将以正确的方式使用自定义生成器。在__getitem__
中,使用batch_x = self.files[index:index+batch_size]
进行批量处理,并使用batch_y
进行批量处理,然后使用X,y = __data_generation(batch_x,batch_y)
对其进行扩充,这将加载图像(使用您喜欢的任何库,我更喜欢opencv),并返回增强对(和其他任何操作)。
您的__getitem__
然后将返回元组(X,y)
即使标签是图像,也可以使用ImageDataGenerator。 这是一个简单的示例,说明如何实现:
代码:
# Specifying your data augmentation here for both image and label
image_datagen = tf.keras.preprocessing.image.ImageDataGenerator()
mask_datagen = tf.keras.preprocessing.image.ImageDataGenerator()
# Provide the same seed and keyword arguments to the flow methods
seed = 1
image_generator = image_datagen.flow_from_directory(
data_dir,class_mode=None,seed=seed)
mask_generator = mask_datagen.flow_from_directory(
data_dir,seed=seed)
# Combine the image and label generator.
train_generator = zip(image_generator,mask_generator)
现在,如果您对其进行迭代,将得到:
for image,label in train_generator:
print(image.shape,label.shape)
break
输出:
(32,256,3) (32,3)
您可以通过fit()
命令使用此train_generator。
代码:
model.fit_generator(
train_generator,steps_per_epoch=2000,epochs=50)
有了flow_from_directory
,您的记忆将不会混乱,Imagedatagenerator
将负责扩充部分。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。