当前位置: 首页 > 科技观察

为什么谷歌最强的NLP模型BERT又酷又厉害?腾讯程序员从头告诉你

时间:2023-03-13 12:19:59 科技观察

1.背景介绍在搜索场景中,用户的搜索query与召回文章标题的相关性对提升用户的搜索体验有很大帮助。query-title分级任务要求query和title根据文本相关性进行5级分类(1~5级),每一级从需求满足和语义匹配两个方面衡量query-doc的相关性,越大水平,相关性越高。比如level1表示文本和语义完全不相关,而level5表示文本和语义高度相关,完全满足查询的需要。我们尝试将Bert模型应用于query-title分类任务,将query和title作为句对输入Bert,取最后一层cls向量进行5个分类(如上图),最终结果优于LSTM-注意交互匹配模型更好。虽然我们知道bert可以解决这个问题,但是我们更好奇“为什么”:为什么bert可以表现的这么好?这里有什么可以解释的部分吗?因为Multi-head-attention是bert的主要组成部分,所以我们从“head”入手,希望搞清楚每个head对bert模型有什么影响。为了研究某个头对模型的影响,我们需要比较有头和没有头的模型前后的性能。在这里定义HEAD-MASK操作。其实对于某个head,直接将head的attention值设置为0,这样head对于任何输入都只能输出一个0向量。通过HEAD-MASK操作,对每个头进行了对比实验,发现了以下有趣的点。注意头非常冗余/健壮。移除20%的头部不影响头部模型。各层transformer之间没有串联关系。去掉一整层attention-head对下层影响不大。每个头都有固定的功能。有的负责人负责分词。一些负责人提取词序关系。有些负责人负责提取query-title之间的term匹配关系。让我们开始尝试文本,看看这些结论是如何得出的?2.Bert模型Attention-Head实验Attention-head是Bert的基本构建块。这个实验想研究每个人头对模型做出了什么贡献。通过Mask去除某个head,对比模型前后的性能差异,研究这个head对模型的影响(在训练好的bert上做head-mask,不重新训练,对比测试集的性能).bert-base模型一共12层,每层12个头。接下来的实验是每个head抽取的特征是否有明显的模式(Bert模型是在query-title数据上finetune的汉字模型)2.1Attention-Head相对冗余一共有12*12144个head在标准尺寸的伯特。我们尝试为训练好的bert模型随机mask出一定比例的人头,然后在测试数据集上测试分类准确率(五类)。下图中直方图的值表示acc相对于bseline(即没有任何head-mask)模型的相对提升。例如,+1%表示acc比基线模型高1%。从下图中可以发现,如果随机mask下降不到20%的头部,模型在测试数据集上的ACC不会下降,甚至当mask下降10%的头部时,与不戴头罩相比,模型性能将提高1%。当mask掉落超过一定数量的heads时,模型的性能会持续下降,mask掉落的次数越多,性能越差。同时为了找出哪个transformer对query-title分类更重要,对底层(layer0~layer5)和顶层(layer6~layer11)的head进行mask,去掉head的比例控制在0~50%(占总头数),50%表示去掉底层或者100%的顶层头。下图清楚地展示了底层和顶层之间的attention-head关系。)head,蓝色部分表示只屏蔽了最底层(0-5层)的head。显然,高层注意力头非常依赖底层头。底层注意力负责提取输入文本的各种特征,高层注意力负责组合这些特征。具体表现为当mask下降80%的底层头部(0~5层)(图中横坐标为40%)和mask下降100%的底层头部(横坐标)图中为50%),模型在测试数据集上的性能急剧下降(图中蓝色部分),说明去掉大部分后仅靠high-levelhead是不够的底层负责人。高级头不提取输入的特征。相反,去除了大部分的高层头后,模型下降并没有那么剧烈(图中橙色部分),说明底层头提取了很多对这个任务有用的输入特征,并且这些特征可以通过残差连接直接传递到末端。一层用于分类。这个结论也可以用来指导后面的模型蒸馏。实验结果表明,底部变压器比高层变压器更重要。显然,我们在蒸馏模型时需要保留更多的底头。那么模型有层吗?head会特别影响query-title分类吗?假设将bert中所有的attention-heads看成一个12*12的方阵,下面是根据rowmask去掉一整行heads后模型在测试数据上的表现。直方图上的值表示基线模型提升的相对性能。可以看出mask第5到第9层的headmodels都有比较大的正向提升,尤其是去掉整个第8层的attention-head后,测试数据的准确率相对提升了2.3%.从上图可以得出两个结论:Bert模型是非常健壮的或者是高度冗余的。Bert模型的层不是串行依赖的,信息不是通过transformer的层传递的。Bert模型非常稳健。或者冗余度很高,直接去掉一整层attention-head,对模型最终的性能影响不大。直接去掉整层的attention-head模型性能没有明显下降,说明每一层提取的特征信息并不是逐层串行传递给分类器,而是通过残差连接直接传递给对应的分类器.层。2.2部分头负责判断词的边界(这样词模型就有分词信息)。在我们的query-title分类场景中,发现wordgranularitybert和wordgranularitybert最终的表现是差不多的,而对于rnn模型来说,wordgranularityrnn很难达到wordgranularityrnn的效果。我们希望研究为什么词粒度和词粒度bert表现相似。使用bert可视化工具bert_viz观察每一层attention-head的注意力权重分布,可以发现部分head有明显的分词信息。推测这部分attention-head是专门用来提取分词信息的head。当当前词可能是词尾时,att的权重会偏向sep。当单词更可能是词尾(commonwordending)时,sep的权重会更高。当当前词不是词尾时,att指向下一个词。这个模式非常明显,直接使用这个attention-head的结果分词准确率是70%。下面的gif是我们模型第一层第3头的注意力分布权重图。可以发现注意力权重明显包含词边界信息。当当前词为末尾时,注意力权重最大的token为“SEP”。如果当前词不是结尾时,attention的权重是下一个词。用于提取分词信息的这种head有很多,不同的head有不同的分词粒度。如果综合考虑多粒度的分词(如果只有一个head分词是正确的),那么直接用attention-head来判断分词的准确率。率为96%,这就是词粒度bert和词粒度bert表现相似的原因。用于提取分词信息的head有很多,不同的head有不同的分词粒度。如果综合考虑多粒度分词(如果只有一个head分词是正确的),那么直接使用attention-head分词的准确率是96%,这也是wordgranularitybert和wordgranularitybert性能差不多的原因.猜词粒度。bert代词边界信息由bert的预训练任务MLM带来。语言模型的训练使得bert对各种词的组合非常敏感,从而能够区分词的边界信息。2.3有些头负责编码输入的顺序。我们知道bert的输入是三部分的加法:token_emb+pos_emb+seg_type_emb,文本输入的顺序由pos_emb隐式表示。bert中有些head实际上是负责提取输入中的位置信息。这个attention-head有明显的垂直对齐方式,如下图:原始输入:query="京东小哥",title="京东小哥最近在干什么",bert模型判断是4个文件,titlesorderisdisruped:query="京东哥",title="近东最火的是小京",bert模型判断是第二个文件,titles顺序打乱:query="Brother京东",title="东方最火的《港歌小京》mask掉了7个头疑似是用来提取词序的,bert模型判断为3档。下面几张图是不加mask的对比,随机mask7个head(重复100次取平均值)mask掉7个特定head(怀疑有词序信息的heads),从下图可以看出mask掉7个特定head后,整体分类升级为3档,而随机maskdrops7个头,结果还是2个档位,档位概率分布和没有mask的情况差别不大。这个案例说明我们屏蔽掉的7个特定的heads应该负责提取输入的序列信息,也就是词序信息。去掉这部分headmask后,bert就很难检测出title中的乱序,从而提高了分类效果。2.4部分负责人负责匹配query和title同一部分的terms。查询和标题中的相同术语是否是我们分类任务中非常关键的特征。如果query中的大部分term都能在title中找到,那么query和titletitle的相关性一般就比较高。比如query="京东哥"在title="京东哥最近在干什么"中完全可以查到,两者的文本相关度也很高。我们发现注意力头的一部分负责提取这个术语匹配特征。这个头的注意力权重分布大致如下图所示。可以看到同一个term在上一句和下一句的权重非常高(颜色越深,权重越大)。其中,2~4层5头匹配的格局尤为明显。我们发现虽然bert模型中的attention-head非常冗余,去掉一些head对模型影响不大,但是少量的head对模型来说非常重要。下面展示这五个头对模型的影响。表中数值表示baseline模型acc的相对提升值——不做HEAD-MASK随机MASK,drop5个HEADMASKs,drop5个specifiedHEADMASKs,dropallHEADMASKsfrom0to5layers,dropotherHEADsfrom0到5层,只保留这5个指定的HEAD测试数据准确率+0%+0%-52.4%-86.5%-18.1%以测试数据为标准,测试随机mask掉5个head和mask丢弃5个指定的头(这些头在注意力可视化中。具有显式查询标题匹配的模式)。从结果可以看出,去掉这些负责query-title匹配的heads后,模型性能急剧下降。只去掉这5个头,模型的性能就会降低50%。即使mask去掉了0~5层的其他heads,在只保留这5个heads的情况下,模型仍然保持了baseline模型82%的性能,这说明query-title的termmatching在我们的任务中非常重要.这可能是双塔bert在我们的场景中表现如此糟糕的原因(Bert+LSTM实验中两个模型结合的最终性能比只使用bert要差,而且bert的输入是双塔输??入),因为query和title是分开输入的,所以这些heads没有办法提取term的匹配特征(相当于mask丢掉这些heads),而这些匹配特征对我们的分类任务至关重要2.4.1finetune的影响ontheattention-headresponsibletotermmatching在query-title分类任务中,query和title是否有相同的term是一个很重要的特征,所以在finetune的过程中,负责匹配相同term的是head查询标题显着增强?我们以案例为例:query="IgrownupinIran"title="VacationMovie《我在伊朗长大》"下图是finetune负责term匹配前的query-title数据**某某**的finetune之前head的attention分布图,可以看出有些head也会对上下句中重复的term分配比较大的attention值。这个特性可能来自于训练任务NSP(上下句预测)。因为如果同一个term出现在上一句和下一句,他们是上句和下句的概率是比较高的,所以bert有一些head专门负责提取这个匹配信息。除了上句和下句对同一个term给予比较大的attention外,每个term对自身也有比较大的attention权重(图中对角线表示的数值都比较大)依次为了更直观的看出训练前后哪部分的attention值有比较大的变化,分别展示了训练后增强attention(微调前-fine-tuning>0)和弱化attention的分布图训练后的关注度(微调前-微调后<0)。可以观察到几个明显的点:query和title中的termmatching的attentionvalue变大了。从下图可以看出,当query和title有相同的term时,attention相比训练前有比较大的增强。说明在下游任务(query-titleclassification)训练中,该head的同词匹配信息的抽取能力得到了提升。这个词和它自己的注意力变小了。该模型侧重于查找query和title中是否存在相同的term,从而削弱了term对自身的注意力权重。分隔符sep的attention值变小。有论文指出,当一个token的attention指向sep时,意味着没有分布的状态(即此时没有找到合适的attention分布方法),经过finetune后指向sep的term权重变小,也就是说经过query-title数据训练后,这个head的attention分配就更加清晰了。2.4.2是否有某个头部特别能影响模型?从上面的实验我们可以看出bert模型有更多的冗余头。移除其中一些头部不会对模型产生太大影响,但少量头部会对模型产生特别大的影响。比如上面提到的head,负责抽取上下句中的term匹配信息。仅去除5个这样的头,模型的性能就会降低50.%。那么有没有某个头特别能影响结果呢?在下面的实验中,每次只mask一个头,看模型的性能在测试数据中有没有增加/减少。下图中,将bert的144个head看成一个12X12的矩阵,矩阵中的每个元素代表去掉head后模型在测试数据上的表现。其中,0表示去除后对模型的影响不是太大。元素中的值表示相对于baseline的性能提升,比如+1%表示acc相对于baseline提高了1%。可以看出,对于bert的大部分head,单独去掉这个head对模型影响不大,但是少数head确实可以影响模型,比如那些负责匹配同一个term的head上句和下句(查询标题)。头。即使移除一个这样的头也会降低模型的性能。同时注意到上层(第10层)有一个头,去掉头后模型的性能变化很大。实验发现head函数负责提取bottomhead输出的特征,即3-4层的head提取输入的query-title具有相同的term特征后,这部分信息会被传递到第10层进一步提取,最终影响分类。2.4.3high-levelhead如何提取底层的headfeatures——一个典型案例上图中,第10层有一个head,去掉后会对模型产生影响。观察其注意力分布。cls的注意力集中在同一个query和title上。在term上,好像是进一步抽取底层termmatchinghead抽取的特征,并将这个匹配特征保存到cls中(cls的最后一层会用于分类)。当没有做head-mask时,可以看出cls的attention主要分配给了query和title中的常用词“PurpleIron”,当mask掉了5个2-4层heads(有词匹配功能),layer10的clsattention分配明显改变了,分散到更多的term上。这个案例展示了高层attention-head是如何依赖底层head的特征,进一步提取底层特征,最后将它们作为query-title分类的重要特征。结论本文主要讨论bert模型在query-title分类场景下的可解释性。主要是从attention-head的角度,我发现attention一方面是非常冗余的,去掉一部分head对模型影响不大。另一方面,有些头对模型的影响很大。即使去掉一个,模型的性能也会下降很多。同时发现,不同的脑袋其实都有特定的功能。比如底层head负责对输入进行特征提取,比如分词,提取输入的词序关系,提取query和title中的相同term信息(即上下句).这部分底层head提取的特征会通过残差连接发送给high-levelhead,high-levelhead会进一步融合这部分特征信息,最后作为分类输入到分类器中特征。本文重点关注哪些头对模型有正面影响,即去除这些头后模型的性能变差。但是如果我们知道哪些头对模型有负面影响,也就是为什么要去掉一些头模型比较好,其实对我们有更多的指导作用。这部分信息可以帮助我们在加速模型和提升模型性能上少走弯路。参考文献[1]ClarkK,KhandelwalU,LevyO,etal.BERT看什么?BERT的Attention分析[J].arXivpreprintarXiv:1906.04341,2019.[2]VigJ.Transformer模型中注意力的多尺度可视化[J].arXiv预印本arXiv:1906.05714,2019。