本文介绍一种新的数据扩展方法mixup
。
1. mixup原理
mixup
是一种对图像进行混类增强的算法,它可以将不同类之间的图像以线性插值的方式进行混合,从而构建新的训练样本,扩充训练数据集。
其中,(xi,yi)
和(xj,yj)
是从训练数据中随机抽取的两个样本,且λ∈[0,1]
。
- 对于输入的一个
batch
的待测图片images
,我们将其和随机抽取的图片按照系数λ
加权相加,λ∈[0,1]
,符合beta
分布 - 将1中得到的混合张量
inputs
传递给模型得到输出张量outputs
- 计算损失函数时,针对两个图片的标签分别计算损失函数,然后按照比例
λ
进行损失函数的加权求和,即
for i,(images,target) in enumerate(train_loader):
# 加载第一张图片和标签
images = images.cuda(non_blocking=True)
target = torch.from_numpy(np.array(target)).float().cuda(non_blocking=True)
# 加载参数
alpha = config.alpha
lam = np.random.beta(alpha,alpha)
# 用来融合的图片的序号
index = torch.randperm(images.size(0)).cuda()
# 将两张图片按照比例系数lam加权求和
inputs = lam*images + (1-lam)*images[index,:]
# 两张图片的标签
targets_a, targets_b = target, target[index]
# 将融合后的图片输入给网络
outputs = model(inputs)
# 损失函数按照比例系数lam加权求和
loss = lam * criterion(outputs, targets_a) + (1 - lam) * criterion(outputs, targets_b)
# 梯度更新
optimizer.zero_grad() # reset gradient
loss.backward()
optimizer.step() # update parameters of net
我们可视化mixup
这个过程,两张图片的mixup
结果随着lam
的变化而发生渐变:
for i in range(1,10):
lam= i*0.1
im_mixup = (im1*lam+im2*(1-lam)).astype(np.uint8)
plt.subplot(3,3,i)
plt.imshow(im_mixup)
plt.show()
实际代码中的lam
由随机数生成器控制,lam
符合参数为(alpha,alpha)
的beta
分布,默认取alpha=1
,这里的alpha
是一个超参数,alpha
的值越大,生成的lam
偏向0.5
的可能性更高。
2. 目标检测中应用mixup的例子
对于目标检测的话,步骤:
- 图1和图2按照比例
lam
进行线性融合 - 送入模型进行检测
- 分别按标签计算损失函数,按照
lam
加权相加得到最终的损失函数。