BERT是在Google论文《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》中被提出的,是一个面向NLP的无监督预训练模型,并在多达11个任务上取得了优秀的结果。这个模型的最大意义是使得NLP任务能够向CV同样使用与训练模型,这极大的方便了一个新的任务开始,由于在NLP领域,海量数据的获取仍是有难度的。git
模型概述:BERT是一个无监督的NLP与训练模型,结构上是Transformer的编码部分,每一个block主要由多头self-Attention、标准化(Norm)、残差链接、Feed Fordawrd组成。在具体任务中,主要分为模型预训练和模型微调两个阶段。在模型预训练阶段,由于模型参数巨大,一般是上千万乃至上亿的数量级,因此须要大量的数据训练,所幸这时候模型是无监督的,只须要爬取或使用开源数据集便可;在模型微调阶段,须要针对具体的任务来微调模型,已达到较好的效果。github
Bert就是Transformer的编码部分,下图是Transformer的具体结构:npm
上图左侧为Transformer的编码部分,右侧为Transformer的解码部分,本文主要以编码部分详细讲解Bert的结构。左侧的编码部分包括输入,添加位置编码,以self-Attention、Add&Norm、Feed Fordward的block。下面就每一个具体细节进行具体分析。网络
位置编码是用来捕获文本之间的时序关联性的,例如打开如今热度第一的新闻的第一句话:“重庆主城区一栋30层的居民楼发生大火,形成百余名群众被困,重庆市政府迅速调集消防、公安、卫生等数百名人员赶赴现场施救。”其中,“重庆市”与“主城区”相关度最高,位置最近。当对NLP文本处理时,位置更近的文本通常相关性更大,因此将位置编码融入到数据中是颇有必要的。须要要说明的是与Bert这种所有基于Attention不一样的是,以前基于RNN的模型在模型结构上已经能够将这种时序信息考虑在内。koa
在具体处理方式上,采用的是Embedding+Positional的方法,将数据之间的关联性融入到数据中。Embedding是嵌入到相应维度的文本数据,Positional在论文中使用了\(sine\)和\(cosine\)函数的线性变换来提供模型的位置信息,公式以下:
\[ PE_{(pos,2i)}=sin(pos/10000^{2i/d_{model}})\\PE_{(pos,2i+1)}=cos(pos/10000^{2i/d_{model}}) \tag{1} \]
那为什么加了位置编码就能获取数据间位置的特征呢?在self-attention的结构中,在对每维数据计算权重时,是采用点积的形式,本质上就是计算向量之间的相关性。而位置编码将临近的数据加上频率接近的位置编码,就是增长了相邻数据的相关性。下图是位置编码向量的热图,能够看出距离越近,频率就更加接近。jvm
self-attention是BERT的重要思想,其与位置编码结合,解决了文本数据的时序相关性的问题,从而一举结束了依靠RNN、LSTM、GRU等以前一直用来解决时序问题的网络模型。self-attention通俗的说就是信息向前传播时动态的计算权重的一种方式,与CNN常见的MaxPooling、MeanPooling不一样的是,attention模型是通过训练,当不一样信息传入时,自动的调整权重的一种结构。self-attention的具体结构以下图所示:
函数
具体的,将上图的过程进行详细的解释,主要是拆分红4个步骤:
1)\(x^1, x^2, x^3, x^4\)表明的是通过embedding的4条时序文本信息,首先将4条信息加上位置向量,获得\(a^1, a^2,a^3, a^4\),这样作的目的上文已经说过,是为了获取文本的时序相关性。ui
2) 对每条信息分配三个权重\(W_Q, W_K, W_V (embed.dim*embed.dim)\),分别与\(a^1, a^2, a^3, a^4\)相乘后造成3个矩阵\(Q, K, V\)也就是上图的\(q^i, k^i, v^i\)。
\[ Q = Linear(a^1) = a^iW^Q\\ K = Linear(a^1) = a^iW^K \\ V = Linear(a^1) = a^iW^V \]
3) 将\(q_1\)分别与\(k^1, k^2, ...,k^i\)点乘,获得\(\alpha_{1, i}\),再有softmax的计算公式,计算得\(\hat\alpha_{1, i}\)。
\[ \alpha_{1, i} = q^1*k^i\\ \hat\alpha_{1, i} = exp(\alpha_{1, i})/\sum_j{exp(\alpha_{1, j})} \]
4)最后按照softmax输出的权重对\(V\)进行加权,计算得\(b^1\)。使用一样的方法计算得\(b^2, b^3, ...,b^i\)。将\(b^1, b^2, b^3, ...,b^i\)进行合并,完成self-attention。
\[ b^1 = \sum_i\hat{\hat\alpha_{1, i}*v^i} \]编码
残差链接是训练深层模型时惯用的方法,主要是为了不模型较深时,在进行反向传播时,梯度消失等问题。具体实现时,当网络进行前向传播时,不只仅时按照网络层数进行逐层传播,还会由当前层隔一层或多层向前传播,以下图所示:spa
以上是BERT的总体结构,Input输入的是文本数据,通过Embedding加上位置向量Positional Encoding。Multi-Head Atention为多头的self-Attention,实际上就是将self-attention的Q、K、V均分红n份,分别进行计算。Add&Norm为残差计算和标准化;Feedward为全链接层,进行前向传播。其中\(N_x\)为基本单元的个数,是能够条调整的超参数。
在预训练Bert模型时,论文提供了两种策略:
在BERT中, Masked LM(Masked language Model)构建了语言模型, 这也是BERT的预训练中任务之一, 简单来讲, 就是随机遮盖或替换一句话里面任意字或词, 而后让模型经过上下文的理解预测那一个被遮盖或替换的部分, 以后作的时候只计算被遮盖部分的
, 实际上是一个很容易理解的任务, 实际操做方式以下:
参考内容:
[1] Vaswani A, Shazeer N, Parmar N, et al. Attention is all you need[C]//Advances in neural information processing systems. 2017: 5998-6008.
[2] Devlin J, Chang M W, Lee K, et al. Bert: Pre-training of deep bidirectional transformers for language understanding[J]. arXiv preprint arXiv:1810.04805, 2018.