如何使用 tensorflow_datasets (tfds) 实施和理解预处理和数据扩充?
How to implement and understand Pre-processing and Data augmentation with tensorflow_datasets (tfds)?
我正在学习基于这个 TF 2.0 tutorial 的分割和数据增强,它使用 Oxford-IIIT Pets.
对于 pre-processing/data 扩充,他们向特定管道提供了一组函数:
# Import dataset
dataset, info = tfds.load('oxford_iiit_pet:3.*.*', with_info=True)
def normalize(input_image, input_mask):
input_image = tf.cast(input_image, tf.float32) / 255.0
input_mask -= 1
return input_image, input_mask
@tf.function
def load_image_train(datapoint):
input_image = tf.image.resize(datapoint['image'], (128, 128))
input_mask = tf.image.resize(datapoint['segmentation_mask'], (128, 128))
if tf.random.uniform(()) > 0.5:
input_image = tf.image.flip_left_right(input_image)
input_mask = tf.image.flip_left_right(input_mask)
input_image, input_mask = normalize(input_image, input_mask)
return input_image, input_mask
TRAIN_LENGTH = info.splits['train'].num_examples
BATCH_SIZE = 64
BUFFER_SIZE = 1000
STEPS_PER_EPOCH = TRAIN_LENGTH // BATCH_SIZE
train = dataset['train'].map(load_image_train, num_parallel_calls=tf.data.experimental.AUTOTUNE)
train_dataset = train.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()
train_dataset = train_dataset.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
考虑到 tf 语法,这段代码给我带来了一些疑问。为了防止我只是执行 ctrl C ctrl V 并真正了解 tensorflow 的工作原理,我想问一些问题:
1) 在normalize
函数中,tf.cast(input_image, tf.float32) / 255.0
行可以通过tf.image.convert_image_dtype(input_image, tf.float32)
?
改变
2) 在 normalize
函数中可以更改 tf.tensor
格式的 segmentation_mask 值而不用更改为 numpy
?我想要做的是只使用两个可能的掩码(0 和 1)而不是(0、1 和 2)。使用 numpy 我做了这样的事情:
segmentation_mask_numpy = segmentation_mask.numpy()
segmentation_mask_numpy[(segmentation_mask_numpy == 2) | (segmentation_mask_numpy == 3)] = 0
是否可以在没有 numpy 转换的情况下做到这一点?
3) 在 load_image_train
函数中他们说这个函数正在做数据扩充,但是 怎么做?在我看来,他们正在通过给定随机数的翻转来更改原始图像,而不是向基于原始图像的数据集提供另一个图像。那么,功能目标是更改图像而不是将 aug_image 保留原始图像添加到我的数据集中?如果我是正确的,我该如何更改此函数以提供 aug_image 并将我的原始图像保留在数据集中?
4) 在其他问题中,例如 and 他们使用了很多 .map()
顺序调用或 .map().map().cache().batch().repeat()
。我的问题是:有这个必要吗?存在更简单的方法来做到这一点?我尝试阅读 tf 文档,但没有成功。
5) 您建议使用来自 keras 的 ImageDataGenerator
,如前所述 here 或者这种 tf 方法更好?
4 - 这些顺序调用的作用是它们 简化了 我们 操纵数据集 到 应用的工作转换,他们还声称这是一种更高效的加载和处理数据的方式。关于 modularization/simplicity 我想它完成了它的工作,因为 你可以轻松加载 ,将它传递到整个 预处理管道 ,随机播放,并迭代批次数据用几行代码.
train_dataset =tf.data.TFRecordDataset(filenames=train_records_paths).map(parsing_fn)
train_dataset = train_dataset.shuffle(buffer_size=12000)
train_dataset = train_dataset.batch(batch_size)
train_dataset = train_dataset.repeat()
# Create a test dataset
test_dataset = tf.data.TFRecordDataset(filenames=test_records_paths).map(parsing_fn)
test_dataset = test_dataset.batch(batch_size)
test_dataset = test_dataset.repeat(1)
#
validation_steps = test_size / batch_size
history = transferred_resnet50.fit(x=train_dataset,
epochs=epochs,
steps_per_epoch=steps_per_epoch,
validation_data=test_dataset,
validation_steps=validation_steps)
例如,为了加载我的数据集并为我的模型提供预处理数据,我只需要做这些。
3 - 他们定义了一个预处理函数,他们的数据集映射到该函数,这意味着每次请求样本时都会应用映射函数,就像我使用解析函数一样为了在使用之前从 TFRecord 格式解析我的数据:
def parsing_fn(serialized):
features = \
{
'image': tf.io.FixedLenFeature([], tf.string),
'label': tf.io.FixedLenFeature([], tf.int64)
}
# Parse the serialized data so we get a dict with our data.
parsed_example = tf.io.parse_single_example(serialized=serialized,
features=features)
# Get the image as raw bytes.
image_raw = parsed_example['image']
# Decode the raw bytes so it becomes a tensor with type.
image = tf.io.decode_jpeg(image_raw)
image = tf.image.resize(image,size=[224,224])
# Get the label associated with the image.
label = parsed_example['label']
# The image and label are now correct TensorFlow types.
return image, label
(另一个例子) - 从上面的解析函数我可以使用下面的代码 为了创建数据集,遍历我的测试集图像 并绘制它们。
records_path = DATA_DIR+'/'+'TFRecords'+'/test/'+'test_0.tfrecord'
# Create a dataset
dataset = tf.data.TFRecordDataset(filenames=records_path)
# Parse the dataset using a parsing function
parsed_dataset = dataset.map(parsing_fn)
# Gets a sample from the iterator
iterator = tf.compat.v1.data.make_one_shot_iterator(parsed_dataset)
for i in range(100):
image,label = iterator.get_next()
img_array = image.numpy()
img_array = img_array.astype(np.uint8)
plt.imshow(img_array)
plt.show()
我正在学习基于这个 TF 2.0 tutorial 的分割和数据增强,它使用 Oxford-IIIT Pets.
对于 pre-processing/data 扩充,他们向特定管道提供了一组函数:
# Import dataset
dataset, info = tfds.load('oxford_iiit_pet:3.*.*', with_info=True)
def normalize(input_image, input_mask):
input_image = tf.cast(input_image, tf.float32) / 255.0
input_mask -= 1
return input_image, input_mask
@tf.function
def load_image_train(datapoint):
input_image = tf.image.resize(datapoint['image'], (128, 128))
input_mask = tf.image.resize(datapoint['segmentation_mask'], (128, 128))
if tf.random.uniform(()) > 0.5:
input_image = tf.image.flip_left_right(input_image)
input_mask = tf.image.flip_left_right(input_mask)
input_image, input_mask = normalize(input_image, input_mask)
return input_image, input_mask
TRAIN_LENGTH = info.splits['train'].num_examples
BATCH_SIZE = 64
BUFFER_SIZE = 1000
STEPS_PER_EPOCH = TRAIN_LENGTH // BATCH_SIZE
train = dataset['train'].map(load_image_train, num_parallel_calls=tf.data.experimental.AUTOTUNE)
train_dataset = train.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()
train_dataset = train_dataset.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
考虑到 tf 语法,这段代码给我带来了一些疑问。为了防止我只是执行 ctrl C ctrl V 并真正了解 tensorflow 的工作原理,我想问一些问题:
1) 在normalize
函数中,tf.cast(input_image, tf.float32) / 255.0
行可以通过tf.image.convert_image_dtype(input_image, tf.float32)
?
2) 在 normalize
函数中可以更改 tf.tensor
格式的 segmentation_mask 值而不用更改为 numpy
?我想要做的是只使用两个可能的掩码(0 和 1)而不是(0、1 和 2)。使用 numpy 我做了这样的事情:
segmentation_mask_numpy = segmentation_mask.numpy()
segmentation_mask_numpy[(segmentation_mask_numpy == 2) | (segmentation_mask_numpy == 3)] = 0
是否可以在没有 numpy 转换的情况下做到这一点?
3) 在 load_image_train
函数中他们说这个函数正在做数据扩充,但是 怎么做?在我看来,他们正在通过给定随机数的翻转来更改原始图像,而不是向基于原始图像的数据集提供另一个图像。那么,功能目标是更改图像而不是将 aug_image 保留原始图像添加到我的数据集中?如果我是正确的,我该如何更改此函数以提供 aug_image 并将我的原始图像保留在数据集中?
4) 在其他问题中,例如 .map()
顺序调用或 .map().map().cache().batch().repeat()
。我的问题是:有这个必要吗?存在更简单的方法来做到这一点?我尝试阅读 tf 文档,但没有成功。
5) 您建议使用来自 keras 的 ImageDataGenerator
,如前所述 here 或者这种 tf 方法更好?
4 - 这些顺序调用的作用是它们 简化了 我们 操纵数据集 到 应用的工作转换,他们还声称这是一种更高效的加载和处理数据的方式。关于 modularization/simplicity 我想它完成了它的工作,因为 你可以轻松加载 ,将它传递到整个 预处理管道 ,随机播放,并迭代批次数据用几行代码.
train_dataset =tf.data.TFRecordDataset(filenames=train_records_paths).map(parsing_fn)
train_dataset = train_dataset.shuffle(buffer_size=12000)
train_dataset = train_dataset.batch(batch_size)
train_dataset = train_dataset.repeat()
# Create a test dataset
test_dataset = tf.data.TFRecordDataset(filenames=test_records_paths).map(parsing_fn)
test_dataset = test_dataset.batch(batch_size)
test_dataset = test_dataset.repeat(1)
#
validation_steps = test_size / batch_size
history = transferred_resnet50.fit(x=train_dataset,
epochs=epochs,
steps_per_epoch=steps_per_epoch,
validation_data=test_dataset,
validation_steps=validation_steps)
例如,为了加载我的数据集并为我的模型提供预处理数据,我只需要做这些。
3 - 他们定义了一个预处理函数,他们的数据集映射到该函数,这意味着每次请求样本时都会应用映射函数,就像我使用解析函数一样为了在使用之前从 TFRecord 格式解析我的数据:
def parsing_fn(serialized):
features = \
{
'image': tf.io.FixedLenFeature([], tf.string),
'label': tf.io.FixedLenFeature([], tf.int64)
}
# Parse the serialized data so we get a dict with our data.
parsed_example = tf.io.parse_single_example(serialized=serialized,
features=features)
# Get the image as raw bytes.
image_raw = parsed_example['image']
# Decode the raw bytes so it becomes a tensor with type.
image = tf.io.decode_jpeg(image_raw)
image = tf.image.resize(image,size=[224,224])
# Get the label associated with the image.
label = parsed_example['label']
# The image and label are now correct TensorFlow types.
return image, label
(另一个例子) - 从上面的解析函数我可以使用下面的代码 为了创建数据集,遍历我的测试集图像 并绘制它们。
records_path = DATA_DIR+'/'+'TFRecords'+'/test/'+'test_0.tfrecord'
# Create a dataset
dataset = tf.data.TFRecordDataset(filenames=records_path)
# Parse the dataset using a parsing function
parsed_dataset = dataset.map(parsing_fn)
# Gets a sample from the iterator
iterator = tf.compat.v1.data.make_one_shot_iterator(parsed_dataset)
for i in range(100):
image,label = iterator.get_next()
img_array = image.numpy()
img_array = img_array.astype(np.uint8)
plt.imshow(img_array)
plt.show()