在 Tensorflow 中为输入和输出保持相同的数据集扩充
Posted
技术标签:
【中文标题】在 Tensorflow 中为输入和输出保持相同的数据集扩充【英文标题】:Keep same dataset augmentation for input and output in Tensorflow 【发布时间】:2020-12-14 07:54:30 【问题描述】:我有一个包含图像作为输入和输出的批处理数据集。代码是这样的:
os.chdir(r'E:/trainTest')
def process_img(file_path):
img = tf.io.read_file(file_path)
img = tf.image.decode_png(img, channels=3)
img = tf.image.convert_image_dtype(img, tf.float32)
img = tf.image.resize(img, size=(img_height, img_width))
return img
x_files = glob('input/*.png')
y_files = glob('output/*.png')
files_ds = tf.data.Dataset.from_tensor_slices((x_files, y_files))
#Dataset which gives me input-output
files_ds = files_ds.map(lambda x, y: (process_img(x), process_img(y))).batch(batch_size)
#model init etc
#----
model.fit(files_ds,epochs=25)
问题是我的模型没有足够的图像。所以我的问题是,如何从files_ds
创建增强图像(如翻转、旋转、缩放等)?因为必须像增强输入图像一样增强输出图像。
这个问题实际上来自以下问题,我想在它自己的部分提出这个问题:Tensorflow image_dataset_from_directory for input dataset and output dataset
【问题讨论】:
您好,第二张图片不是输出。这是基本事实。通常称为 Y。如果您更改“Tensorflow 中 X 和 Y 的相同增强”中的问题,我认为会更清楚。 【参考方案1】:tf.image
有一堆你可以使用的随机变换。例如:
random_brightness
random_hue
random_saturation
这是一个关于猫的完全随机图像的示例。
from skimage import data
import matplotlib.pyplot as plt
import tensorflow as tf
cat = data.chelsea()
plt.imshow(cat)
plt.show()
经过变换的图像:
from skimage import data
import matplotlib.pyplot as plt
import tensorflow as tf
cat = data.chelsea()
plt.imshow(tf.image.random_hue(cat, .2, .5))
plt.show()
您可以像这样在tf.data.Dataset
中实现它:
def process_img(file_path):
img = tf.io.read_file(file_path)
img = tf.image.decode_png(img, channels=3)
img = tf.image.convert_image_dtype(img, tf.float32)
img = tf.image.resize(img, size=(img_height, img_width))
img = tf.image.random_hue(img, 0., .5) # Here
return img
我找到了一种在图形模式下保持相同转换的方法。基本上是在同一次调用中将两个图像传递给转换器。
import os
import tensorflow as tf
os.chdir(r'c:/users/user/Pictures')
from glob2 import glob
import matplotlib.pyplot as plt
x_files = glob('inputs/*.jpg')
y_files = glob('targets/*.jpg')
files_ds = tf.data.Dataset.from_tensor_slices((x_files, y_files))
def load(file_path):
img = tf.io.read_file(file_path)
img = tf.image.decode_jpeg(img, channels=3)
img = tf.image.convert_image_dtype(img, tf.float32)
img = tf.image.resize(img, size=(28, 28))
return img
def process_img(file_path1, file_path2):
img = tf.stack([load(file_path1), load(file_path2)])
img = tf.image.random_hue(img, max_delta=.5)
return img[0], img[1]
files_ds = files_ds.map(lambda x, y: process_img(x, y)).batch(1)
a, b = next(iter(files_ds))
plt.imshow(a[0, ...])
plt.imshow(b[0, ...])
【讨论】:
我明白了,我如何将这个新的增强数据集与原始数据集连接起来?另外我认为我必须使用seed=1
参数来同步输入和输出增强
我猜分享种子就可以了
我添加了一些细节。【参考方案2】:
您可以使用 tf.keras.preprocessing.image.ImageDataGenerator 进行预处理。 This 是完整选项的文档页面。我已经分享了一个关于如何将其与 flow_from_directory 一起使用的小示例。您没有事先阅读图像并用完您的 RAM。图像从目录中加载、预处理并在需要时输入到模型中。
# we create two instances with the same arguments
data_gen_args = dict(rescale=1./255,
shear_range=0.2,
horizontal_flip=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_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(
train_generator,
steps_per_epoch=2000,
epochs=50)
【讨论】:
谢谢,但我的输出是图像,而不是标签,所以我无法从这个方法开始得到我想要的输出。flow_from_directory
是否支持输入图像和输出图像?如果是这样那就太好了
我已经为你的用例更新了答案。这样,您的输出图像将被增强,就像您的输入图像被增强一样。与此同时,图像将根据需要加载,不会消耗您的 RAM。
我明白了,image_datagen.fit(images, augment=True, seed=seed)
中的“图像”代表什么?
如果您在 ImageDataGenerator 中使用 featurewise_center
或 featurewise_std_normalization
或 zca_whitening
属性,则必须使用此步骤。图像代表加载的图像数据。(4d 张量)。这是计算内部状态所必需的。如果您有大量数据,您可以对数据样本使用 fit 命令。但是,如果您不使用上述参数,则可以完全跳过此步骤。 This 是它的文档页面。
我想我无法理解。图像尚未加载,将使用flow_from_directory
加载,但代码假定图像已经加载,我错过了什么吗?甚至文档也没有提到它来自哪里以上是关于在 Tensorflow 中为输入和输出保持相同的数据集扩充的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Tensorflow 中为 BERT 标记器指定输入序列长度?
Tensorflow 做LSTM 恢复模型测试时相同输入数据 给出的输出却不一样,这是怎么回事?