这个系列咱们用实际中常常碰到的小样本问题来串联半监督,文本对抗,文本增强等模型优化计划。小样本的核心在于怎么在有限的标示样本上,最大化模型的泛化才能,让模型对unseen的样本具有很好的猜测作用。之前在NER系列中咱们已经介绍过Data Augmentation,不熟悉的童鞋看过来 中文NER的那些事儿4. 数据增强在NER的测验。样本增强是经过进步标示样本的丰富度来提高模型泛化性,另一个方向半监督计划则是经过运用很多的相同领域未标示数据来提高模型的样本外猜测才能。这一章咱们来聊聊半监督计划中的共同性正则

共同性正则~一个好的分类器应该对类似的样本点给出共同的猜测,于是在练习中经过束缚样本和注入噪声的样本要具有相对共同的模型猜测,来下降模型对部分扰动的敏感性,为模型参数拟合提供更多的束缚。施工中的SimpleClassifcation提供了Temporal Ensemble的相关完成,能够支撑多种预练习或许词袋模型作为backbone,欢迎来一同Debug >(*^3^)<

小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现

上图很形象的描述了共同性正则是怎么运用标示和未标示数据来束缚曲线拟合

a. 指用两个标示样本练习(大蓝点),由于样本少所以对模型拟合缺少束缚

b. 对标示样本注入噪音(小蓝点),并束缚噪声样本和原始样本猜测共同,经过拓展标示样本掩盖的空间,对模型拟合施加了更多的束缚

c. 在对标示样本拟合之后,冻住模型,对未标示样本(空心点)进行共同性束缚。由于共同性束缚并不需求用到label因而能够充分运用未标示数据

d. 用未标示样本上共同性束缚的loss来更新模型,使得模型对噪声愈加鲁棒

以下三种计划采用了不同的噪声注入和Ensemble方法,前两个计划来自【REF1】Temporal Ensemble,第三个计划来自【REF2】Mean Teacher。由于兼并了2篇paper,所以咱们先全体过一下3种练习框架,再说练习技巧和共同性正则的一些insights。

-MODEL

小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现

如上图,针对每个样本,-MODEL会进行两次不同的增强,以及网络自身的随机drop out得到两个猜测成果,共同性正则loss运用了MSE来核算两次猜测成果的差异,既束缚模型对输入样本的部分扰动要愈加鲁棒。模型方针是有标示样本的cross- entropy,结合全样本的共同性正则loss

-MODEL的练习功率较低,由于每个样本都要核算两遍。

Temporal Ensemble

小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现

以上-MODEL在同一个epoch内对样本注入不同噪音的猜测值进行束缚,这部分束缚会存在噪声较大,以及在epoch之间相对分裂的问题。因而作者引进Ensemble的思路在时间维度(epoch)做移动均匀,来下降共同性loss的波动性。Temporal Ensemble经过束缚各个epoch猜测值的加权移动均匀值ZZ,和当时epoch猜测值zz的相对共同,来完成共同性正则,当=0\alpha=0的时分Temporal就退化成了-MODEL。

小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现

因而Temporal需求引进Sample_size * label_size的额定变量ZZ,来存储每个样本在各个epoch上猜测值的加权移动均匀,假如你的样本非常大,则Temporal额定存储猜测的变量会是很大的内存开销,以下为temporal部分的相关完成~

with tf.variable_scope('temporal_ensemble'):
    temporal_ensemble = tf.get_variable(initializer=tf.zeros_initializer,
                                        shape=(self.params['sample_size'], self.params['label_size']),
                                        dtype=tf.float32, name='temporal_ensemble', trainable=False)
    self.Z = tf.nn.embedding_lookup(temporal_ensemble, features['idx'])  # batch_size * label_size
    self.Z = self.alpha * self.Z + (1 - self.alpha) * preds
    self.assign_op = tf.scatter_update(temporal_ensemble, features['idx'], self.Z)
    add_layer_summary('ensemble', self.Z)

所以比照-MODEL,Temporal的共同性束缚愈加滑润,全体作用更好,以及核算功率更高由于每个样本只需求做一次猜测,不过由于移动均匀的引进会占用更多的内存~

Mean Teacher

小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现

Mean Teacher是在Temporal的基础上调整了Ensemble完成的计划。Temporal是对每个样本的模型猜测做Ensemble,所以每个epoch每个样本的移动均匀才被更新一次,而Mean Teacher是对模型参数做Ensemble,这样每个step,student模型的更新都会反应在当时teacher模型上。

和Temporal无比类似的公式,差异只在于上面的Z是模型输出,下面的\theta是模型参数, 相同当=0\alpha=0的时分,Mean Teacher也退化成-MODEL。

小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现

