人工智能自然语言处理之数据增强去噪类别不平衡模型轻量化
1、数据增强 1.1 EDA(Easy Data Augmentation)图像任务中,有随机裁剪、翻转、改变饱和度等操作,同样地,文本也有不少的增强方法,如同义词替换,回译,近音字替换,随机插入,随机交换,随机删除等等,这里说一下个人平时用得做多,也认为效果最好的两个,同义词替换和回译 1.1.1 同义词替换:做法可以是维护一个同义词表,如哈工大的发布的同义词词典。在每次训练的时候,样本有一定的概率对里面的词语进行替换。如"自动驾驶、医疗、能源……一季度融资最多的人工智能公司" -> "自动驾车、医术、能源……一季度融资最多的人工智能公司"。根据经验,有条件的话最好用项目领域的同义词词典,如做医疗的文本,就用医疗的同义词词典,做金融领域的就用金融的同义词词典,而不是用一个通用的字典。还有种做法是用词向量进行替换,如上面的句子中,我们对"驾驶"一次进行同义词替换,发现在词向量表中,离"驾驶"余弦距离最近的一词是"行驶",所以就把"驾驶"替换成"行驶",当然这样做的话需要预先训练一个词向量表,还是那句话,最好用你目前手头任务领域的文本来训练词向量。也可以用 Bert 等模型来进行替换,如把上面的句子随机 MASK 掉一些字,变成"自[MASK]驾驶、医疗、能源……一季[MASK]融资最多的人工智[MASK]公司",再让 Bert 对 MASK 掉的字进行预测,这样又得到新的一个样本。
2、数据去噪大家都说算法工程师 80%在洗数据,20%时间在跑模型,实质上,以我的个人经验来说,这个说法也是有道理的,一个 AI 应用,一周的时间要解决的话,在准备数据层面可能会花 3~4 天。特别是做久了之后,很多模型的组件,方法论都已成型,想比较不同方法的效果,从以往积累的项目库里把相关代码抽出来,就可以跑来做实验了,时间成本很低。而且做项目,最后常常会发现,制约模型效果再上一步的,往往是最数据质量,所以洗数据尤为关键,想想假如你在一个准确率只有 80%的训练集上训练模型,你觉得你训练出来的模型最后在测试集的准确率能超过 80%吗?通常,接到一个 AI 需求,假如要训练机器学习或深度学习的模型,标注数据是必不可少的,来源可以是已有的人工标注,没有的话,只能自己或者找实习生标注进行打标,假如需要的标注样本多的话,还可以请众包公司进行标注。就拿文本分类来说,人工标注准确率有 95%就已经很好了。怎么清洗标注错误的数据呢?这个问题其实本人还没有很深的积累,常常优先使用的方法是根据业务规则洗,就拿前段时间做的一个工单分类的项目来说(以往是人工分类,客户想用 AI 的方法进行自动分类),以往确实积累了几万条人工分类过的样本,但以往的工作人员很多是凭经验进行随机分类的,所以在看数据的时候,看的我皱眉头,很多都是分类错误的,这时候,只能和客户不断沟通,拿更多的资料,思考从客户角度,他们判断类别的逻辑,从而把错误的样本修正过来,这个过程很耗时,但也很重要,我想这也是实际做项目和打比赛的一个很大的不同。除此之外,还有没有更智能的清洗数据方法?有不少前沿的论文对这些方法进行过讨论,如通过置信度清洗数据等等,但实际上,很多方法都仅仅能争对非常有限的场景,效果有限。本人常常用的比较笨的方法是交叉验证清洗,如"湖人拿到 2020 年 NBA 的总冠军"这样本,在训练集上把它标注为"娱乐"新闻,很明显是错误的,像这种错误,用交叉验证的方法洗是最容易的,举个例子,我们可以对训练集训练一个 5 折的模型,然后对训练集进行预测,假如这个样本在 5 折模型中都预测为"体育",则把该样本的 label 从"娱乐"修正为"体育",用交叉验证的方法能批量洗掉一些很明显错误的样本,但是这个阈值(出现 5 次还是 4 次以上就把该样本修正)需要多做实验。
3、类别不平衡针对类别不平均的问题,有过采样、欠采样、改造损失函数等方法入手。实际项目落地时,还需要考虑客户的需求,例如某个标签的样本很少,导致这个样本的召回率、精确率都比较低,但可能客户不太关心这个标签的精确性,这时候也没必要花太多时间纠结如何改善。个人经验来说,我会比较倾向使用改造函数函数来调接样本不平衡的问题,因为无论是过采样或者欠采样,都会导致样本噪声这个问题,而改造损失函数,如调整不同样本的权重,采用 Focal Loss 等等函数都能有限减少不平衡的问题。
4、半监督学习 4.1、Consistency Loss(一致性损失)拿一个例子来说明 UDA 中的一致性损失,如现在只有【体育,娱乐,金融,政治】四个分类,某个样本"詹姆斯超乔丹论调遭麦蒂吐槽:为什么人们总会忘记科比?",在模型训练过程中,模型判断出的该样本属于四个类别的概率分别为【0.5, 0.15, 0.15, 0.2】,这时候对该样本进行数据增强(这也是论文标题出现 Data Augmentation 的原因,原论文用了同义词替换和回译两种方法),样本变成"詹姆斯强于乔丹论调遭麦蒂埋怨:为什么人们总会遗忘科比?"。一致性的意思就是认为,增强后的样本跟原来的样本语义相同,这时候模型的输出概率就应该保持一致,所以增强后的样本的概率分布应该要去拟合【0.5, 0.15, 0.15, 0.2】这一概率分布。在论文中,用原样本的输出概率分布和增强样本的输出概率分布的 KL 散度损失与有标签样本的交叉熵损失进行联合训练。在 UDA 方法中,还有许多训练的细节,如 Sharpening Predictions、TSA(TRAINING SIGNAL ANNEALING)等等,下面简单介绍一下这些细节。
5、模型轻量化模型轻量化也是更实际落地常常碰到的问题,一般的 AI 项目,可能存在资源不充足的情况,如客户提供的服务器不包括 GPU,这时候就要在自己公司的服务器上把模型先训练好,再迁移到客户的服务器,用 CPU 部署,这时要考虑推断速度是否满足项目需求,也有可能是服务器可能不止部署你一个模型,还要部署其它系统应用,这时候给你留下的内存就不足了。当然最好是项目前期,就像客户说明需求的配置,让客户尽量满足,但实际上,随着项目的进展,很可能发生各种意外情况。在实际部署中,本人比较倾向用 docker 这种微服务进行部署,通常一个 bert 模型加上 docker 需要的基础环境,用 CPU 进行部署,把容器起起来后,占用的内存会到 2G 左右,推断速度大概在 1~2 秒/一个样本。模型轻量化也有几种思路,如模型剪枝(把贡献不高的神经元去掉)、换轻量化模型(如用 3 层 Bert 代替原生的 12 层 Bert、或者换 Fasttext 等轻量化模型)、模型蒸馏(TinyBert 等蒸馏模型)。想想在某个应用种,Bert 模型能得到 89%的准确率,FastText 能得到 85%的准确率,最终上线的时候你会考虑用哪个模型?不是说 Bert 不好,但毕竟它在某些资源有限的情形下,还是显得太"重"了,但 Bert 可以作为一个性能标杆,用轻量化的模型不断去逼近 Bert 的效果。
版权声明: 本文为 InfoQ 作者【XiaoChao_AI】的原创文章。
原文链接:【http://xie.infoq.cn/article/ebeb3d14ce140e804b05f788b】。文章转载请联系作者。
评论