2023年6月21日发(作者:)
⼀种图像增⼴(ImageAugmentation)⽅式MixUp算法附有代码解析这是对facebook研究团队的⼀篇⽂章 Mixup: Beyond Empirical Risk Minimization 的解读这篇⽂章相对于之前提到的Sample pariring来说就不那么神奇了,因为毕竟⽂章作者在⾥⾯有⼀些相关理论的推导。⽂章开头通篇讲的是ERM也就是经验风险最⼩化原则是整个机器学习遵循的原则,作者正是基于此思想才提出了MixUp的⽅法。在⼀般的机器学习任务中,⽐如分类任务中,对于ERM原则遵循的⼀种变种被称之为相邻风险最⼩化(Vicinal Risk Minimization),VRM实际上是指在训练集周围的邻域内构造⼀些样本参与训练来扩⼤原先的训练数据集的分布,通常情况下认为这些围绕着训练集某个类别⽽扩展的邻域和该类别数据是同属⼀类,并且不研究不同类别样本的邻域之间的关系(这⾥我的理解是,VRM原则是将原来的训练集进⾏邻域扩充,但是某个类别的邻域从属于某个类别,即使是该邻域同另⼀个邻域有相交的地⽅,但也不研究这些相交区域到底该如何规划)。基于上述思想,作者提出混合思路:如上式所述,输⼊样本x进⾏混合,得到⼀个新的样本,于此同时对该样本的标签也按照这样的混合⽅式进⾏混合,这样相当于⽤线性的⽅式获得⼀个原训练集某个类别样本的邻域。我通过对这篇⽂章代码的研究,实际上作者是这样操作的:1. 利⽤上述公式,将训练集中某⼀数据选出x_i,然后随机选出数据x_j,两者按照上述公式进⾏合成,于此同时标签也按照上述公式合成,并且同时可以得到合成⽤的⽐例2. 将这种合成数据送⼊⽹络,获得⽹络的输出3. 将输送⼊loss函数进⾏计算,但是注意此时的loss函数是合成loss,是由y_i和y_j合成的,loss计算分为两部分,先计算模型预测同y_i的loss,然后乘以第⼀步获得的⽐例,然后模型预测同y_j计算loss,乘以1减去第⼀步获得的⽐例,两者求和如下是代码解析:def mixup_data(x, y, alpha=1.0, use_cuda=True): # 对数据的mixup 操作 x = lambda*x_i+(1-lamdda)*x_j '''Returns mixed inputs, pairs of targets, and lambda''' if alpha > 0: lam = (alpha, alpha) else: lam = 1 batch_size = ()[0] if use_cuda: index = rm(batch_size).cuda() else: index = rm(batch_size) mixed_x = lam * x + (1 - lam) * x[index, :] # 此处是对数据x_i 进⾏操作 y_a, y_b = y, y[index] # 记录下y_i 和y_j return mixed_x, y_a, y_b, lam # 返回y_i 和y_j 以及lambdadef mixup_criterion(criterion, pred, y_a, y_b, lam): # 对loss函数进⾏混合,criterion是crossEntropy函数 return lam * criterion(pred, y_a) + (1 - lam) * criterion(pred, y_b)def train(epoch): print('nEpoch: %d' % epoch) () train_loss = 0 reg_loss = 0 correct = 0 total = 0 for batch_idx, (inputs, targets) in enumerate(trainloader): if use_cuda: inputs, targets = (), () inputs, targets_a, targets_b, lam = mixup_data(inputs, targets, , use_cuda) # 对数据集进⾏mixup操作 inputs, targets_a, targets_b = map(Variable, (inputs, targets_a, targets_b)) outputs = net(inputs) loss = mixup_criterion(criterion, outputs, targets_a, targets_b, lam) #对loss#函数进⾏mixup操作 train_loss += [0] _, predicted = (, 1) total += (0) correct += (lam * (targets_).cpu().sum().float() + (1 - lam) * (targets_).cpu().sum().float())
我说这篇⽂章好就好在后⾯作者给出了⼀定的数学解释,现在看数学原理:假定数据x和标签y,并且这两者具有联合分布P(x,y) (当然这个联合分布函数是未知的), 模型函数⽤f表⽰,loss函数⽤l表⽰,则经验风险为通常情况下我们的训练集{x,y}可以⽤狄拉克函数来表⽰,假定训练集⾜够,可以模拟真实情况,那么上述的P可以⽤狄拉克函数近似,如下那么上述表达式带⼊第⼀个式⼦,可得到此为⽌就是在正常的未经增⼴的训练数据集下的ERM表达式,那么先前已经提到VRM来做图像增⼴的思想,那么回到这个式⼦上P就不应该是⼀个狄拉克函数的表⽰,⽽是服从邻域分布v的⼀种表达,P的表达式可由上述第⼆个式⼦退化为:这⾥的v是邻域分布函数,同样的上述第三个式⼦可以退化为:注意,由于数据发⽣了增⼴,因⽽这⾥的数据量由最开始的n变为m。⽽这篇⽂章提出的mixup ⽅法实际上就是提出了⼀种上述的v式⼦,即⼀种线性表达来代替上述第4个式⼦中的v到这⾥便是mixup的数学解释。从模型训练定性的⾓度来说,mixup相当于让模型在不同类别之间学会⼀种线性的过度,这样会导致模型在预测过程中不容易在某些类别之间发送震荡,这⼀点从⽂章实验的权重稳定性可以看得出
从我本⼈实验结果的⾓度来说,确实可以按照上述定性解释这样理解;不过这实际上给我们提供了⼀种思路,就是说在分类任务中的数据增⼴的实质有可能是打通孤⽴数据样本之间的联系,这种联系有可能是⼀种线性关系,也有可能是另⼀种⾮线性关系,模型所要做的是学会如何在已有这些联系的基础上的判别能⼒,这样可以保证模型不发⽣过拟合,也就是⽂章中提到的震荡。
2023年6月21日发(作者:)
⼀种图像增⼴(ImageAugmentation)⽅式MixUp算法附有代码解析这是对facebook研究团队的⼀篇⽂章 Mixup: Beyond Empirical Risk Minimization 的解读这篇⽂章相对于之前提到的Sample pariring来说就不那么神奇了,因为毕竟⽂章作者在⾥⾯有⼀些相关理论的推导。⽂章开头通篇讲的是ERM也就是经验风险最⼩化原则是整个机器学习遵循的原则,作者正是基于此思想才提出了MixUp的⽅法。在⼀般的机器学习任务中,⽐如分类任务中,对于ERM原则遵循的⼀种变种被称之为相邻风险最⼩化(Vicinal Risk Minimization),VRM实际上是指在训练集周围的邻域内构造⼀些样本参与训练来扩⼤原先的训练数据集的分布,通常情况下认为这些围绕着训练集某个类别⽽扩展的邻域和该类别数据是同属⼀类,并且不研究不同类别样本的邻域之间的关系(这⾥我的理解是,VRM原则是将原来的训练集进⾏邻域扩充,但是某个类别的邻域从属于某个类别,即使是该邻域同另⼀个邻域有相交的地⽅,但也不研究这些相交区域到底该如何规划)。基于上述思想,作者提出混合思路:如上式所述,输⼊样本x进⾏混合,得到⼀个新的样本,于此同时对该样本的标签也按照这样的混合⽅式进⾏混合,这样相当于⽤线性的⽅式获得⼀个原训练集某个类别样本的邻域。我通过对这篇⽂章代码的研究,实际上作者是这样操作的:1. 利⽤上述公式,将训练集中某⼀数据选出x_i,然后随机选出数据x_j,两者按照上述公式进⾏合成,于此同时标签也按照上述公式合成,并且同时可以得到合成⽤的⽐例2. 将这种合成数据送⼊⽹络,获得⽹络的输出3. 将输送⼊loss函数进⾏计算,但是注意此时的loss函数是合成loss,是由y_i和y_j合成的,loss计算分为两部分,先计算模型预测同y_i的loss,然后乘以第⼀步获得的⽐例,然后模型预测同y_j计算loss,乘以1减去第⼀步获得的⽐例,两者求和如下是代码解析:def mixup_data(x, y, alpha=1.0, use_cuda=True): # 对数据的mixup 操作 x = lambda*x_i+(1-lamdda)*x_j '''Returns mixed inputs, pairs of targets, and lambda''' if alpha > 0: lam = (alpha, alpha) else: lam = 1 batch_size = ()[0] if use_cuda: index = rm(batch_size).cuda() else: index = rm(batch_size) mixed_x = lam * x + (1 - lam) * x[index, :] # 此处是对数据x_i 进⾏操作 y_a, y_b = y, y[index] # 记录下y_i 和y_j return mixed_x, y_a, y_b, lam # 返回y_i 和y_j 以及lambdadef mixup_criterion(criterion, pred, y_a, y_b, lam): # 对loss函数进⾏混合,criterion是crossEntropy函数 return lam * criterion(pred, y_a) + (1 - lam) * criterion(pred, y_b)def train(epoch): print('nEpoch: %d' % epoch) () train_loss = 0 reg_loss = 0 correct = 0 total = 0 for batch_idx, (inputs, targets) in enumerate(trainloader): if use_cuda: inputs, targets = (), () inputs, targets_a, targets_b, lam = mixup_data(inputs, targets, , use_cuda) # 对数据集进⾏mixup操作 inputs, targets_a, targets_b = map(Variable, (inputs, targets_a, targets_b)) outputs = net(inputs) loss = mixup_criterion(criterion, outputs, targets_a, targets_b, lam) #对loss#函数进⾏mixup操作 train_loss += [0] _, predicted = (, 1) total += (0) correct += (lam * (targets_).cpu().sum().float() + (1 - lam) * (targets_).cpu().sum().float())
我说这篇⽂章好就好在后⾯作者给出了⼀定的数学解释,现在看数学原理:假定数据x和标签y,并且这两者具有联合分布P(x,y) (当然这个联合分布函数是未知的), 模型函数⽤f表⽰,loss函数⽤l表⽰,则经验风险为通常情况下我们的训练集{x,y}可以⽤狄拉克函数来表⽰,假定训练集⾜够,可以模拟真实情况,那么上述的P可以⽤狄拉克函数近似,如下那么上述表达式带⼊第⼀个式⼦,可得到此为⽌就是在正常的未经增⼴的训练数据集下的ERM表达式,那么先前已经提到VRM来做图像增⼴的思想,那么回到这个式⼦上P就不应该是⼀个狄拉克函数的表⽰,⽽是服从邻域分布v的⼀种表达,P的表达式可由上述第⼆个式⼦退化为:这⾥的v是邻域分布函数,同样的上述第三个式⼦可以退化为:注意,由于数据发⽣了增⼴,因⽽这⾥的数据量由最开始的n变为m。⽽这篇⽂章提出的mixup ⽅法实际上就是提出了⼀种上述的v式⼦,即⼀种线性表达来代替上述第4个式⼦中的v到这⾥便是mixup的数学解释。从模型训练定性的⾓度来说,mixup相当于让模型在不同类别之间学会⼀种线性的过度,这样会导致模型在预测过程中不容易在某些类别之间发送震荡,这⼀点从⽂章实验的权重稳定性可以看得出
从我本⼈实验结果的⾓度来说,确实可以按照上述定性解释这样理解;不过这实际上给我们提供了⼀种思路,就是说在分类任务中的数据增⼴的实质有可能是打通孤⽴数据样本之间的联系,这种联系有可能是⼀种线性关系,也有可能是另⼀种⾮线性关系,模型所要做的是学会如何在已有这些联系的基础上的判别能⼒,这样可以保证模型不发⽣过拟合,也就是⽂章中提到的震荡。
发布评论