最近承接了项目要复现tiny_Bert。所以在这里用文章记录自己学到的。这篇文章是前置,主要介绍bert原理。 下一篇文章介绍tinybert的原理和训练

模型介绍:

BERT概述:

    如果要介绍tinyBERT,首先我们需要了解BERT模型。(了解BERT模型之前,希望你对Transformer结构已经有了基本的了解。bert:https://arxiv.org/abs/1810.04805。Transformer: Attention is All you Need)。 简单的介绍一下,Transformer的结构分为编码器和解码器,编码器可以把文字编码成高纬度的特征,而解码器可以用这些特征去完成相应任务,比如生成翻译。Transformer是如此的强大,以至于nlp届的两大巨头其实都是由他的一部分改变而来,如下图。GPT取用的是Transformer的解码器部分,而BERT取的是Transformer的编码器,因此Bert的作用,大家可以理解为一个编码器,将输入编码为高维的特征。

  在CV领域,在imagenet上训练一个编码器,迁移到其他任务,已经是惯用手段了。 而在BERT以前,NLP领域使用预训练技术的并不多。BERT为无标注的文本设计了两个自监督预训练任务,第一个是MLM(Masked Language Model)任务: 遮盖掉句子中一定比例的单词,使用剩余单词来预测被遮盖的词。 第二个是NSP(Next Sentence Prediction)任务:预测输入的两个句子是否是上下文关系。这样,无需标注即可在海量文本数据上进行预训练,得到一个效果十分良好的编码器,然后使用此编码器在其他文本任务上进行微调。BERT所建立的预训练加微调的模式在后续的NLP网络中得到了广泛的应用。

BERT结构

在这里介绍bert的基本结构,会涉及代码里的一些参数。一句文本,进入BERT后,首先经过编码层:被分词,然后分别编码。之后编码后的特征会进入BERT自注意力模块中进行提取,最后得到深度特征。下面详细介绍这个步骤。

嵌入层(embedding layer):

 BERT源自Transformer,他们的嵌入层也是很相似的。上图是Transformer的嵌入层,我们可以看到,当一个分词变为输入时,首先要经过词嵌入(Embedding),变为长度为hidden_size的向量(图中为6,实际一般很长),字所在的位置也要进行嵌入。两个嵌入向量直接数值相加,我们就得到了嵌入层的输出。
   
   下图则是BERT的嵌入层,它的输出来源于三个嵌入向量相加。我们可以看到有两个区别。1:增加了句子嵌入(segment Embeddings),因为BERT的输入是两个句子,因此要在这里用句子嵌入值标识出是哪一句。2:出现了字符token,如E[cls],E[sep]。CLStoken一般用来统计全局的信息,最后可以用此token的特征进行下游分类任务。SEPtoken则表示句子的分割和中止。  其实还存在着第三个区别:Transformer的位置嵌入是固定的,也就是公式算出的值,而BERT的位置嵌入则是模型训练得到的。(其他嵌入也都是训练得到)。

   

 一层bert:

 

    首先需要知道的是,每个BERT layer ,都是不改变特征的维度的(如上图)。由于输入和输出维度一直相同,因此可以堆叠无数层,一直往上叠下去(然后带来极大的运算开销)。对于BERT的base模型,是堆叠了12层,而large模型 堆叠了24层。

   而一个BERT layer 是由 多头自注意力层和MLP组成的。先介绍自注意力层。

 自注意力层,有时候写作Transformer blocks,是进行特征交互,提取的关键部分。这一部分,李宏毅老师是讲的非常好的。如下。

第四节 2021 - 自注意力机制(Self-attention)(上)_哔哩哔哩_bilibili

 当然我也会文字介绍。

  因为每层都是相同的,所以我们只看一层。如下图所示。 图中的a1,a2与上图是对应的,指的就是一个token的特征。每一个token,都会分别经过三个不同的线性映射(也就是三个全连接),得到query,key和value(q,k,v)。然后对于每一个token,它的q会与其他token的k相乘得到一个权重,它的 v 按照这些权重加起来,就得到了这个token的输出。

     不得不提到的是,多头注意力机制。通过上图,我们了解到了注意力机制是如何工作的,那么多头注意力机制其实非常简单。 举例说明:如下图。 一个长为6的特征转换为Q,K,V后,  长为6的Q,K,V 被分到3个注意力头中。每个头中,仅需长度为6/3=2的特征计算自注意力,最后得到3个长度为2的特征,再拼在一起就得到了输出。维度和输入相同,每一个token都这样操作,因此能保证输入输出的维度不变。

而后面的mlp层是两次线性映射,首先通过一个全连接从长度L的向量变为 L*ratio,然后再通过一个全连接从L*ratio 到L,

 对于一个BERT-base模型,他的特征长度L为768,注意力头的个数为12.这样每个头计算的特征长度就为64. 而ratio值为4.也就是先从768到3072,再从3072到768.而他的输入token数量,最大为512。

输出层

        输出前面已经提到了,与输入是一样的。 如输入是 512*768 那么输出依然是512*768(512个token,768的特征长度)。你可以认为输入和输出是一一对应的,也可以认为他们并不对应。BERT的工作其实到这里就结束了,我们要得到的就是一个编码器而已。 对于预训练任务,其实也表示了bert完成生成和分类两个下游任务的一般方式。 MLM任务: 可以取遮盖token对应的输出token的特征,通过一个分类,得到输出的词,这样可以做生成任务(但BERT很少直接用于生成任务)。SEP任务: 取第一个token的特征,也就是CLStoken 进行二分类。

        当然你也可以采取平均池化等方式得到输出的特征。L_{token}

至此,你知道了BERT的运转流程。比如你想拿bert做一个下游的分类任务,你就可以把文字输入到bert中去,得到特征,用这个特征做个分类就行。easy!

GitHub 加速计划 / be / bert
37.61 K
9.55 K
下载
TensorFlow code and pre-trained models for BERT
最近提交(Master分支:2 个月前 )
eedf5716 Add links to 24 smaller BERT models. 4 年前
8028c045 - 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