我正在研究用于对象检测的区域建议网络。如果我想增加我的数据,我需要增加图像和相应的边界框(例如缩放、旋转等)+ 我还有图像掩码作为输入,我也需要增加它。所以我为数据增强制作了自定义函数。
管道如下:
- 我
tf.data.Dataset
从 python 生成器创建,其中包含加载的图像、标签(边界框坐标)和掩码:
tf_dataset = tf.data.Dataset.from_generator(lambda: data_generator(img_paths, annotations),
output_shapes={'images': tf.TensorShape([None, None, 3]),
'labels': tf.TensorShape([None, 4]),
'masks': tf.TensorShape([None, None, 1])},
output_types={'images': tf.float32,
'labels': tf.int32,
'masks': tf.uint8})
if use_augument:
tf_dataset = augment_dataset(tf_dataset)
代码继续进行一些额外的扩展,但这部分很重要,因为当我添加扩充时,它开始导致内存泄漏。
- 函数
augment_dataset(tf_dataset)
调用数据集扩充。除了一个增强之外,一切都很好(所有增强都是作为这个进行的,但只有这个会导致非常高的内存泄漏(RAM 使用)):
dataset = dataset.map(
lambda x: tf.cond(
tf.keras.backend.random_uniform([], 0, 1) > 0.0,
lambda: aug.shrink(
x,
vertical=tf.keras.backend.random_uniform([], 0.8, 2),
horizontal=tf.keras.backend.random_uniform([], 0.8, 2)
),
lambda: x
), num_parallel_calls=8
)
- 函数
aug.shrink(tensor: tf.Tensor, vertical: float = 1, horizontal: float = 1)
根据vertical
和horizontal
比率调整图像、标签和蒙版的大小。我的网络接受图像的动态大小(使用原因tf.shape
)和标签(边界框)的格式为(xcenter, ycenter, width, height)
:
def shrink(tensor: tf.Tensor, vertical: float = 1, horizontal: float = 1):
image = tensor['images']
label = tensor['labels']
mask = tensor['masks']
height = tf.cast(tf.shape(image)[0], tf.float32) / vertical
width = tf.cast(tf.shape(image)[1], tf.float32) / horizontal
height = tf.cast(height, tf.int32)
width = tf.cast(width, tf.int32)
# resize image
resize_image = tf.image.resize(image, (height, width))
resize_mask = tf.image.resize(mask, (height, width))
resize_mask = tf.cast(resize_mask, tf.uint8)
div_tensor = [horizontal, vertical, horizontal, vertical]
new_label = tf.math.divide(tf.cast(label, tf.float32), div_tensor)
new_label = tf.cast(new_label, tf.int32)
return {'images' : resize_image, 'labels' : new_label,'masks' : resize_mask}
我还尝试了一个版本tf.py_function
,其中我使用 OpenCV 和 numpy 的组合来调整大小,但它不起作用。有没有人遇到过这样的问题?
谢谢您的帮助。