写点什么

人工智能自然语言处理之数据增强去噪类别不平衡模型轻量化

作者:XiaoChao_AI
  • 2022-11-14
    浙江
  • 本文字数:4798 字

    阅读完需:约 16 分钟

人工智能自然语言处理之数据增强去噪类别不平衡模型轻量化

1、数据增强 1.1 EDA(Easy Data Augmentation)图像任务中,有随机裁剪、翻转、改变饱和度等操作,同样地,文本也有不少的增强方法,如同义词替换,回译,近音字替换,随机插入,随机交换,随机删除等等,这里说一下个人平时用得做多,也认为效果最好的两个,同义词替换和回译 1.1.1 同义词替换:做法可以是维护一个同义词表,如哈工大的发布的同义词词典。在每次训练的时候,样本有一定的概率对里面的词语进行替换。如"自动驾驶、医疗、能源……一季度融资最多的人工智能公司" -> "自动驾车、医术、能源……一季度融资最多的人工智能公司"。根据经验,有条件的话最好用项目领域的同义词词典,如做医疗的文本,就用医疗的同义词词典,做金融领域的就用金融的同义词词典,而不是用一个通用的字典。还有种做法是用词向量进行替换,如上面的句子中,我们对"驾驶"一次进行同义词替换,发现在词向量表中,离"驾驶"余弦距离最近的一词是"行驶",所以就把"驾驶"替换成"行驶",当然这样做的话需要预先训练一个词向量表,还是那句话,最好用你目前手头任务领域的文本来训练词向量。也可以用 Bert 等模型来进行替换,如把上面的句子随机 MASK 掉一些字,变成"自[MASK]驾驶、医疗、能源……一季[MASK]融资最多的人工智[MASK]公司",再让 Bert 对 MASK 掉的字进行预测,这样又得到新的一个样本。


    1.1.2 回译        做法很简单,把中文翻译成英文或法文或日本,再翻译回中文,如下面的句子,先翻译成英文,再翻译回中文,"自动驾驶、医疗、能源……一季度融资最多的人工智能公司" -> "第一季度融资最多的自动驾驶仪、医疗保健、能源人工智能公司",有时回译能得到语法结构不同的句子,如被动句变成主动句,有效增强了样本的多样性。不过个人觉得,长文本并不适用于回译,想想一个500多字的长文本,经过回译后,上下文是否还通顺是个问题,当然也可以随机对长文本中的单句进行回译,而不是把整个长文本进行回译。        实际项目中取哪种数据增强方法,个人感觉是都要进行实验尝试,但无论进行何种尝试,把握一点就是增强后的样本要和测试集的样本分布相似,其实这也是无论做图像任务、检测任务还是机器学习的任务都通用的一点,假如你增强后的样本与真实要预测的样本出入很大,你还让模型去学,那怎么可能会带来正向的效果呢?对吧。        这里的实验,采用了同义词替换这个增强方法,用的同义词表就是上文提到的哈工大,用的是nlpcda库[1](貌似做中文文本增强的库不多,本人还没找到几个用得比较顺手的,当然也可以自己写数据增强这部分的代码,并不复杂)        可以看到经过数据增强后,分数都有所上涨,其实可以说几乎所有的任务,做数据增强都会带来正向的效果,但这个效果有多大的提升,就很依赖做数据增强的方法了,举个例子,一个样本"互联网时代有隐私可言吗?" ->"互联网时代有心事可言吗?",这个样本的增强我认为效果有限,因为增强后已经不是一个语义明了的句子了,还是那句话,增强后的样本要和实际预测的样本分布要相似,这样才能得到比较好的正向效果。

1.2 对抗训练 添加噪声扰动的思想想到了,也有个问题,噪声有很多种,是加入高斯噪声、还是均值噪声还是其它?其中对抗训练的思想就是往损失函数上升的方向,在embedding层添加扰动 抗训练后,训练时间会近乎成倍增常,就拿FGM来说,每一次更新参数,都进行了两次后向传播。在大部分场景下,基本都会加上FGM,基本都能带来正向的效果,而且FGM相对其它对抗方法,所耗时间也较少。
复制代码


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)等等,下面简单介绍一下这些细节。


