在现实应用中,标注数据的缺失往往是NLPer面临的最头疼的问题。下图总结了关于Data Augmentation的相关技术分类:
本文的行文思路,按照上图介绍各种方法的原理。然后会详细介绍一些模型中做数据增强的具体实施细节。
1. 无条件增强
1.1 词汇&短语替换
同义词替换 基于词典,使用同义词典进行同义词替换,比如英文有WordNet,中文有哈工大词林等。Synonyms是一个不错的开源项目,可以用来获取中文同义词。
基于词向量 可以直接通过计算词向量(glove等)距离来替换。
Masked LM 使用BERT等 Masked预训练语言模型模型,启发式的Mask词汇并进行预测替换。
TF-IDF 实质上是一种非核心词替换,对TF_IDF分值比较低的词进行替换。 这个最早在UDA中提出。
1.2 随机噪音注入
随机插入 随机的插入一个词汇、错误拼写、占位符等。UDA中根据Uni-gram词频分布进行了采样。 英文错误拼写替换有一个表可以参考:spelling_en,中文暂时没有发现。
随机替换 随机交换词汇或者shuffle句子。
随机删除 随机删除词汇或者句子。
UDA中也使用了上面三种随机噪音注入的方法。
1.3 混合(Mixup)&交叉
混合增强 Mixup先出现在图像里面,它试图将任意一对训练sample,在像素数值和target上做线性差值计算(linearly interpolating),构造更多的训练数据。详细来说,比如一对sample: $(x^i;y^i )$ 和 $(x^j;y^j )$,其中x是输入矩阵,y是one-hot表示的task数组。通过下面的方法构造数据: 其中$\lambda$大小取自$Beta(\alpha,\alpha)$分布。
在NLP模型中,作者提出了下面两种模式:wordMixup和senMixup。基本思想和线性计算都一样,只是将像素矩阵变成了词向量矩阵或者最后的sentence embedding。
paper在此
交叉增强 类似于“染色体的交叉操作”,将完整推文分成两部分,然后同类sample之间交叉: 这一技术对准确性没有影响,但有助于论文中极少数类的F1分数,如tweets较少的中性类。 paper在此
1.4 回译
可以通过一段,比如:中->英->中,或者两段式,比如:中->英->日->中。效果一般都会比较好,最好使用domain相关的自训练翻译模型。
1.5 句法变换
其思想是解析和生成原始句子的依赖关系树,使用规则对其进行转换,并生成改写后的句子。例如,一个不改变句子意思的转换是句子从主动语态到被动语态的转换,反之亦然。
1.6 对抗增强
CV领域很多使用GAN做数据增强,在NLP上通常在词向量上添加扰动并进行对抗训练。
对于无增强方法的总结: 无增强方法是在不改变标签的前提,使用各种方法来改变句子的token或者句式,但是这种改变可能影响label,比如:在情绪分类任务中,把good变成bad,label肯定会改变的。所以,可以引入标签信息来引导做数据增强。
2. 条件增强
所谓条件增强,就是需要把标签信息加入到模型中指导产生数据。
2.1 深度生成模型
既然想使用深度模型,就需要大量数据,然而这个又与现实矛盾。所以,在使用GAN或者CVAE这一类深度生成模型在解决少样本问题时,还需要更多的探索。
2.2 预训练语言模型(Conditional Pre-trained Language Models)
主要介绍三篇文章:
Contextual Augment 在上述方法中,都没有考虑替换token的上下文,本文使用语言模型,通过根据上下文来预测$i$位置的token来做data augmentation。 但是如果仅仅使用语言模型还不够,比如“the actors are fantastic”,对于"fantastic",通过语言模型,可能给正面的“good”和“entertaining”,也可能给负面的“bad”和“terrible”。所以,需要把这句话的分类信息也考虑进来。 模型的具体做法是,在feed-forward层将标签y(label_embedding)与隐向量concat在一起,然后在分类任务上进行fine-tuning。 作者在LSTM和CNN上做了实验: code
CBERT 这篇论文延续了上一篇Contextual Augment的思路,并使用BERT作为encoder。 基础模型与BERT相同。只是在构造输入中有所改变。也就是,将segment_embedding替换程label_embedding。然后,在 MLM 任务上fine-tuning来得到一个有效的模型。 实验结果: CBERT-paper
LAMBADA 使用预训练预言模型GPT2做token预测。预CBERT相比,除了基础模型的差别外,还有两点不同:
输入矩阵构造方式不同。 在CBERT中,是将segment_embedding替换程label_embedding。而在LAMBADA中,将label与sentence通过$SEP$拼接直接作为输入。
LAMBADA在生成扩充后的sample之后,还使用一个分类器做进一步的过滤降噪,而这个分类器就是用训练数据在GPT2中训练得到的。 整体算法如下: LAMBADA
论文paper对上述三种基于预训练语言模型来做DA的方法进行了总结和比较。自我感觉,这个思路还是有很大潜力的。
3. 半监督学习
使用大量未标注数据做数据增强,可以称之为半监督学习,同样是研究热点,它最早应用于CV领域,在NLP同样可以发光发热。
使用半监督学习的策略,总结来说就是:如何在损失函数中添加针对未标注数据相关的正则项,使模型能够充分利用大量的未标注数据来不断迭代模型,增强模型泛化性能。
添加对未标注数据相关正则化项,通常有下面两种方法:
1.熵最小化(Entropy Minimization) 根据半监督学习的Cluster假设,决策边界应该尽可能地通过数据较为稀疏的地方(低密度区),以能够避免把密集的样本数据点分到决策边界的两侧。也就是模型通过对未标记数据预测后要作出低熵预测,即熵最小化: 通过下图可以看到分布决策边界的意义:
2.一致性正则(Consistency Regularization):对于未标注数据,希望模型在输入$x$受到扰动时产生相同的输出分布。即:
3.2 UDA(2019.4.29)
UDA就是使用一致性正则,下图是UDA的模型框架,注意一点,左右两边的模型M,在训练时,只在左边进行BP,右边的模型参数只直接从左边模型复制过来。 在文本任务中对输入$x$添加扰动的方式使用了两种:
回译
低TF_IDF的词汇替换 然后使用KL散度计算两者之间的一致性损失,再与本身的分类交叉熵损失相加构成了模型的总损失。
此外,UDA也利用了一些辅助技术:
结合了熵最小化正则:对无监督信号进行sharpen操作构建人工标签,使其趋近于 One-Hot 分布,对某一类别输出概率趋向 1,其他类别趋向0,此时熵最低。此外,还直接计算了熵损失。
将人工标签与strong增强后的预测标签共同构建一致性正则,并计算损失时进行了confidence-based masking,低于置信度阈值不参与loss计算。
采用训练信号退火(TSA)方法防止对标注数据过拟合,对于标注数据的置信度高于阈值要进行masking,这与无标注数据正好相反。
使用初始模型过滤了领域外的无标注数据。
UDA-code UDA-paper
4. 实施方案
4.1 TinyBert
在这片文章中,作者设计了借助于BERT模型做数据增强的方法。 详细来说,对于输入句子$x$,首先随机mask掉部分token,然后使用BERT模型来预测对应位置的top-M的词语作为candidates,然后随机选取一个token,最终组合成扩充语料。 其中有两个细节有特殊处理:
在从candidates中挑选token时,作者设置一个参数$p$,使其服从$ UNIFORM(0,1)$分布,再通过一个阈值$p_t$(0.4)来决定是不是从candidates中取token。
对于有子词的token,不在使用BERT预测,而是使用Glove计算最近距离的token。
4.2 Learning Robust Models for e-Commerce Product Search
这篇论文是用来增加副样本。
paper
5. 相关工作
nlpaug的开源代码:nlpaug
基于lasertagger做中文文本数据增强,LaserTagger
[参考文献:] A Visual Survey of Data Augmentation in NLP 让机器自动生成文本数据--NLP文本数据增强方法简述 NLP中的少样本困境问题探究