论文地址:mixup: BEYOND EMPIRICAL RISK MINIMIZATION

(一)、什么是数据增强?
(1). 数据增强主要指在计算机视觉领域中对图像进行数据增强,从而弥补训练图像数据集不足,达到对训练数据扩充的目的。
(2). 数据增强是一种数据扩充方法,可分为同类增强(如:翻转、旋转、缩放、移位、模糊等)和混类增强(如mixup)两种方式。

(二)、同类数据增强方式主要有哪些?
(1). 翻转Flip
可分为水平翻转,垂直翻转

(2). 旋转Rotation

(3). 缩放Scale(向外缩放,向内缩放)
向外缩放时,最终图像尺寸将大于原始图像尺寸,大多数图像框架从新图像中剪切出一个部分,其大小等于原始图像。而向内缩放,因为它会缩小图像大小,迫使我们对超出边界的内容做出假设。

(4). 随机裁剪(Random Crop)
与缩放不同,随机裁剪只是从原始图像中随机抽样一个部分,然后我们将此部分的大小调整为原始图像大小。

(5). 移位(Translation)
移位只涉及沿X或Y方向(或两者)移动图像。这种增强方法非常有用,因为大多数对象几乎可以位于图像的任何位置,移位时我们需要对边界作出假设。

(6). 模糊(Gaussian Noise)
当您的神经网络试图学习可能无用的高频特征(大量出现的特征)时,通常会发生过拟合。具有零均值的高斯噪声基本上在所有频率中具有数据点,从而有效地扭曲高频特征。但是这也意味着较低频率的数据(通常是您的预期数据)也会失真,但您的神经网络可以学会超越它。添加适量的噪声可以增强网络学习能力。

(三)、mixup混类数据增强方式
(1). mixup介绍
mixup是一种运用在计算机视觉中的对图像进行混类增强的算法,它可以将不同类之间的图像进行混合,从而扩充训练数据集。

(2). mixup原理
假设b a t c h x 1 batch_{x1}batchx1是一个b a t c h batchbatch样本,b a t c h y 1 batch_{y1}batchy1是该b a t c h batchbatch样本对应的标签;b a t c h x 2 batch_{x2}batchx2是另一个b a t c h batchbatch样本,b a t c h y 2 batch_{y2}batchy2是该b a t c h batchbatch样本对应的标签,λ lambdaλ是由参数为α alphaα,β etaβ的贝塔分布计算出来的混合系数,由此我们可以得到mixup原理公式为:λ = B e t a ( α , β ) (3.1) {lambda=Beta(alpha,eta) ag{3.1}}λ=Beta(α,β)(3.1)m i x e d _ b a t c h x = λ ∗ b a t c h x 1 + ( 1 − λ ) ∗ b a t c h x 2 (3.2) mixed\_ batch_x=lambda*batch_{x1}+(1-lambda)*batch_{x2} ag{3.2}mixed_batchx=λbatchx1+(1λ)batchx2(3.2)m i x e d _ b a t c h y = λ ∗ b a t c h y 1 + ( 1 − λ ) ∗ b a t c h y 2 (3.3) {mixed\_batch_y=lambda*batch_{y1}+(1-lambda)*batch_{y_2}} ag{3.3}mixed_batchy=λbatchy1+(1λ)batchy2(3.3)其中B e t a BetaBeta指的是贝塔分布,m i x e d _ b a t c h x mixed\_batch_xmixed_batchx是混合后的b a t c h batchbatch样本,m i x e d _ b a t c h y mixed\_batch_{y}mixed_batchy是混合后的b a t c h batchbatch样本对应的标签。

需要说明几点:
1.在论文作者多组实验中,无论如何设置α alphaα,β etaβ的值,期望α α + β frac{alpha}{alpha+eta}α+βα始终近似为0.5。这可能是由于权重λ lambdaλ在每个batch样本都会随机产生,在整个训练过程中会有N个batch,权重在N个batch中期望近似为0.5。所以作者认为产生b a t c h x 1 batch_{x1}batchx1b a t c h x 2 batch_{x2}batchx2样本混合权重λ lambdaλ的Beta分布参数α = β = 0.5 alpha=eta=0.5α=β=0.5时,算法效果相对较好。Beta分布如下图:
数据增强之mixup算法详解-冯金伟博客园

