python - 如何为图像分类中的马赛克增强创建类标签?
问题描述
CutMix
要在或MixUp
类型扩充中创建类标签,我们可以使用beta
诸如np.random.beta
orscipy.stats.beta
并对两个标签执行以下操作:
label = label_one*beta + (1-beta)*label_two
但是如果我们有两个以上的图像呢?在YoLo4中,他们尝试了一种有趣的增强,称为Mosaic Augmentation来解决对象检测问题。与CutMix
or不同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)
然而,这里有更多的例子来激励你。数据来自木薯叶比赛。
解决方案
我们已经知道,在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
推荐阅读
- python - mysql.connector.errors.ProgrammingError: 1064 (42000
- ios - textFieldDidChange 和 shouldChangeCharactersIn 方法的主要区别是什么,UITextFieldDelegate 的委托?
- python - 类对象被引用为字符串
- javascript - 电容Android不加载http javascript源
- javascript - 尝试生成 Irfan View 以缩小图像时出现 ENOENT 错误
- javascript - 如何在反应中使用数组获取数据?
- python - 无法使用 folium 创建地图
- pycharm - “TypeError: __init__() 需要 2 到 3 个位置参数,但给出了 9 个”但我在一个新的项目文件中进行了测试并且工作正常
- android-studio - 升级后查找在 Android Studio 中不起作用的用法(查看 --> 工具窗口缺少多个选项)
- reactjs - Webpack 输出的 .js 文件不会更新 React 组件的代码