背景
自2019年以来,除了BERT以外,NLP没有什么革命性的进展,当然革命性的进展也不是那么容易出现的。BERT在各NLP任务上取得了sota无不让人惊奇与跃跃欲试。如果你是刚入门NLP,可能BERT中的内容有些难度。前文介绍的【NLP】《Attention Is All You Need》的阅读笔记就是我为书写BERT相关内容做的准备。BERT的论文:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding。
BERT是用来干什么的呢?BERT首先会在大规模无监督的语料上进行预训练,然后在NLP的任务中,如:文本分类,命名实体识别等提供动态词向量。如在文本分类中,BERT直接再加上一个全连接网络效果就轻轻松松超过很多现有的神经网络模型。这种方式也称为:预训练+微调(finetune)。可以理解为一种提供词向量的新范式。
模型结构
BERT模型结构基本上就是Transformer的encoder部分,BERT-base对应的是12层encoder,BERT-large对应的是24层encoder。
模型的输入
BERT模型输入有一点特殊的地方是在一句话最开始拼接了一个[CLS] token,如下图所示。这个特殊的[CLS] token经过BERT得到的向量表示通常被用作当前的句子表示。除了这个特殊的[CLS] token,其余输入的单词类似Transformer。BERT将一串单词作为输入,这些单词在多层encoder中不断向上流动,每一层都会经过 Self-Attention和前馈神经网络。 BERT输入的文本是在进行token时是有自己的方式的,使用的是WordPieces作为最小的处理单元。语句处理成tokens后就需要考虑位置编码以及tokens, CLS,SEP进行Embedding编码了。
位置编码(对应下图的 Position Embeddings),不同于 Transformer 的位置编码用三角函数表示,BERT 的位置编码将在预训练过程中训练得到。
由于在 MLM 的训练过程中,存在单句输入和双句输入的情况,因此 BERT 还需要一套区分输入语句的分割编码(对应下图的 Segment Embeddings),BERT 的分割编码也将在预训练过程中训练得到。对于分割编码,Segment Embeddings 层只有两种向量表示。前一个向量是把 0 赋给第一个句子中的各个 token,后一个向量是把 1 赋给第二个句子中的各个 token ;如果输入仅仅只有一个句子,那么它的 segment embedding 就是全 0。
模型的输出
BERT输入的所有token经过BERT编码后,会在每个位置输出一个大小为 hidden_size(在 BERT-base中是 768)的向量。 在句子分类(文本分类)中,获取CLS 对应的向量再接一个分类器,如一个全连接层就可以进行分类。例如: 原论文是这样的: 由于BERT模型可以得到输入序列所对应的所有token的向量表示,因此不仅可以使用最后一层BERT的输出连接上任务网络进行微调,还可以直接使用这些token的向量当作特征。比如,可以直接提取每一层encoder的token表示当作特征,输入现有的特定任务神经网络中进行训练,例如在NER任务中。 原论文中的图形是这样的。
由于BERT的encoder比较多,效果如下图:
预训练过程
再次过程中使用的语言模型是Masked language model。简单来说就是:将输入文本序列的部分(15%)单词随机Mask掉,让BERT来预测这些被Mask的词语。了解过Word2vec的对此应该不难理解,如图: 除了使用masked language model训练模型之外,BERT在预训练时,还引入了一个新的任务:判断两个句子是否是相邻句子。如下图所示:输入是sentence A和sentence B,经过BERT编码之后,使用[CLS] token的向量表示来预测两个句子是否是相邻句子。 不过该任务在后来的研究中逐渐淡化。
总结
回过头来看,在了解了词向量,self-attention相关的知识后,来看看这部分内容理解起来就不会那么难了。当然文中还提到了ELMO,GPT等语言模型,感兴趣的可以深入了解。
由于模型各个模块逐渐增多,模型的体积也不断变大。BERTBASE (L=12, H=768, A=12, Total Parameters=110M) and BERTLARGE (L=24, H=1024, A=16, Total Parameters=340M)。也就是说Bert large的模型参数达到3.4亿。也就意味着深度学习模型进入大模型时代,这也为模型的部署提出了更高的挑战。模型参数这么多,模型在计算时间也随之加长,在实际生产上困扰着很多工程人员,当然加机器是一种解决方式,那么相关的成本就不断提升了。
现在由于BERT的火爆,使用中文语料预训练的模型也被开放出来了。除此之外,BERT的使用也在tensorflow,pytorch,Keras等平台有相关的工具包,例如pytorch中的transformers,使用起来也比较方便。后面我就不去造轮子了,调用相关的包去使用BERT模型,去解决相关的问题。如果对模型实现感兴趣的话,可以在github上查阅相关源码,因为在模型实现的过程中还会很多小tricks是不会在论文展开介绍的。这些小tricks在我们日常构建模型过程中还是有很多借鉴的意义的,所以要多看看源码呀。
|