在计算机视觉领域,经常面临数据不足的问题,这限制了模型的泛化能力。为了解决这个问题,采用了数据增强技术,它通过扩展现有数据集来创建新的训练样本,从而帮助机器学习模型更好地泛化。数据增强的一种常见方法是随机裁剪,这种方法通过从原始图像中创建随机子集来帮助模型更好地泛化,因为训练数据中的物体并不总是完全可见或以相同的比例出现。
随机裁剪是一种数据增强技术,它通过从原始图像中随机选择一个子集来创建新的训练样本。这种方法对于训练识别图像中的物体特别有用,因为物体在图像中的位置和大小可能会有很大的变化。例如,如果正在训练一个用于识别院子里的浣熊的深度学习模型,可能会使用一个摄像头实时传输图像到一个目标检测模型,该模型会在检测到浣熊时报告。在这种情况下,浣熊并不总是完全在画面中,也不总是与摄像头保持相同的距离。因此,随机裁剪是一个很好的数据增强技术选择。
在更一般的情况下,大多数移动应用中的计算机视觉模型示例也可能从随机裁剪数据增强中受益。用户可能会将手机以不同的距离对准想要识别的物体,而这些物体并不总是完全在画面中。
可以执行多种随机裁剪的变体,这些实现也取决于正在解决的计算机视觉问题的类型。需要考虑的问题包括:想要裁剪多少图像?否每次都想要相同大小的裁剪?如果裁剪包含边界框的图像,那么边界框的哪个区域必须出现在结果图像中,以便边界框仍然有效?
在最基本的情况下,对于不需要担心边界框或分割注释的分类问题,正在创建图像的随机子集。会设置裁剪的期望输出区域,确定随机的输出坐标,并执行裁剪。
即使在这个简单的例子中,也存在一个问题:随机确定的(X,Y)坐标,定义了输出图像中心,实际上不能是输入图像上的任何位置。输出裁剪图像需要是原始图像的一个完全子集。如果随机选择的中心坐标在输入图像的边缘,输出将需要填充以达到真正期望的尺寸。
许多框架,如TensorFlow、PyTorch和FastAI,都包含了随机裁剪的开源实现。(值得注意的是,Keras目前还没有随机裁剪的实现。)例如,要利用TensorFlow,会编写一个如下的Python函数来处理RGB图像:
def random_crop(image):
cropped_image = tf.image.random_crop(
image, size=[NEW_IMG_HEIGHT, NEW_IMG_WIDTH, 3])
return cropped_image
如果目标是将随机裁剪应用于目标检测问题,还必须处理更新边界框。具体来说,如果新裁剪的图像包含一个完全在框架外的注释,应该丢弃该注释。如果注释部分在框架内,需要裁剪注释以与新创建的框架边缘对齐。
这正是Roboflow在同时调整图像大小时实现随机裁剪的方式。回到浣熊示例,可能有如下的图像:
它非常可爱。可在查看。
在Roboflow中,如果选择随机裁剪50%(保留原始图像像素的50%)再加上调整大小到416x416,会得到这样的结果:
这个确切的版本可在查看。
请注意,在这种情况下,原始的浣熊边界框需要被裁剪以仍然是一个有效的注释。延伸到框架外的注释会在模型训练中抛出错误。
如果想查看这个确切版本的浣熊数据集,包括所选的调整大小设置,它是公开可用的。(注意:可以分叉这个浣熊数据集,并修改自己的图像预处理和增强步骤。)
如果目标是将裁剪应用于语义分割,需要以与图像(X,Y)调整相同的比例处理掩码。GitHub用户wouterdewinter提供了如下的示例:
def random_crop(img, mask, width, height):
assert img.shape[0] >= height
assert img.shape[1] >= width
assert img.shape[0] == mask.shape[0]
assert img.shape[1] == mask.shape[1]
x = random.randint(0, img.shape[1] - width)
y = random.randint(0, img.shape[0] - height)
img = img[y:y+height, x:x+width]
mask = mask[y:y+height, x:x+width]
return img, mask
目前正在进行研究,以从多类问题中裁剪在一起的图像创建新的数据。例如,随机图像裁剪和拼接(RICAP)将各种输入图像的部分组合成单个图像,并为图像提供混合的类标签,这带来了类似于标签平滑的优势。
阅读。