前三章咱们陆续介绍了半监督和对立练习的计划来进步模型在样本外的泛化能力,这一章咱们介绍一种嵌入模型的数据增强计划。之前没太重视这种计划,实在是方法过于朴素。。。不过在最近用的几个数据集上mixup的体现都比较哇塞,所以咱们再来聊聊~

Mixup

  • paper: mixup: Beyond Empirical Risk Minimization
  • TF源码:github.com/facebookres…
  • torch复现:ClassicSolution

原理

mixup的完成非常简略,它从练习集中随机挑选两个样本,对x和y分别进行线性加权,运用交融后的x~,y~\tilde{x}, \tilde{y}进行模型练习

x~=xi+(1−)xjy~=yi+(1−)yj\tilde{x} = \lambda x_i + (1-\lambda) x_j \\ \tilde{y} = \lambda y_i + (1-\lambda) y_j

对x的交融比较容易了解,例如针对图画输入,mixup对输入特征层的线性交融能够被直观的展现如下。

小样本利器4. 正则化+数据增强 Mixup Family代码实现

对y的交融,假如是2分类问题且=0.3\lambda=0.3, 一个y=1的样本交融一个y=0的样本后d得到y~=[0.3,0.7]\tilde{y}=[0.3,0.7],等价于两个样本损失函数的线性加权,既0.3 *CrossEntropy(y=0)+0.7 * CrossEntropy(y=1)

怎么了解mixup会生效呢?作者是从数据增强的视点给出了解说,以为线性差值的方式拓宽了练习集掩盖的区域,在原始样本未掩盖区域(in-between area)上让模型学到一个简略的label线性差值的结果,然后进步模型样本外的泛化作用~

不过我更倾向于从正则化的视点来了解,由于模型并不是在原始样本上补充差值样本进行练习,而是彻底运用差值样本进行练习。线性差值本身是基于一个简化的空间假设,既输入的线性加权能够映射到输出的线性加权。这个简化的假设会作为先验信息对模型学习起到正则约束的作用,使得模型的分类鸿沟愈加滑润,且分类鸿沟离样本高密度区更远。这和咱们上一章提到的半监督3大假设,滑润性假设,低密度分离假设相互照应~

作者对比了原模型和mixup增强模型在对立样本上的猜测误差,验证了mixup能够有用进步模型在扰动样本上的鲁棒性,不过看误差感觉对立练习可能能够和mixup并行运用,今后有机会尝试后再来补充~

小样本利器4. 正则化+数据增强 Mixup Family代码实现

一起作者做了个有趣的实验,对比了在交融样本上的猜测误差,举个栗子0.3个体育新闻交融0.7个娱乐新闻让模型去做猜测,假如猜测结果既非体育也非娱乐则判断为miss。下图显现mixup能够有用下降miss率。直接作证了mixup有进步in-between样本外猜测的作用~

小样本利器4. 正则化+数据增强 Mixup Family代码实现

实践运用中还有几个细节有待评论

  1. 在哪一层进行mixup作用更好

作者在图画分类使命中对比了layer1~6,终究发现对最底层施加mixup的作用最好。和FGM一样,假如对高层进行mixup,由于非线性程度较低,可能会导致模型欠拟合

  1. 只在同一个类别内部进行mixup仍是对全类别进行随机mixup

作者对比了类内mixup,和所有类随机mixup,作用是随机mixup作用更好。感觉不约束插值类别才是保证分类鸿沟远离样本高密度区的关键,由于mixup会使得模型在两个分类cluster中心未掩盖的区域学到一个线性插值的分类,然后使得分类鸿沟远离恣意类别样本的掩盖区域

  1. 是否需要约束mixup样本之间的类似度,防止引入过多噪声 作者尝试把mixup的规模约束在KNN200,不过作用没有随机mixup作用好

  2. 混合权重的挑选 论文并没有对应该怎么挑选插值的权重给出太多的建议,实践尝试中我也一般是从大往小了调,在一些小样本上假如权重太大会明显看到模型欠拟合,这时再考虑适当调低权重,和dropout扰动相同权重越大正则化作用越强,也就越容易欠拟合

完成

def mixup(input_x, input_y, label_size, alpha):
    # get mixup lambda
    batch_size = tf.shape(input_x)[0]
    input_y = tf.one_hot(input_y, depth=label_size)
    mix = tf.distributions.Beta(alpha, alpha).sample(1)
    mix = tf.maximum(mix, 1 - mix)
    # get random shuffle sample
    index = tf.random_shuffle(tf.range(batch_size))
    random_x = tf.gather(input_x, index)
    random_y = tf.gather(input_y, index)
    # get mixed input
    xmix = input_x * mix + random_x * (1 - mix)
    ymix = tf.cast(input_y, tf.float32) * mix + tf.cast(random_y, tf.float32) * (1 - mix)
    return xmix, ymix

