Skip to content

Latest commit

 

History

History
69 lines (36 loc) · 3.72 KB

Theseus-模块压缩交替训练.md

File metadata and controls

69 lines (36 loc) · 3.72 KB

大家好,我是DASOU,今天介绍一下:BERT-of-Theseus

这个论文我觉得还挺有意思,攒个思路。

读完这个文章,BERT-of-Theseus 掌握以下两点就可以了:

  1. 基于模块替换进行压缩

  2. 除了具体任务的损失函数,没有其他多余损失函数。

效果的话,与$Bert-base$相比,$BERT-of-Theseus$:推理速度 $1.94$;模型效果 98%;

模块替换

举个例子,比如有一个老师网络是12层的Bert,现在我每隔两层Transformer,替换为学生网络的一层Transformer。那么最后我的学生网络也就变成了6层的小Bert,训练的时候老师网络和学生网络的模块交替训练。

直接看下面这个架构图:

BERT-of-Theseus

作者说他是受 Dropout 的启发,仔细想了想还真的挺像的。

我们来说一下这样做的好处。

我刚才说每隔老师网络的两层替换为学生网络的一层。很容易就想到PKD里面,有一个是PKD-Skip策略。

就是每隔几层,学生网络的层去学习老师网络对应层的输出,使用损失函数让两者输出接近,使用的是CLS的输出。

在这里提一下蒸馏/压缩的基本思想,一个最朴素的想法就是让学生网络和老师网络通过损失函数在输出层尽可能的靠近。

进一步的,为了提升效果,可以通过损失函数,让学生网络和老师网络在中间层尽可能的靠近,就像PKD这种。

这个过程最重要的就是在训练的时候需要通过损失函数来让老师网络和学生网络尽可能的接近。

如果是这样的话,问题就来了,损失函数的选取以及各自损失函数之前的权重就需要好好的选择,这是一个很麻烦的事情。

然后我们再来看 BERT-of-Theseus,它就没有这个问题。

它是在训练的时候以概率 $r$ 来从老师网络某一层和学生网络的某一层选择一个出来,放入到训练过程中。

在这个论文里,老师网络叫做 $predecessor$, 学生网络叫做 $successor$

训练过程

对着这个网络架构,我说一下整体训练的过程:

  1. 在具体任务数据上训练一个 BERT-base 网络作为 $predecessor$
  2. 使用 $predecessor$ 前六层初始化一个 6层的Bert作为 $successor$
  3. 在具体任务数据上,固定 $predecessor$ 相应权重,以概率$r$(随着steps,线性增加到1),对整个网络($predecessor$加上$successor$ )进行整体的训练。
  4. 为了让$successor$ 作为一个整体,单独抽离出来$successor$ (其实$r$设置为1就可以了),作为一个单独的个体,在训练数据上继续微调。直至效果不再增加。

简单总结,在训练数据上,老师网络和学生网络共同训练,因为存在概率问题,有的时候是老师网络的部分层加入训练,有的时候是学生网络的部分层加入训练。在这一步训练完成之后,为了保证学生网络作为一个整体(因为在第一步训练的时候大部分情况下学生网络的层都是分开加入训练过程的),在具体任务数据上,对学生网络继续微调,直至效果不再增加。

结果分析

不同方法的损失函数

论文提供了一个不同Bert蒸馏方法使用的损失函数的图,值得一看,见下图:

bert蒸馏不同方法损失函数

值得注意的是,这里的 $Finetuning$应该是选取前六层,在具体任务微调的结果。

效果

BERT-of-Theseus实验效果

整体来说,BERT-of-Theseus 思路很简单,效果也还不错。