首页 > 解决方案 > 如何为图像分类中的马赛克增强创建类标签?

问题描述

CutMix要在或MixUp类型扩充中创建类标签,我们可以使用beta诸如np.random.betaorscipy.stats.beta并对两个标签执行以下操作:

label = label_one*beta + (1-beta)*label_two

但是如果我们有两个以上的图像呢?在YoLo4中,他们尝试了一种有趣的增强,称为Mosaic Augmentation来解决对象检测问题。与CutMixor不同MixUp,此增强创建具有4 个图像的增强样本。在目标检测案例中,我们可以计算每个实例坐标的偏移,从而可以得到正确的基本事实,这里。但是对于只有图像分类的情况,我们该怎么做呢?

这是一个开胃菜

import tensorflow as tf
import matplotlib.pyplot as plt 
import random

(train_images, train_labels), (test_images, test_labels) = \
tf.keras.datasets.cifar10.load_data()
train_images = train_images[:10,:,:]
train_labels = train_labels[:10]
train_images.shape, train_labels.shape

((10, 32, 32, 3), (10, 1))

这是我们为此增强编写的函数;(“内-外循环”太丑了!请建议我们是否可以有效地做到这一点。)

def mosaicmix(image, label, DIM, minfrac=0.25, maxfrac=0.75):
    '''image, label: batches of samples 
    '''
    xc, yc  = np.random.randint(DIM * minfrac, DIM * maxfrac, (2,))
    indices = np.random.permutation(int(image.shape[0]))
    mosaic_image = np.zeros((DIM, DIM, 3), dtype=np.float32)
    final_imgs, final_lbs = [], []

    # Iterate over the full indices 
    for j in range(len(indices)): 
        # Take 4 sample for to create a mosaic sample randomly 
        rand4indices = [j] + random.sample(list(indices), 3) 
        
        # Make mosaic with 4 samples 
        for i in range(len(rand4indices)):
            if i == 0:    # top left
                x1a, y1a, x2a, y2a =  0,  0, xc, yc
                x1b, y1b, x2b, y2b = DIM - xc, DIM - yc, DIM, DIM # from bottom right        
            elif i == 1:  # top right
                x1a, y1a, x2a, y2a = xc, 0, DIM , yc
                x1b, y1b, x2b, y2b = 0, DIM - yc, DIM - xc, DIM # from bottom left
            elif i == 2:  # bottom left
                x1a, y1a, x2a, y2a = 0, yc, xc, DIM
                x1b, y1b, x2b, y2b = DIM - xc, 0, DIM, DIM-yc   # from top right
            elif i == 3:  # bottom right
                x1a, y1a, x2a, y2a = xc, yc,  DIM, DIM
                x1b, y1b, x2b, y2b = 0, 0, DIM-xc, DIM-yc    # from top left
                
            # Copy-Paste
            mosaic_image[y1a:y2a, x1a:x2a] = image[i,][y1b:y2b, x1b:x2b]

        # Append the Mosiac samples
        final_imgs.append(mosaic_image)
        
    return final_imgs, label

增强的样本,目前带有错误的标签。

data, label = mosaicmix(train_images, train_labels, 32)
plt.imshow(data[5]/255)

在此处输入图像描述


然而,这里有更多的例子来激励你。数据来自木薯叶比赛。

标签: pythontensorflowkeraspytorchdata-augmentation

解决方案


我们已经知道,在CutMix中,λ它是来自 beta 分布 Beta(α,α) 的浮点数。我们已经看到,当 时α=1,它表现最好。现在,如果我们α==1总是授予,我们可以说它λ是从均匀分布中采样的。.

简单地说λ,它只是一个浮点数,其值为 0 到 1。

因此,仅对于2张图像,如果我们使用λ第 1 张图像,那么我们可以简单地计算剩余的未知部分1-λ

但是对于 3 张图像,如果我们使用λ第 1 张图像,我们无法从那张图像中计算出其他 2 个未知数λ。如果我们真的想这样做,我们需要 3 个图像的 2 个随机数。同样,我们可以说,对于n图像的数量,我们需要n-1数字随机变量。在所有情况下,总和应该是1。(例如,λ + (1-λ) == 1)。如果总和不是1,标签将是错误的!

为此, 狄利克雷分布可能会有所帮助,因为它有助于生成总和为 1 的数量。狄利克雷分布的随机变量可以看作是 Beta 分布的多元泛化。

>>> np.random.dirichlet((1, 1), 1)  # for 2 images. Equivalent to λ and (1-λ)
array([[0.92870347, 0.07129653]])  
>>> np.random.dirichlet((1, 1, 1), 1)  # for 3 images.
array([[0.38712673, 0.46132787, 0.1515454 ]])
>>> np.random.dirichlet((1, 1, 1, 1), 1)  # for 4 images.
array([[0.59482542, 0.0185333 , 0.33322484, 0.05341645]])

CutMix中,图像裁剪部分的大小与λ相应标签的权重有关。

在此处输入图像描述

在此处输入图像描述

因此,对于 multiple λ,您还需要相应地计算它们。

# let's say for 4 images
# I am not sure the proper way. 

image_list = [4 images]
label_list = [4 label]
new_img = np.zeros((w, h))

beta_list = np.random.dirichlet((1, 1, 1, 1), 1)[0]
for idx, beta in enumerate(beta_list):
    x0, y0, w, h = get_cropping_params(beta, full_img)  # something like this
    new_img[x0, y0, w, h] = image_list[idx][x0, y0, w, h]
    label_list[idx] = label_list[idx] * beta

推荐阅读