Pytorch的完成如下

class Mixup(nn.Module):
    def __init__(self, label_size, alpha):
        super(Mixup, self).__init__()
        self.label_size = label_size
        self.alpha = alpha
    def forward(self, input_x, input_y):
        if not self.training:
            return input_x, input_y
        batch_size = input_x.size()[0]
        input_y = F.one_hot(input_y, num_classes=self.label_size)
        # get mix ratio
        mix = np.random.beta(self.alpha, self.alpha)
        mix = np.max([mix, 1 - mix])
        # get random shuffle sample
        index = torch.randperm(batch_size)
        random_x = input_x[index, :]
        random_y = input_y[index, :]
        xmix = input_x * mix + random_x * (1 - mix)
        ymix = input_y * mix + random_y * (1 - mix)
        return xmix, ymix

迁移到NLP场景

  • paper: Augmenting Data with mixup for Sentence Classification: An Empirical Study

mixup的计划是在CV中提出,那怎么迁移到NLP呢?其实仍是在哪一层进行差值的问题,在NLP中一般能够在两个方位进行交融,在过Encoder之前对词向量交融,过Encoder之后对句向量进行交融。

小样本利器4. 正则化+数据增强 Mixup Family代码实现

作者在文本分类使命上对比了二者的作用,并尝试了随机词vs预练习词向量 * 允许微调vs冻结词向量,总共4种不同的情况。全体上不论是wordmixup仍是sentmixup都对作用有一定提升,不过二者的差异并不如以上的CV实验中显著。

小样本利器4. 正则化+数据增强 Mixup Family代码实现
在[运用类别辨认挑战赛](https://challenge.xfyun.cn/topic/info?type=scene-division)中,我分别尝试了FGM,Temporal半监督,文本增强,和mixup来提升文本分类模型的作用。在我运用的词+字向量的TextCNN模型结构中,mixup的体现最好,单模型在初赛排到13名。之后等Top3解决计划出来后,咱们再来总结这个竞赛~

Manifold Mixup

  • paper: Manifold Mixup: Better Representations by Interpolating Hidden States
  • github: github.com/vikasverma1…

Manifold Mixup是在mixup基础上的改良,一言以蔽之便是把上面纠结的mixup在哪一层进行插值的问题,变成了每个step都随机选一层进行插值。个人很喜欢这篇paper有两个原因,其一是由于觉得作者对mixup为何有用比原作解说的愈加简略易懂;其二是它对插值方位的挑选计划更适合BERT这类多层Encoder的模型。而反观cv场景,优化点更多集中在cutmix这类对插值信息(对两个像素框内的信息进行交融)的挑选上,核心也是由于图画输入的像素的信息量要远小于文本输入的字符所包含的信息量。

说回Manifold mixup,它的全体完成计划很简略:在个layer中任选一个layer K,这儿包含输入层(layer=0), 然后向前传导到k层进行mixup就齐活了。作者的代码完成也很简略一个randint做层数挑选,加上一连串的if layer==i则进行mixup就搞定了~

关键咱们来拜读下作者对于Manifold Mixup为何有用的解说,作者从空间表征上给出了3个观点

  1. 得到更滑润,且远离样本掩盖空间的决策鸿沟,这个同mixup

  2. 展平分类的空间表征:啥叫展平这个我开始也木有看懂,不过作者的证明方式愈加易懂,作者对比了不同的正则计划mixup,dropout,batchnorm和manifold对躲藏层奇特值的影响,发现manifold相较其他正则化能够有用下降躲藏层的全体奇特值。下降奇特值有啥用嘞?简略说便是一个矩阵越奇特,则越少的奇特值蕴含了更多的矩阵信息,矩阵的信息熵越小。所以这儿作者以为mixup起到了下降猜测置信度然后进步泛化的作用。更详细对奇特值的解说能够去知乎崇拜各路大神的奇特值的物理意义是什么?

  3. 更高躲藏层的交融,供给更多的练习信号:个人阅读了解给出的解读是高层的空间表征更贴近使命本身,因此交融带来的增益更大。这也是我之前对为啥文本使命在Encoder之后交融作用作用有时比在输入层交融还要好的强行解说。。。。

至于Manifold mixup为何比mixup更好,作者做了更多的数学证明,不过。。。这个我们感兴趣去看下就知道这儿为何省掉一万字了~以及之后呈现的Flow Mixup也挑战过Manifold会导致样本分布潇洒以及练习不稳定的问题,不过我并没有在NLP上尝试过manifold的计划,今后要是用了再来comment ~