所以练习过程如下

  1. student模型对每个随机增强后的样本核算输出
  2. 每个step,student模型权重会移动更新teacher模型的权重
  3. 更新后的teacher模型对相相同本随机增强后核算输出
  4. 核算teacher和student模型猜测成果的共同性loss,这里相同选用了MSE
  5. 监督loss + 共同性loss共同更新student模型参数

作用上Mean Teacher要优于Temporal,不过在核算功率上和-MODEL相同都需求猜测两遍,所以要比Temporal慢不少,以及由于要存储模型参数的移动均匀,所以内存占用也让人很头疼,所以Mean Teacher这块并没做相关的完成,对大模型并不太友好~

练习技巧

以上的噪声注入和Ensemble需求调配一些特定的练习技巧。

  1. ramp up weight

在练习初期,模型应该以有监督方针为主,逐步增加共同性loss的权重,在temporal ensemble上更容易解说,由于当epoch=0时,z\hat{z}是拿不到前一个epoch的猜测成果的,因而共同性loss权重为0。代码中支撑了线性,cosine,sigmoid等三种权重预热计划,原文中运用的是sigmoid

def ramp_up(cur_epoch, max_epoch, method):
    """
    依据练习epoch来调整无标示loss部分的权重,初始epoch无标示loss权重为0
    """
    def linear(cur_epoch, max_epoch):
        return cur_epoch / max_epoch
    def sigmoid(cur_epoch, max_epoch):
        p = 1.0 - cur_epoch / max_epoch
        return tf.exp(-5.0 * p ** 2)
    def cosine(cur_epoch, max_epoch):
        p = cur_epoch / max_epoch
        return 0.5 * (tf.cos(np.pi * p) + 1)
    if cur_epoch == 0:
        weight = tf.constant(0.0)
    else:
        if method == 'linear':
            weight = linear(cur_epoch, max_epoch)
        elif method == 'sigmoid':
            weight = sigmoid(cur_epoch, max_epoch)
        elif method == 'cosine':
            weight = cosine(cur_epoch, max_epoch)
        else:
            raise ValueError('Only linear, sigmoid, cosine method are supported')
    return tf.cast(weight, tf.float32)
  1. 有标示样本权重

由于以上计划多用于半监督任务,因而需求依据无标示样本的占比来调整共同性正则部分的权重。最简单的就是直接用有标示样本占比来对以上的weight做rescale,有标示占比越高,共同性loss的权重约高,防止模型过度关注正则项。

  1. 丢失函数选择

针对共同性正则的丢失函数究竟运用MSE还是KL,两篇paper都进行了比照,尽管从理论上KL更合逻辑,由于是对猜测的概率分布进行共同性束缚,但全体上MSE的作用更好。我猜测和NN倾向于给出over confident的猜测相关,尤其是Bert一类的大模型会会集给出0.9999这种猜测概率,在KL核算时容易出现极点值

Insights

以上两种ensemble的策略除了能提高半标示样本的作用之外,还有以下的额定作用加成

  1. 含糊标签:作者在全标示的样本上也测验了self-ensemble的作用,对猜测成果也有提高,猜测这源于共同性正则在必定程度上可能改善边际/含糊label的样本作用

  2. 降噪:作者把x%的练习样本赋予随机label,然后比照惯例练习和temporarl ensemble的作用。成果如下temporal对部分的标示噪音有很好的降噪作用。正确样本的监督loss帮助模型学习文本表征到label的mapping,而在正确样本附近的误标示样本会被共同性正则束缚,然后下降过错标签对模型的影响。

小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现

分类作用

这里在头条15分类的数据集进步行了测试。分别在Fasttext和Bert进步行了测试,左是原始模型,右参加Temporal Ensemble。考虑NLP的样本层面的增强作用比照CV相对有限,这里的随机增强只用了Encoder层的Drop out,原论文是CV领域所以增强还包括crop/flip这类图像增强。

首先是Fasttext,受限于词袋模型自身的才能,即便是不参加未标示样本,只是参加Temporal共同性丢失都带来了全体作用上的提高,详细参数设置详见checkpoint里边的train.log

小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现
小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现

其次是Bert,这里参加了chinanews的无标示样本,不过作用比较有限,主要提高是在样本很少的stock分类上。这里必定程度和缺少有效的样本增强有关,后边结合隐藏层增强咱们会再试下temporal~

小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现
小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现

Reference

  1. Laine, S., Aila, T. (2016). Temporal Ensembling for Semi-Supervised Learning arXiv arxiv.org/abs/1610.02…
  2. Tarvainen, A., Valpola, H. (2017). Mean teachers are better role models: Weight-averaged consistency targets improve semi-supervised deep learning results arXiv arxiv.org/abs/1703.01…
  3. tech.meituan.com/tags/%E5%8D…
  4. zhuanlan.zhihu.com/p/250278934
  5. zhuanlan.zhihu.com/p/128527256
  6. zhuanlan.zhihu.com/p/66389797
  7. github.com/diyiy/ACL20…