【说在前面】本人博客新手一枚,象牙塔的老白,职业场的小白。以下内容仅为个人见解,欢迎批评指正,不喜勿喷![握手][握手]
知识蒸馏被广泛的用于模型压缩和迁移学习当中。
本文主要参考:模型压缩中知识蒸馏技术原理及其发展现状和展望
知识蒸馏可以将一个网络的知识转移到另一个网络,两个网络可以是同构或者异构。做法是先训练一个teacher网络,然后使用这个teacher网络的输出和数据的真实标签去训练student网络。
知识蒸馏是对模型的能力进行迁移,根据迁移的方法不同可以简单分为基于目标驱动的算法、基于特征匹配的算法两个大的方向。
从上图中可以看出,包括一个teachermodel和一个studentmodel,teachermodel需要预先训练好,使用的就是标准分类softmax损失,但是它的输出使用带温度参数T的softmax函数进行映射,如下:
当T=1时,就是softmax本身。当T>1,称之为softsoftmax,T越大,因为输入zk产生的概率f(zk)差异就会越小。之所以要这么做,其背后的思想是:当训练好一个模型之后,模型为所有的误标签都分配了很小的概率。然而实际上对于不同的错误标签,其被分配的概率仍然可能存在数个量级的悬殊差距。这个差距,在softmax中直接就被忽略了,但这其实是一部分有用的信息。
训练的时候小模型有两个损失:一个是与真实标签的softmax损失,一个是与teachermodel的蒸馏损失,定义为KL散度。
当teachermodel和studentmodel各自的预测概率为pi,qi时,其蒸馏损失部分梯度传播如下:
可以看出形式非常的简单,梯度为两者预测概率之差,这就是最简单的知识蒸馏框架。
Hinton等人提出的框架是在模型最后的预测端,让student模型学习到与teacher模型的知识,这可以称之为直接使用优化目标进行驱动的框架,类似的还有ProjectionNet。
PrjojectNet同时训练一个大模型和一个小模型,两者的输入都是样本,其中大模型就是普通的CNN网络,而小模型会对输入首先进行特征投影。每一个投影矩阵P都对应了一个映射,由一个d-bit长的向量表示,其中每一个bit为0或者1,这是一个更加稀疏的表达。特征用这种方法简化后自然就可以使用更加轻量的网络的结构进行训练。那么怎么完成这个过程呢?文中使用的是localitysensitivehashing(LSH)算法,这是一种聚类任务中常用的降维的算法。
优化目标包含了3部分,分别是大模型的损失,投影损失,以及大模型和小模型的预测损失,全部使用交叉熵,各自定义如下:
基于优化目标驱动的方法其思想是非常直观,就是结果导向型,中间怎么实现的不关心,对它进行改进的一个有趣方向是GAN的运用。
结果导向型的知识蒸馏框架的具体细节是难以控制的,会让训练变得不稳定且缓慢。一种更直观的方式是将teacher模型和student模型的特征进行约束,从而保证student模型确实继承了teacher模型的知识,其中一个典型代表就是FitNets,FitNets将比较浅而宽的Teacher模型的知识迁移到更窄更深的Student模型上,框架如下:
FitNets背后的思想是,用网络的中间层的特征进行匹配,不仅仅是在输出端。它的训练包含了两个阶段:
(1)第一阶段就是根据Teacher模型的损失来指导预训练Student模型。记Teacher网络的某一中间层的权值Wt为Whint,意为指导的意思。Student网络的某一中间层的权值Ws为Wguided,即被指导的意思,在训练之初Student网络进行随机初始化。需要学习一个映射函数Wr使得Wguided的维度匹配Whint,得到Ws',并最小化两者网络输出的MSE差异作为损失,如下:
(2)第二个训练阶段,就是对整个网络进行知识蒸馏训练,与上述Hinton等人提出的策略一致。不过FitNet直接将特征值进行了匹配,先验约束太强,有的框架对激活值进行了归一化。
基于特征空间进行匹配的方法其实是知识蒸馏的主流,类似的方法非常多,包括注意力机制的使用、类似于风格迁移算法的特征匹配等。
知识蒸馏还有非常多有意思的研究方向,这里我们介绍其中几个。
机器学习模型要解决的问题如下,其中y是预测值,x是输入,L是优化目标,θ1是优化参数。
因为深度学习模型没有解析解,往往无法得到最优解,我们经常会通过添加一些正则项来促使模型达到更好的性能。
BornAgainNeuralNetworks框架思想是通过增加同样的模型架构,并且重新进行优化,以增加一个模型为例,要解决的问题如下:
具体的流程就是:
(1)训练一个教师模型使其收敛到较好的局部值。
(2)对与教师模型结构相同的学生模型进行初始化,其优化目标包含两部分,一部分是要匹配教师模型的输出分布,比如采用KL散度。另一部分就是与教师模型训练时同样的目标,即数据集的预测真值。
然后通过下面这样的流程,一步一步往下传,所以被形象地命名为“bornagain”。
类似的框架还有Net2Net,networkmorphism等。
一般知识蒸馏框架都需要包括一个Teacher模型和一个Student模型,而Deepmutuallearning则没有Teacher模型,它通过多个小模型进行协同训练,框架示意图如下。
Deepmutuallearning在训练的过程中让两个学生网络相互学习,每一个网络都有两个损失。一个是任务本身的损失,另外一个就是KL散度。由于KL散度是非对称的,所以两个网络的散度会不同。
相比单独训练,每一个模型可以取得更高的精度。值得注意的是,就算是两个结构完全一样的模型,也会学习到不同的特征表达。
网络结构如上图所示,Teacher模型是一个全精度模型,Apprentice模型是一个低精度模型。
本文主要参考:知识蒸馏在推荐系统中的应用
深度学习模型正在变得越来越复杂,网络深度越来越深,模型参数量也在变得越来越多。而这会带来一个现实应用的问题:将这种复杂模型推上线,模型响应速度太慢,当流量大的时候撑不住。
知识蒸馏就是目前一种比较流行的解决此类问题的技术方向。复杂笨重但是效果好的Teacher模型不上线,就单纯是个导师角色,真正上战场挡抢撑流量的是灵活轻巧的Student小模型。
在智能推荐中已经提到,一般有三个级联的过程:召回、粗排和精排。
以上环节都可以采用知识蒸馏技术来优化性能和效果,这里的性能指的线上服务响应速度快,效果指的推荐质量好。
精排环节注重精准排序,所以采用尽量多特征复杂模型,以期待获得优质的个性化推荐结果。这也意味着复杂模型的在线服务响应变慢。
(1)在离线训练的时候,可以训练一个复杂精排模型作为Teacher,一个结构较简单的DNN排序模型作为Student。
(2)在模型上线服务的时候,并不用那个大Teacher,而是使用小的Student作为线上服务精排模型,进行在线推理。
(1)阿里妈妈在论文"RocketLaunching:AUniversalandEfficientFrameworkforTrainingWell-performingLightNet"提出。
在精排环节采用知识蒸馏,主要采用Teacher和Student联合训练(JointLearning)的方法。所谓联合训练,指的是在离线训练Student模型的时候,增加复杂Teacher模型来辅助Student,两者同时进行训练,是一种训练过程中的辅导。
从网络结构来说,Teacher和Student模型共享底层特征Embedding层,Teacher网络具有层深更深、神经元更多的MLP隐层,而Student则由较少层深及神经元个数的MLP隐层构成,两者的MLP部分参数各自私有。
(2)爱奇艺在排序阶段提出了双DNN排序模型,可以看作是在阿里的rocketlaunching模型基础上的进一步改进。
为了进一步增强student的泛化能力,要求student的隐层MLP的激活也要学习Teacher对应隐层的响应,这点同样可以通过在student的损失函数中加子项来实现。但是这会带来一个问题,就是在MLP隐层复杂度方面,Student和Teacher是相当的。那么,Teacher相比student,模型复杂在哪里呢?
这引出了第二点不同:双DNN排序模型的Teacher在特征Embedding层和MLP层之间,可以比较灵活加入各种不同方法的特征组合功能。通过这种方式,体现Teacher模型的较强的模型表达和泛化能力。
召回或者粗排环节,作为精排的前置环节,需要在准确性和速度方面找到一个平衡点,在保证一定推荐精准性的前提下,对物品进行粗筛,减小精排环节压力。这两个环节并不追求最高的推荐精度。毕竟在这两个环节,如果准确性不足可以靠返回物品数量多来弥补。而模型小,速度快则是模型召回及粗排的重要目标之一。
作者给出了一些可能的处理方式,目前业内还没定论。
(1)设想一:召回蒸馏的两阶段方法
(2)设想二:logits方法
(3)设想三:Without-Logits方案
(4)设想四:PointWise蒸馏:PointWiseLoss将学习问题简化为单Item打分问题。
(5)设想五:PairWise蒸馏:PairWiseLoss对能够保持序关系的训练数据对建模。
(6)设想六:ListWise蒸馏:ListWiseLoss则对整个排序列表顺序关系建模。
(7)设想七:联合训练召回、粗排及精排模型的设想
引用Robipolikar对增量学习算法的定义,即一个增量学习算法应同时具有以下特点:
在概念上,增量学习与迁移学习最大的区别就是对待旧知识的处理: