心法利器[1] | NLP知识蒸馏思考

 

【前沿重器】

全新栏目,本栏目主要和大家一起讨论近期自己学习的心得和体会,与大家一起成长。具体介绍:仓颉专项:飞机大炮我都会,利器心法我还有

往期回顾

知识蒸馏本就不是什么比较新的知识,早在2015年,Hinton就已经提出了蒸馏学习,并成功使用在特定的任务上,近期在NLP领域重提,其实是因为各种预训练语言模型的体积越来越大而无法落地实施,而要尝试把这些好东西落地实施,一方面是硬件和引擎能够过关,另一方面则是算法要自食其力,自己尝试让这个好东西能被使用,除了剪枝、压缩等对模型能力更高的方法外,蒸馏应该是要求成本最低的方法了,因此也有不少人开始尝试研究这块咋整了。今天我和大家聊的核心不低不在于介绍蒸馏,而在于谈蒸馏本身给大家的一些启示以及我们日常可以怎么去做,来看看吧。

懒人目录:

  • 什么是知识蒸馏。

  • NLP的知识蒸馏成果。

  • 从蒸馏任务想到的。

  • 结论

什么是知识蒸馏

Hinton在2015年Distilling the Knowledge in a Neural Network的论文首次提出了知识蒸馏的并尝试在CV领域中使用,旨在把大模型学到的知识灌输到小模型中,以达到缩小模型的目标,示意图如下:

  • 首先,训练一个大模型。

  • 大模型做特征软化,即输出他预测的概率,可以理解为softed labeled。

  • 训练小模型,同时附带大模型的信息。常用的方式就是在损失函数里面加入这个信息。

来看一个损失函数的例子:

表示老师网络,即大模型, 是小模型,这个损失考虑了老师网络和label的关系、学生网络和label的关系以及学生网络和老师网络的关系。

损失函数代表的是一种学习方式,平时我们只考虑网络结果和label的关系,这样就能拟合出和特征到label映射关系相近的信息,现在不仅要考虑到这两者的关系,而是多了老师网络,不仅考虑学生网络和label接近,还要求老师网络和学生网络接近,所以就通过损失函数来进行牵引。

NLP的知识蒸馏成果

BERT的效果已经得到广泛认可,然而由于其体积、推理速度等问题,即使可以免去了pretrain的烦恼,还是无法上线,为了让他能够上线,其中一个重要的方法就是蒸馏,因此在这块大家有了很多尝试。

BiLSTM借助BERT突破上限

对于很多人来说,BiLSTM已经看不上了吧,在最终预测效果上相形见绌,然而轻便快速是他能够被使用的关键。将BERT蒸馏到BiLSTM是一个比较容易想到的思路,先把文章摆出来:

Distilling Task-Specific Knowledge from BERT into Simple Neural Networks

文章的处理其实并不复杂,只不过是在训练过程中对损失函数进行了修改,来看看他的损失函数。

公式上和上面类似,只是没有把本身老师网络的损失放进去而已, 是网络信息的输出,这个信息最终经过softmax就是预测的结果,而在训练中,我们还需要在常规损失的基础上关心了师生两个网络输出的差距,于是求了两者的欧氏距离。

结果也是我比较希望给大家展示的:

从这个图可以看到,虽然蒸馏后的BiLSTM效果依旧不如BERT,但是相比自己的base,在没有任何模型结构的变化下,即可有明显的提升效果,换言之,其实我们可以认为当前的数据和训练方式目前依旧没有完全发挥特定模型结构的所有知识存储和表达能力,在更为高级模型的帮助下浅层模型仍然有进一步提升的空间,简单地说,BiLSTM没有被充分学习。

能少几层是几层:DistilBERT

BERT本身有较多的transformer层,这也是BERT比较强的核心原因之一,有了上面BiLSTM的经验,我们不禁要开始想一个问题,BERT里面的Transformer是不是也可能没有被充分学习呢?在更多层训练完的transformer(原版BERT)的支持下少几层的BERT是否仍然保持比较好的效果呢?论文在这里:

a distilled version of BERT: smaller, faster, cheaper and lighter

答案依旧是肯定的。

先来看看具体的操作方法,来张图:

模型的结构其实没什么大改:

  • 在12层Transformer-encoder的基础上每2层中去掉一层,最终将12层减少到了6层。

  • 去掉了token type embedding和pooler。

  • 利用teacher model的soft target和teacher model的隐层参数来训练student mdoel。

然后开始在损失函数上下了功夫:

  • :老师模型的损失函数,并使用了T进行进行了温度的调整。。

  • :bert训练任务的损失函数。

  • :老师模型输出向量和学生模型向量输出的余弦距离。

然后将三个损失函数进行线性组合:

同样来看看效果:

数据很简单,可以看到BistilBERT在大幅度简化模型的情况下仍能保持和BERT高度接近的效果。

手把手教学:TinyBERT

可能是认为上面的学习只是简单的在学结果,那么TinyBERT就是在手把手地教了,先把论文放过来:

TinyBERT: Distilling BERT for Natural Language Understanding

个人认为论文的核心就在于他的训练是手把手的,逐层去计算老师网络和学生网络之间的差距,以保证学生网络的推理过程就尽可能和教师模型一致。

当然,这种手把手的模式也是通过损失函数的优化来实现的:

  • :embedding层的学习,要求两者差距不大。

  • :attention的学习,要求每个头的平均情况要尽可能相同。

  • :隐含层,要求两者差距不大。

由于TinyBERT的transformer层数是少于BERT的,所以TinyBERT的每一层和BERT的那一层对齐就成为问题, 就表示TinyBERT中的第 层对应BERT的层数。

效果不多说了,和大家预预期一样,一方面稍弱于BERT,另一方面打败了一些炮灰。

从蒸馏想到的

知识蒸馏的魅力相信大家都能体验到了,而我在阅读这些论文的其实就在想很多,我来列举一下吧。

  • 浅层、传统的模型的知识承载能力可能还要高于我们的想象,还有可以挖掘的空间。

  • 但是要用传统模型进一步提升效果,可能需要依赖更加丰富复杂的数据或者更加丰富的学习手段,光填充数据可能有用,但是性价比可能不高。

  • 更复杂、更大的模型可能可以更多维度地关注到信息,然后进行整合,这些消化后的知识更容易为小模型所接受。

  • 从DistilBERT的结论看来,我现在甚至在怀疑BERT都没有被充分学习,其中几个头的信息就能吸收原bert的信息了。

  • 同等数量的数据,大模型的学习和信息整合应该强于浅层模型,这应该是导致小模型不如大模型的一个根本原因。

这是蒸馏实验带来的有关模型知识承载能力的思考,一言蔽之,小模型并非那么的弱,我们还可以进一步挖掘他,提升他,引入一个老师教他应该就是其中一个方法。

结论

全文花了很多精力讨论蒸馏是什么、NLP的蒸馏是咋整的,最后归结到很简短的几条思考,这几条思考终究是要落到我们的实践中,实践就是把那些我们所喜爱的飞机大炮,蒸馏成足够厉害的子弹装到我们手枪里,我们现在已经清晰的知道,一颗子弹不仅能消灭一个敌人,而是一群,他所蕴含的潜在威力超乎我们的想象。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值