如何在 Tensorflow 2.0 中将 imgaug 增强应用到 tf.dataDataset
how to apply imgaug augmentation to tf.dataDataset in Tensorflow 2.0
我有一个带有输入管道的应用程序,该管道使用 tf.data.Dataset
图像和标签。现在我想使用扩充,并且我正在尝试使用 imgaug 库来达到这个目的。但是,我不知道该怎么做。我找到的所有示例都使用 Keras ImageDataGenerator
或 Sequence
.
在代码中,给定一个像这样的顺序增强器
self.augmenter = iaa.Sequential([
iaa.Fliplr(config.sometimes),
iaa.Crop(percent=config.crop_percent),
...
], random_order=config.random_order)
我正在尝试将该增强器应用于我的数据集中的成批图像,但没有成功。似乎我无法评估张量,因为我是 运行 我在 map 函数中的扩充。
def augment_dataset(self, dataset):
dataset = dataset.map(self.augment_fn())
return dataset
def augment_fn(self):
def augment(images, labels):
img_array = tf.make_ndarray(images)
images = self.augmenter.augment_images(img_array)
return images, labels
return augment
例如,如果我尝试使用 make_ndarray,我会得到一个 AttributeError
:'Tensor' object has no attribute 'tensor_shape'
这是因为 Dataset.map 没有使用 eager 模式吗?。关于如何处理这个问题的任何想法?
更新#1
我试过建议tf.numpy_function,如下
def augment_fn(self):
def augment(images, labels):
images = tf.numpy_function(self.augmenter.augment_images,
[images],
images.dtype)
return images, labels
return augment
但是,生成的图像具有未知形状,这会导致以后出现其他错误。如何保持图像的原始形状?在应用增强功能之前,我的一批图像的形状为 (batch_size, None, None, 1)
,但之后的形状为 <unknown>
更新 #2
我通过首先找到图像的动态(真实)形状然后重塑应用增强的结果解决了未知形状的问题
def augment_fn(self):
def augment(images, labels):
img_dtype = images.dtype
img_shape = tf.shape(images)
images = tf.numpy_function(self.augmenter.augment_images,
[images],
img_dtype)
images = tf.reshape(images, shape = img_shape)
return images, labels
return augment
Is this due to non using eager mode? I thought Eager mode was default in TF2.0. Any ideas on how to approach this?
是的,数据集预处理不在eager模式下执行。我认为,如果您认为数据集可以表示任意大(甚至无限)的数据流,那么这是经过深思熟虑的并且肯定是有意义的。
假设你不possible/practical将你正在做的增强转化为tensorflow操作(这将是第一选择!)那么你可以使用tf.numpy_function
执行任意python 代码(这是现在已弃用的 tf.py_func
的替代品)
请转至 TF Dataset documentation 了解为什么在使用 tf.py_function
时需要 return 图像形状
def tf_random_rotate_image(image, label):
im_shape = image.shape
[image,] = tf.py_function(random_rotate_image, [image], [tf.float32])
image.set_shape(im_shape)
return image, label
我有一个带有输入管道的应用程序,该管道使用 tf.data.Dataset
图像和标签。现在我想使用扩充,并且我正在尝试使用 imgaug 库来达到这个目的。但是,我不知道该怎么做。我找到的所有示例都使用 Keras ImageDataGenerator
或 Sequence
.
在代码中,给定一个像这样的顺序增强器
self.augmenter = iaa.Sequential([
iaa.Fliplr(config.sometimes),
iaa.Crop(percent=config.crop_percent),
...
], random_order=config.random_order)
我正在尝试将该增强器应用于我的数据集中的成批图像,但没有成功。似乎我无法评估张量,因为我是 运行 我在 map 函数中的扩充。
def augment_dataset(self, dataset):
dataset = dataset.map(self.augment_fn())
return dataset
def augment_fn(self):
def augment(images, labels):
img_array = tf.make_ndarray(images)
images = self.augmenter.augment_images(img_array)
return images, labels
return augment
例如,如果我尝试使用 make_ndarray,我会得到一个 AttributeError
:'Tensor' object has no attribute 'tensor_shape'
这是因为 Dataset.map 没有使用 eager 模式吗?。关于如何处理这个问题的任何想法?
更新#1
我试过建议tf.numpy_function,如下
def augment_fn(self):
def augment(images, labels):
images = tf.numpy_function(self.augmenter.augment_images,
[images],
images.dtype)
return images, labels
return augment
但是,生成的图像具有未知形状,这会导致以后出现其他错误。如何保持图像的原始形状?在应用增强功能之前,我的一批图像的形状为 (batch_size, None, None, 1)
,但之后的形状为 <unknown>
更新 #2
我通过首先找到图像的动态(真实)形状然后重塑应用增强的结果解决了未知形状的问题
def augment_fn(self):
def augment(images, labels):
img_dtype = images.dtype
img_shape = tf.shape(images)
images = tf.numpy_function(self.augmenter.augment_images,
[images],
img_dtype)
images = tf.reshape(images, shape = img_shape)
return images, labels
return augment
Is this due to non using eager mode? I thought Eager mode was default in TF2.0. Any ideas on how to approach this?
是的,数据集预处理不在eager模式下执行。我认为,如果您认为数据集可以表示任意大(甚至无限)的数据流,那么这是经过深思熟虑的并且肯定是有意义的。
假设你不possible/practical将你正在做的增强转化为tensorflow操作(这将是第一选择!)那么你可以使用tf.numpy_function
执行任意python 代码(这是现在已弃用的 tf.py_func
的替代品)
请转至 TF Dataset documentation 了解为什么在使用 tf.py_function
时需要 return 图像形状def tf_random_rotate_image(image, label):
im_shape = image.shape
[image,] = tf.py_function(random_rotate_image, [image], [tf.float32])
image.set_shape(im_shape)
return image, label