Keras 的数据增强实验层到底在做什么?

数据挖掘 喀拉斯 张量流 图像分类 图像预处理 数据增强
2022-01-24 18:35:01

根据我收集到的信息,数据增强包括通过应用一些转换来增加数据集中的实例数量。假设我想对图像进行分类。图像的数据集中的每个图像应用随机旋转,我将获得一个包含图像的新数据集,对原始图像加上它的随机旋转对应物。n2nn

假设这是真的,我不明白与数据增强相关的 keras 实验层在做什么。

tf.keras.layers.experimental.preprocessing.RandomRotation 图像分类教程中,它把这一层放在了 Sequential 模型中,如下所示:

model = Sequential([
  layers.experimental.preprocessing.RandomFlip("horizontal", 
                                                 input_shape=(img_height, 
                                                              img_width,
                                                              3)),
  layers.experimental.preprocessing.Rescaling(1./255),
  layers.Conv2D(16, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(64, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Dropout(0.2),
  layers.Flatten(),
  layers.Dense(128, activation='relu'),
  layers.Dense(num_classes)
])

这已经有点奇怪了,因为一个层(显然)从输入产生输出,但它不会复制图像。无论如何,我决定在文档中检查这一点,实际上,这就是正在发生的事情。

Init signature: layers.experimental.preprocessing.RandomRotation(*args, **kwargs)
Docstring:     
Randomly rotate each image.

By default, random rotations are only applied during training.
At inference time, the layer does nothing. If you need to apply random
rotations at inference time, set `training` to True when calling the layer.

Input shape:
  4D tensor with shape:
  `(samples, height, width, channels)`, data_format='channels_last'.

Output shape:
  4D tensor with shape:
  `(samples, height, width, channels)`, data_format='channels_last'.

因此,我知道我只是随机旋转图像,即更改数据集中的每个图像,但我没有做任何数据增强。但是,我发现这没有任何意义,否则他们不会将其作为数据增强程序提及。那么我错过了什么?

1个回答

如果您查看代码,您可以弄清楚到底发生了什么。

举个tf.keras.layers.experimental.preprocessing.RandomRotation例子

def call(self, inputs, training=True):
  ...
  def random_flipped_inputs():
    flipped_outputs = inputs
    if self.horizontal:
      flipped_outputs = image_ops.random_flip_left_right(flipped_outputs,
                                                         self.seed)
    ...
    return flipped_outputs

你会random_flip_left_right在你的输入图像上看到它,里面的评论是

"""Randomly flip an image horizontally (left to right).
With a 1 in 2 chance, outputs the contents of `image` flipped along the
second dimension, which is `width`.  Otherwise output the image as-is.
When passing a batch of images, each image will be randomly flipped
independent of other images."""
Example usage:
...
>>> images = np.array(
... [
...     [[[1], [2]], [[3], [4]]],
...     [[[5], [6]], [[7], [8]]]
... ])
>>> tf.image.random_flip_left_right(images, 6).numpy().tolist()
[[[[2], [1]], [[4], [3]]], [[[5], [6]], [[7], [8]]]]

所以基本上它所做的是每个图像将有 50% 的机会水平翻转,所以如果你有 10 个 epoch,image_1 将有可能是 [original,flipped,original,flipped,...],依此类推以此类推到其他图像。从外部看会发现我们有 10 个不同的数据集(特别是在多个数据增强上)。