4.2、Sharpening Predictions    半监督学习的大部分论文中中,除了Consistency思想,其实还是一种思路是最小化熵,还是拿一个样本进行举例,如"用摄影记录当红女星杨幂成长之路"这一无标签样本,还是【体育,娱乐,金融,政治】四分类,把样本输入模型,模型其实不是直接输出概率,而是不同的数值,如【0.50, 1.05, -0.56, 0.01】,把这些数据经过Sofrmax才得到概率分布【0.27, 0.47, 0.09, 0.17】,这时候同上面的思想一样,我们把样本进行数据增强后输入模型,让输出的概率去拟合【0.27, 0.47, 0.09, 0.17】这一概率分布,但在这里我们有个不同的处理,在原样本的Softmax过程中,我们引入Sharpening Predictions,Softmax( l(X) / τ )**计算,其中l(X)表示结果逻辑分布概率,即上面的【0.50, 1.05, -0.56, 0.01】,τ 表示温度。τ 越小,分布越Sharper。如τ =0.6,【0.50, 1.05, -0.56, 0.01】每个元素都除以τ,变为【0.83, 1.75, -0.93, 0.02】,再经过Softmax,得到分类概率为【0.24, 0.61, 0.04, 0.11】,可以看到τ 取小于1的数,Softmax输出的概率分布会更"Sharpening",即为更陡峭,熵也越低**(思考一下,概率分布陡峭了,不确定自然也少了,熵也自然少了)。    为啥要引入Sharpening Predictions?我认为是为了让模型输出能更明确,或者说就是让熵尽可能小,让模型更 倾向输出【0.97, 0.01, 0.01, 0.01】这种明确性更高的、低熵的概率分布,而不是【0.7, 0.1, 0.1, 0.1】这种相对来说不是很明确的概率分布,增加模型的鲁棒性。
4.3、TSA(TRAINING SIGNAL ANNEALING) 思考一个问题,假如你现在只有50个标注样本和20K个无标注样本,假如不经过任何处理,直接进行联合训练,很可能的情况是,模型会对50个标注样本过拟合,因为标注样本数量实在太少了,所以这里引入TSA,举个例子,我们取TSA=0.5,对于某个标注样本"去年A股上市公司高管薪酬比拼:金融和房地产业最高",还是【体育,娱乐,金融,政治】四分类,其真实标签为"金融",模型输出的概率分布为【0.1, 0.1, 0.7, 0.1】,由于其真实标签的概率为0.7>0.5,所以我们不把该样本的损失考虑进行,只有其真实标签的概率小于TSA的样本的损失我们才用来进行反向传播,通过这一方法,减缓模型对于少量标签样本过拟合的步伐。TSA系数是随着训练过程不断增加的。
4.4、Confidence Mask 首先设定Confidence Mask系数,如把Confidence Mask Coefficient=0.5,把无标注样本输入模型,得到概率分布为【0.3, 0.25, 0.4, 0.05】,由于最大的类别概率也少于0.5,所以就不把该无标注样本的 Consistency Loss 纳入到反向传播中。 可以看到引入半监督学习,在缺少标注数据的情况下,提升巨大,但随着标注数据的不断增加,半监督带来的正向效果也在不断减少,在原论文中讨论过,当标注数据充分的情况下,无监督仍能带来少量的提升,但在本实验中,看最后两行,可以发现标注数据充分的情况下,引入半监督是没有提升的,我估计是这里的数据增强做得太简单了,这里的数据增强只是对句子中的词进行同义词替换, 而原论文用了一种考虑更细致的方法,思想是用TF-IDF进行统计,样本中对分类成功贡献很大的词,不进行替换
复制代码


5、模型轻量化模型轻量化也是更实际落地常常碰到的问题,一般的 AI 项目,可能存在资源不充足的情况,如客户提供的服务器不包括 GPU,这时候就要在自己公司的服务器上把模型先训练好,再迁移到客户的服务器,用 CPU 部署,这时要考虑推断速度是否满足项目需求,也有可能是服务器可能不止部署你一个模型,还要部署其它系统应用,这时候给你留下的内存就不足了。当然最好是项目前期,就像客户说明需求的配置,让客户尽量满足,但实际上,随着项目的进展,很可能发生各种意外情况。在实际部署中,本人比较倾向用 docker 这种微服务进行部署,通常一个 bert 模型加上 docker 需要的基础环境,用 CPU 进行部署,把容器起起来后,占用的内存会到 2G 左右,推断速度大概在 1~2 秒/一个样本。模型轻量化也有几种思路,如模型剪枝(把贡献不高的神经元去掉)、换轻量化模型(如用 3 层 Bert 代替原生的 12 层 Bert、或者换 Fasttext 等轻量化模型)、模型蒸馏(TinyBert 等蒸馏模型)。想想在某个应用种,Bert 模型能得到 89%的准确率,FastText 能得到 85%的准确率,最终上线的时候你会考虑用哪个模型?不是说 Bert 不好,但毕竟它在某些资源有限的情形下,还是显得太"重"了,但 Bert 可以作为一个性能标杆,用轻量化的模型不断去逼近 Bert 的效果。

发布于: 刚刚阅读数: 4
用户头像

XiaoChao_AI

关注

还未添加个人签名 2022-11-10 加入

还未添加个人简介

评论

发布
暂无评论
人工智能自然语言处理之数据增强去噪类别不平衡模型轻量化_人工智能_XiaoChao_AI_InfoQ写作社区