3.1 Beta分布

 
2.b a t c h x 1 batch_{x1}batchx1b a t c h x 2 batch_{x2}batchx2没有太多的限制,当b a t c h   s i z e batch sizebatch size=1时,就是两张图片样本混合;当b a t c h   s i z e batch sizebatch size>1时,便是两个b a t c h batchbatch图片样本两两对应混合。此外,b a t c h x 1 batch_{x1}batchx1b a t c h x 2 batch_{x2}batchx2可以是同一批样本,也可以是不同批样本。一般在代码实现过程中,两个b a t c h batchbatch图片是同一批样本,唯一不同的是,b a t c h x 1 batch_{x1}batchx1是原始b a t c h batchbatch图片样本,而b a t c h x 2 batch_{x2}batchx2是对b a t c h x 1 batch_{x1}batchx1b a t c h   s i z e batch sizebatch size维度进行shuffle后得到的。

3.mixup原理大致如上,在实际代码实现过程中可能略有不同,需要灵活处理。

(3). mixup代码实现
mixup代码实现部分如下:

###############################author:qiu#################################

########################修改位置1:config.configurations#########################
#在代码配置config中添加以下键值信息:
USE_MIXUP=True,  #是否使用mixup方法增强数据集
MIXUP_ALPHA = 0.5,#add mixup alpha ,用于beta分布
##########################################################################

#######################修改位置2:添加mixup.py文件############################
import numpy as np
import torch
import torch.nn as nn
from loss.focal import FocalLoss
LOSS=FocalLoss()

def criterion(batch_x, batch_y, alpha=1.0, use_cuda=True):
    '''
    batch_x:批样本数,shape=[batch_size,channels,width,height]
    batch_y:批样本标签,shape=[batch_size]
    alpha:生成lam的beta分布参数,一般取0.5效果较好
    use_cuda:是否使用cuda
    
    returns:
    	mixed inputs, pairs of targets, and lam
    '''
    
    if alpha > 0:
    	#alpha=0.5使得lam有较大概率取0或1附近
        lam = np.random.beta(alpha, alpha)
    else:
        lam = 1
    batch_size = batch_x.size()[0]
    if use_cuda:
        index = torch.randperm(batch_size).cuda()
    else:
        index = torch.randperm(batch_size) #生成打乱的batch_size索引
	
	#获得混合的mixed_batchx数据,可以是同类(同张图片)混合,也可以是异类(不同图片)混合
	mixed_batchx = lam * batch_x + (1 - lam) * batch_x[index, :]
	
	"""
	Example:
	假设batch_x.shape=[2,3,112,112],batch_size=2时,
	如果index=[0,1]的话,则可看成mixed_batchx=lam*[[0,1],3,112,112]+(1-lam)*[[0,1],3,112,112]=[[0,1],3,112,112],即为同类混合
	如果index=[1,0]的话,则可看成mixed_batchx=lam*[[0,1],3,112,112]+(1-lam)*[[1,0],3,112,112]=[batch_size,3,112,112],即为异类混合
	"""
    batch_ya, batch_yb = batch_y, batch_y[index]
    return mixed_batchx, batch_ya, batch_yb, lam


def mixup_criterion(criterion, inputs, batch_ya, batch_yb, lam):
    return lam * criterion(inputs, batch_ya) + (1 - lam) * criterion(inputs, batch_yb)
##########################################################################

#####################修改位置3:train.py文件修改代码如下######################
if torch.cuda.is_available() and DEVICE.type=="cuda":  #add
	inputs, targets = inputs.cuda(), targets.cuda()   
else:
	inputs = inputs.to(DEVICE)
	targets = targets.to(DEVICE).long()                   
	
if cfg['USE_MIXUP']:
	inputs, targets_a, targets_b, lam = mixup.mixup_data(
		inputs,targets,cfg["MIXUP_ALPHA"], torch.cuda.is_available())  
	
	#映射为Variable
	inputs, targets_a, targets_b = map(Variable, (inputs,targets_a,targets_b))
	#抽取特征,BACKBONE为粗特征抽取网络
	features = BACKBONE(inputs)   
	#抽取特征,HEAD为精细的特征抽取网络
	outputs = mixup.mixup_criterion(HEAD, features, targets_a, targets_b, lam)
	loss = mixup.mixup_criterion(LOSS, outputs, targets_a, targets_b, lam)             
else:
	features = BACKBONE(inputs)  
	outputs = HEAD(features, targets)                     
	loss = FocalLoss(outputs, labels)     
##########################################################################