1

我正在研究用于对象检测的区域建议网络。如果我想增加我的数据,我需要增加图像和相应的边界框(例如缩放、旋转等)+ 我还有图像掩码作为输入,我也需要增加它。所以我为数据增强制作了自定义函数。

管道如下:

  1. 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)

代码继续进行一些额外的扩展,但这部分很重要,因为当我添加扩充时,它开始导致内存泄漏。

  1. 函数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
    )
  1. 函数aug.shrink(tensor: tf.Tensor, vertical: float = 1, horizontal: float = 1)根据verticalhorizontal比率调整图像、标签和蒙版的大小。我的网络接受图像的动态大小(使用原因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 的组合来调整大小,但它不起作用。有没有人遇到过这样的问题?

谢谢您的帮助。

4

0 回答 0