以前理解的模型蒸馏就是模型“提纯”,这样说太宽泛了,应该说 蒸馏是“提纯”的一种手段而已。
知识蒸馏具体指:让小模型去学到大模型的知识。通俗的说,让student模型的输出接近(拟合)teacher模型的输出。知识蒸馏的重点在于拟合二字,即我们要定义一个方法去衡量student模型和teacher模型的接近程度,说白了就是损失函数。必备元素为:教师模型、学生模型、损失函数。
为什么需要知识蒸馏?
因为大模型推理慢难以应用到工业界。小模型直接进行训练又不如蒸馏得到的效果好。
相关工作介绍:
(1)Hinton在论文:Distilling the Knowledge in a Neural Network提出了知识蒸馏的方法。
损失函数:Loss = a L{soft} + (1-a) L{hard}
其中L{soft}是studentModel和TeacherModel的输出的交叉熵,L{hard}是studentModel输出和真实标签的交叉熵。L{soft},我们直到TeacherModel的输出是经过softmac处理的,指数e拉大来各个类别之间的差距,最终输出结果特别像one-hot向量,这样不利于studentModel的学习,因此我们希望输出更加软一些。因此我么我们需要修改一些softmax函数:
显然T越大输出越软。这样改完之后,对比原始softmax,梯度相当于乘了1/T^2,因此L{soft}需要再乘以T^2来与L{hard}在一个数量级上。
最后再放一张这个算法的整体框架图:
(2)TinyBert
首先说到对Bert的蒸馏大家肯定会想到就用微调好的Bert作为TeacherModel去训练一个StudentModel,没错目前就是这么干的。那么下面的问题就是我们选取什么模型作为StudentModel,这个已经有一些尝试了,比如有人使用BiLSTM,但是更多的人还是继续使用了Bert,只不过这个Bert会比原始的Bert小。在TinyBert中,StudentModel使用的是减少embeddingsize、hidden size和num hidden layers的小bert。
那么新的问题又来了,我们怎么初始化StudentModel?
最直接的解决方案就是随机化,模型不都是这么训练的吗?但是这种效果真的好吗?我看未必,如果没问题那么为啥那么多人用预训练模型?所以啊,我们需要一个比较好StudentModel的参数,确切说,我们需要一个与训练的studentModel,那么怎么获取一个预训练的StudentModel,TinyBert给出的答案就是咱们再用预训练好的Bert蒸馏出一个预训练好的StudentModel。(是不是很绕,感觉等于没说,要想弄明白,还是要实践,实践出真知)
Ok,TinyBert基本讲完了,简单总结下,TinyBert一共分为两步:
1、用pretrained bert蒸馏一个pretrained TinyBert
2、用fine-tuned bert蒸馏一个fine-tuned TinyBert(它的初始参数就是第一步里pretrained TinyBert)
在进行蒸馏的时候,会先进行隐层蒸馏(即m<=M),然后再执行m = M+1时的蒸馏。
总结一下,TinyBert在蒸馏的时候,不仅要让StudentModel学到最后一层的输出,还要学到中间几层的输出。换言之,studentModel的某一隐层可以学到TeacherModel若干隐层的输出。感觉蒸馏的力度比较细,我觉得可以叫做LayerBasedDistillation.
(3)BERT-OF-Theseus
这个准确的来说不是知识蒸馏,但是它确实减小了模型体积,而且思路和TinyBERT、DistillBERT都有类似。这个思路非常优雅,它通过随机使用小模型的一层替换大模型中若干层来完成训练。举一个例子:假设大模型是
input->tfc1->tfc2->tfc3->tfc4->tfc5->tfc6->output,然后再定义一个小模型input->sfc1->sfc2->sfc3->output。再训练过程中还是要训练大模型,只是在每一步中,会随机的将(tfc1, tfc2),(tfc3,tfc4),(tfc5,tfc6)替换sfc1, sfc2, sfc3,而且随着训练的进行,替换的概率不断变大,因此最后就是在训练一个小模型。
方式优雅,作者提供了源码,强烈推荐大家用一用。
(4)MiniLM
1、先用TeacherModel蒸馏一个中等模型,再用中等模型蒸馏一个较小的StudentModel。只有在StudentModel很小的时候才会这么做。
2、只对最后一个隐层做蒸馏,作者认为这样可以让StudentModel有更大的自由空间,而且这样对StudentModel架构的要求就变得宽松了。
3、对于最后一个隐层主要是对attention权重做学习。
相关库的使用见如下链接:
https://www.cnblogs.com/SuperDun/p/12442919.html
后期会增加这一部分的实战介绍。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深度学习–知识蒸馏介绍 - Python技术站