Bert模型详解

BERT 模型详解

本篇文章共 15326 个词,一个字一个字手码的不容易,转载请标明出处:
BERT 模型详解 - 二十三岁的有德html

1、BERT 引入

BERT 在天然语言处理(NLP)领域刷新了 11 个任务的记录,万众瞩目,成为异常火热的一个预训练语言模型。python

今天咱们就来详细讲解下 BERT 这个预训练语言模型,虽然 BERT 刷新了各个任务的记录,可是 BERT 并非一个具备极大创新的算法,更多的是一个集大成者,把 BERT 以前各个语言模型的优势集于一身,并做出了适当的改进,而拥有了现在无与伦比的能力。git

BERT 既然是集大成者,那么集了哪些大成呢?github

  1. BERT 做为一个预训练语言模型,它的预训练思想借鉴了图像领域中的预训练的思想;
  2. 做者说的是借鉴了完形填空任务的思想(双向编码),但我感受应该也借鉴了 Word2Vec 的 CBOW 的思想,由于二者本质上是相同的;
  3. 没有使用传统的类 RNN 模型做为特征提取器,而是使用了最近火热的 Transformer 做为特征提取器,而 Transformer 又使用了 Attention 机制做为特征提取器,更是火上浇油
  4. 真要说创新,也许就是在 CBOW 的思想之上,添加了语言掩码模型(MLM),减小了训练阶段和推理阶段(测试阶段)的不匹配,避免了过拟合;
  5. 因为单词预测粒度的训练到不了句子关系这个层级,为了学会捕捉句子之间的语义联系,BERT 采用了下句预测(NSP )做为无监督预训练的一部分,这也算是一个小小的创新吧。

既然是集大成者,那么咱们只要把上述五点大成一一解释清楚,相信再带你看 BERT 时,你必定会豁然开朗:“BERT 不过如此”。算法

2、图像领域的预训练

在叙述图像领域的预训练以前,咱们经过下图来看看 CNN 是如何对图片作特征提取的:一张图片放入到 CNN 中,由浅层到深层api

  • 浅层:浅层提取的特征对于 “人脸、汽车、大象、椅子” 这四个任务而言,很是的类似,都是 “横竖撇捺” 之类的
  • 深层:深层提取的特征对于 “人脸、汽车、大象、椅子” 这四个任务而言,都是接近于任务自己,例如 “人脸” 任务的 CNN 深层提取的特征更接近于人脸的轮廓

经过上述分析,也就是说,CNN 浅层提取的特征对于各个任务而言都是通用的。网络

图 1 - CNN 提取图片特征架构

聪明的读者应该想到了,什么是 “预训练”,但很懵懵懂懂,下面咱们来详细解释。app

图 2 - 预训练在图像领域的应用框架

假设咱们拥有两个尽可能类似的任务 A 和 B(能够都为图像处理任务),任务 A 是咱们目标任务,任务 B 是能够提早训练好的一个任务:

  1. 咱们训练任务 B 获得一个 CNN 模型 B
  2. 因为 CNN 浅层特征的通用性,咱们能够作以下两种处理:
    1. fine-tuning(微调):浅层参数使用模型 B 的参数,高层参数随机初始化,利用任务 A 训练模型 B,浅层参数随着变化
    2. frozen(冻结):浅层参数使用模型 B 的参数,高层参数随机初始化,利用任务 A 训练模型 B,浅层参数一直不变

上述两个步骤便是预训练的思想,那么预训练有什么好处呢?

  1. 若是咱们还有类似任务 C,能够利用模型 B 的参数直接启动任务的训练,进而能够加快任务 C 训练的收敛速度
  2. 若是咱们还有一个类似任务但数据量很小的任务 D,因为数据量小的任务很难训练出一个深度神经网络模型,然而利用预训练的思想,小数据量的任务也能够利用深度神经网络模型解决

3、词向量 Word Embedding

在讲解 CBOW 思想以前,咱们不得不讲解下词向量的发展史,这算是预训练语言模型的始祖,语言模型的预训练的思想最先来源于此,而且 CBOW 模型就是为了生成单词的词向量应运而生。

3.1 One-hot 编码

One-hot 编码相信你们都很熟悉了,一个很简单的小知识,让计算机认识现实世界中的单词。

因为计算机并不认识单词 “time、fruit……”,为此,人们构建一个词典 \(V\) ,以下图所示词典包含 8 个单词,对于词典中的每一个单词,都有之对应的 \(|V|\)(词典大小的)维度的向量表示,以下图的 “time” 对应的向量为 8 维的 “1000 0000”。

图 3 - 词的 One-hot 编码

One-hot 编码虽然解决了计算机不认识单词的这一缺陷,可是 One-hot 编码自己也是有问题的,对于上图 “fruit” 和 “banana” 的 One-hot 编码,能够经过余弦类似度计算二者的类似性,能够发现结果为 0,也就是二者绝不相关,然而实际上二者是相关的,由此,词向量应运而生。

3.2 神经网络语言模型 - 词向量的起源

图 4 - 神经网络语言模型架构

如今让咱们看看词向量究竟是个什么玩意儿,对于上述的 3 层神经网络语言模型(NNLM),它的学习任务是输入某个句中单词 \(w_t = banana\)​ 前的 \(t-1\)​ 个单词,要求网络正确预测单词 “banana”,即最大化:

\[P(w_t=bert|w_1,w_2,\cdots,w_{t-1};\theta) \]

其中 \(\theta\)​ 是 NNLM 的参数。

首先输入前 \(t-1\)​ 个单词的 One-hot 编码

  1. 单词的 One-hot 编码通过第一层,输入层,One-hot 编码左乘矩阵 Q 获得词向量 \(C(w_i)\)​​​

    1. 矩阵 Q 是一个随机初始化的参数矩阵
  2. 词向量 \(C(w_i)\) 通过第二层,隐层(至关于全链接层),隐层的输出为 \(\tanh(Wx+d)\),其中 \(x\) 为输入的词向量,\(W\) 为权重矩阵,\(d\) 为偏置,\(\tanh\) 为激活函数。

    1. 假设词典大小为 8,输出为一个 8 维的向量 [11, 22, 55, 44, 87, 84, 88]
  3. 第二层输出的向量通过第三层,输出层,通过 Softmax 函数归一化。

    1. 假设输入为一个输出为一个 8 维的向量 [11, 22, 55, 44, 87, 84, 88],则该层输出为 [0.000, 0.000, 0.000, 0.000, 0.265, 0.013, 0.721],对应图三,则该层输出的对应的词为 “banana”

    2. y = torch.FloatTensor([11, 22, 55, 44, 87, 84, 88])
      print(functional.softmax(y, dim=0))
      # 输出: [0.000, 0.000, 0.000, 0.000, 0.265, 0.013, 0.721]

在讲解 NNLM 的过程当中,能够看到该模型的一个副产品词向量 \(C(w_i)\)​,这就是大名鼎鼎的词向量。

这个词向量是如何解决 One-hot 编码对于本应该类似的单词而不类似的问题的呢?假设矩阵 Q 己经被成功训练,下面咱们来计算 “banana” 的词向量:

\[\begin{bmatrix} 0&0&0&0&0&0&0&1 \end{bmatrix} \begin{bmatrix} 17&24&1\\ 23&5&7\\ 4&6&13\\ 10&12&19\\ 11&18&25 \\ 23&36&24 \\ 5&34&23 \\ 7&6&18 \end{bmatrix} = \begin{bmatrix} 7&6&18 \end{bmatrix} \]

同理 “fruit” 的词向量为 [23,5,7],二者的余弦类似度为 “0.638”,能够发现词向量顺利的解决了词类似的问题。

y1 = torch.FloatTensor([7, 6, 18])
y2 = torch.FloatTensor([23, 5, 7, ])
print(torch.cosine_similarity(y1, y2, dim=0)) # 输出:0.638

上过构建词向量的过程被称做 Word Embedding,并且细心地读者应该发现训练矩阵 Q 并获得词向量的过程其实就是一个预训练的过程,对于将来的 NLP 的任务,直接使用训练获得的矩阵 Q 和词向量便可。

下图给出网上找的几个例子,能够看出有些效果仍是蛮不错的:

图 5 - Word Embedding 例子

4、Word2Vec 模型

NNLM 的学习任务是输入某个句中单词 \(w_t = banana\) 前的 \(t-1\)​ 个单词,要求网络正确预测单词 “banana”,矩阵 Q 和词向量都只是它的副产品。

为此,2013 年出现了一个最火的用语言模型专门作 Word Embedding 的工具 Word2Vec ,它的架构以下图所示:

图 6 - Word2Vec 模型

因为 Word2Vec 专门用来作 Word Embedding,它再也不是利用前 \(t-1\)​ 个单词,而是利用了上下文信息,这个也是很好理解的,对于一个单词的解释,利用上下文的信息做出的解释会更合理。

其实 Word2Vec 和 NNLM 很是相似,都是三层架构,除了利用了上下文信息,Word2Vec 还提供了 2 种训练方法:

  1. 第一种叫 CBOW,核心思想是从一个句子里面把一个词抠掉,用这个词的上文和下文去预测被抠掉的这个词;
  2. 第二种叫作 Skip-gram,和 CBOW 正好反过来,输入某个单词,要求网络预测它的上下文单词。

当你看到 CBOW 的时候,想必你也想到了为何要在这里讲讲 Word2Vec 的缘由,由于将来的 BERT 将会用到 CBOW 的思想:利用单词 \(w_t\) 上下文的信息,预测单词 \(w_t\)

5、Attention 机制

Attention 机制来源于人类的视觉注意力机制:人类视觉经过快速扫描全局图像,得到须要重点关注的目标区域,也就是通常所说的注意力焦点,然后对这一区域投入更多注意力资源,以获取更多所须要关注目标的细节信息,而抑制其余无用信息。

对于下图,若是只关心颜色,咱们可能第一眼就会把重心放在显眼的红色上,而后再观察其余地方。

图 7 - 婴儿图像

经过对人类视觉注意力机制的描述,Attention 机制简单点讲就是:经过一个 Query(查询变量)从一堆信息(Key-Value 表示的信息,能够把 Key 看做信息的地址,Value 表示信息的内容)中找到对于 Query 而言重要的信息,以此获取更多对于 Query 而言更重要的细节信息,进而抑制其余无用信息。

Attention 的具体作法以下图所示:

图 8 - Attention 计算图

  1. 计算 Q 和 K 的类似度,用 f 来表示:\(f(Q,K_i)\quad i=1,2,\cdots,m\)​,Self-Attention 模型中 \(f(Q,K_i) = Q^TK_i\)

  2. 第二步:将获得的类似度进行 softmax 操做,进行归一化:\(\alpha_i = softmax(\frac{f(Q,K_i)}{\sqrt d_k})\)

    1. 这里简单讲解除以 \(\sqrt d_k\) 的做用:假设 \(Q\) , \(K\) 里的元素的均值为0,方差为 1,那么 \(A^T=Q^TK\) 中元素的均值为 0,方差为 d。当 d 变得很大时, \(A\) 中的元素的方差也会变得很大,若是 \(A\) 中的元素方差很大(分布的方差大,分布集中在绝对值大的区域),在数量级较大时, softmax 将几乎所有的几率分布都分配给了最大值对应的标签,因为某一维度的数量级较大,进而会致使 softmax 将来求梯度时会消失。总结一下就是 \(\operatorname{softmax}\left(A\right)\) 的分布会和d有关。所以 \(A\) 中每个元素乘上 \(\frac{1}{\sqrt{d_k}}\) 后,方差又变为 1,而且 \(A\) 的数量级也将会变小。

    2. y1 = torch.FloatTensor([11, 22, 55, 44, 87, 84, 88])
      y2 = torch.FloatTensor([11, 22, 55, 44, 80, 80, 88])
      print(functional.softmax(y1, dim=0))
      # 输出: [0.000, 0.000, 0.000, 0.000, 0.265, 0.013, 0.721]
      print(functional.softmax(y2, dim=0))
      # 输出:[0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.999]
  3. 针对计算出来的权重 \(\alpha_i\),对 \(V\) 中的全部 values 进行加权求和计算,获得 Attention 向量:\(Attention = \sum_{i=1}^m \alpha_i V_i\)

6、Self-Attention 模型

6.1 Self-Attention 的向量运算

Self-Attention 模型是 Attention 机制的具体应用,下面咱们给出 Self-Attention 的架构图:

图 9 - Self-Attention 模型架构图

经过上图能够看到 Self Attention 有三个输入 Q、K、V:对于 Self Attention,Q、K、V 来自输入句子 X 的 词向量 x 的线性转化,即对于词向量 x,给定三个可学习的矩阵参数 \(W_Q,W_k,W_v\),x 分别右乘上述矩阵获得 Q、K、V。这也是Self-Attention 名字的来源:Q、K、V 三个矩阵由同一个词向量线性转化而得。

下面咱们来详细了解下 Self-Attention 的具体计算流程:

  1. 第一步,Q、K、V 的获取

    图 10 - Q、K、V 矩阵的获取

    上图操做:两个单词 Thinking 和 Machines。经过线性变换,即 \(x_i\)\(x_2\) 两个向量分别与\(W_q,W_k,W_v\) 三个矩阵点乘获得 ${q_1,q_2},{k_1,k_2},{v_1,v_2} $ 共 6 个向量。矩阵 Q 则是向量 \(q_1,q_2\) 的拼接,K、V 同理。

  2. 第二步,MatMul

    1. 图 11 - \(q_1\)\(k一、k_2\) 的计算

      上图操做:向量 \({q_1,k_1}\) 作点乘获得得分 112, \({q_1,k_2}\) 作点乘获得得分96。注意:这里是经过 \(q_1\) 这个信息找到 \(x_1,x_2\) 中的重要信息。

  3. 第三步和第四步,Scale + Softmax

    图 12 - \(q_1\)\(k一、k_2\) 的计算作 Softmax

    上图操做:对该得分进行规范,除以 \(\sqrt {d_k} = 8\)

  4. 第五步,MatMul

    图 13 - \(z_1\) 的计算

用得分比例 [0.88,0.12] 乘以 \([v_1,v_2]\) 值获得一个加权后的值,将这些值加起来获得 \(z_1\)

上述所说就是 Self Attention 模型所作的事,仔细感觉一下,用 \(q_1\)​、\(K=[k_1,k_2]\)​ 去计算一个 Thinking 相对于 Thinking 和 Machine 的权重,再用权重乘以 Thinking 和 Machine 的 \(V=[v_1,v_2]\)​ 获得加权后的 Thinking 和 Machine 的 \(V=[v_1,v_2]\)​,最后求和获得针对各单词的输出 \(z_1\)​​​。

同理能够计算出 Machine 相对于 Thinking 和 Machine 的加权输出 \(z_2\)

6.2 Self-Attention 的优势

上述所计算的结果 \(z_1\)​​ 就能够看做是查询变量 Thinking 的词向量,而且是 Thinking 从 Thinking Machine 这句话中找到了对于 Thinking 而言更为重要的信息,而且抑制了不重要的信息。这样讲,可能没法理解 Self-Attention 机制的好处,咱们能够经过下图来了解 Self-Attention 机制的优势到底在哪里:

图 14 - attention 获取句法特征

图 15 - attention 获取语义特征

从图 14 能够看出,Self-Attention 捕获了同一个句子中单词之间的一些句法特征(有必定距离的短语结构);从图 15 能够看出,Self-Attention 捕获了同一个句子中单词之间的语义特征(“its” 的指代对象 “Law”)。

而且从上面的计算步骤和图片能够看出,不管句子序列多长,均可以很好的提取句子特征,而且既能够提取句法特征还能够提取语义特征,这很好的解决了 RNN 序列长距离依赖的问题,并且对于一个句子而言,每一个单词的计算是能够并行处理的

图 16 - RNN 结构图

6.3 Self-Attention 的矩阵运算

上述例子是 Self-Attention 单个向量运算的例子。下图展现的是 Self-Attention 的矩阵运算的例子,输入是一个 [2x4] 的矩阵(句子中每一个单词的词向量的拼接),每一个运算是 [4x3] 的矩阵,求得 Q、K、V。

Q 对 K 转制作点乘,除以 \(\sqrt d_k\),作一个 softmax 获得合为 1 的比例,对 V 作点乘获得输出 Z。那么这个 Z 就是一个考虑过 Thinking 周围单词 Machine 的输出。

注意看这个公式,\(QK^T\) 其实就会组成一个 word2word 的 attention map!(加了 softmax 以后就是一个合为 1 的权重了)。好比说你的输入是一句话 "i have a dream" 总共 4 个单词,这里就会造成一张 4x4 的注意力机制的图:

这样一来,每个单词对应每个单词都会有一个权重,这也是 Self Attention 名字的来源,即 Attention 的计算来源于 Source(源句) 和 Source 自己,通俗点讲就是 Q、K、V 都来源于输入 X 自己。

6.4 Masked Self Attention 模型

趁热打铁,咱们讲讲 Transformer 将来会用到的 Masked Self Attention 模型,这里的 Masked 就是要在作语言模型(或者像翻译)的时候,不给模型看到将来的信息,它的结构以下图所示:

上图中和 Self Attention 重复的部分此处就不讲了,主要讲讲 Mask 这一块。

假设在此以前咱们已经经过 scale 以前的步骤获得了一个 attention map,而 mask 就是沿着对角线把灰色的区域用0覆盖掉,不给模型看到将来的信息,以下图所示:

详细来讲:

  1. "i" 做为第一个单词,只能有和 "i" 本身的 attention;
  2. "have" 做为第二个单词,有和 "i、have" 前面两个单词的 attention;
  3. "a" 做为第三个单词,有和 "i、have、a" 前面三个单词的 attention;
  4. "dream" 做为最后一个单词,才有对整个句子 4 个单词的 attention。

而且在作完 softmax 以后,横轴结果合为 1。以下图所示:

具体为何 在 Transformer 中要用到 Masked Self Attention,将来在讲解 Transformer 的时候会详细解释。

6.5 Multi-head Self Attention 模型

因为 Transformer 使用的都是 Self Attention 的进阶版 Multi-head Self Attention,咱们简单讲讲 Multi-head Self Attention 的架构,而且在该小节结尾处讲讲它的优势。

Multi-Head Attention 就是把 Self Attention的过程作 H 次,而后把输出 Z 合起来。论文中,它的结构图以下:

咱们仍是以上面的形式来解释,首先,咱们使用 8 组不一样的 \(W_Q^i,W_k^i,W_V^i\quad i=1,2,\cdots,8\) ,重复 8 次和 Self Attention 类似的操做,获得 8 个 \(Z_i\) 矩阵:

为了使得输出与输入结构相同,拼接矩阵 \(Z_i\) 后乘以一个线性 \(W_0\) 获得最终的Z:

看完了 Multi-head Self Attention 的架构,发现它与 Self Attention 的区别,在于用了 \(n\)\(W_Q^i,W_k^i,W_V^i\quad i=1,2,\cdots,n\) 获得 \(n\)\(Q_i,K_i,V_i \quad i=1,2,\cdots,n\)

能够经过下图看看 multi-head attention 的整个流程:

上述操做有什么好处呢?使用多套参数,多套参数至关于把原始信息 Source 放入了多个子空间中,也就是捕捉了多个信息,对于使用 multi-head(多头) attention 的简单回答就是,多头保证了 attention 能够注意到不一样子空间的信息,捕捉到更加丰富的特征信息。其实本质上是论文原做者发现这样效果确实好。

7、Position Embedding

在 Attention 和 RNN 的对比中,咱们说到 Attention 解决了长距离依赖问题,而且能够支持并行化,可是它就真的百利而无一害了吗?

其实否则,咱们往前回顾,Self Attention 的 Q、K、V 三个矩阵是由同一个输入 \(X_1=(x_1,x_2,\cdots,x_n)\) 线性转换而来,也就是说对于这样的一个被打乱序列顺序的 \(X_2=(x_2,x_1,\cdots,x_n)\) 而言,因为 Attention 值的计算最终会被加权求和,也就是说二者最终计算的 Attention 值都是同样的,进而也就代表了 Attention 丢掉了 \(X_1\) 的序列顺序信息。

如上图所示,为了解决 Attention 丢失的序列顺序信息,Transformer 的提出者提出了 Position Embedding,也就是对于输入 \(X\) 进行 Attention 计算以前,在 \(X\) 的词向量中加上位置信息,也就是说 \(X\) 的词向量为 \(X_{final\_embedding} = Embedding + Positional\, Embedding\)

可是如何获得 \(X\) 的位置向量呢?

其中位置编码公式以下图所示:

其中 pos 表示位置、i 表示维度、\(d_{model}\)表示位置向量的向量维度 、\(2i、2i+1\) 表示的是奇偶数(奇偶维度),上图所示就是偶数位置使用 \(\sin\) 函数,奇数位置使用 \(\cos\) 函数。

有了位置编码,咱们再来看看位置编码是如何嵌入单词编码的(其中 512 表示编码维度),经过把单词的词向量和位置向量进行叠加,这种方式就称做位置嵌入,以下图所示:

Position Embedding 自己是一个绝对位置的信息,但在语言模型中,相对位置也很重要。那么为何位置嵌入机制有用呢?

咱们不要去关心三角函数公式,能够看看下图公式(3)中的第一行,咱们作以下的解释,对于 “我爱吃苹果” 这一句话,有 5 个单词,假设序号分别为 一、二、三、四、5。

假设 \(pos=1=我、k=2=爱、pos+k=3=吃\),也就是说 \(pos+k=3\) 位置的位置向量的某一维能够经过 \(pos=1\) 位置的位置向量的某一维线性组合加以线性表示,经过该线性表示能够得出 “吃” 的位置编码信息蕴含了相对于前两个字 “我” 的位置编码信息。

总而言之就是,某个单词的位置信息是其余单词位置信息的线性组合,这种线性组合就意味着位置向量中蕴含了相对位置信息。

8、Transformer

8.1 Transformer 的结构

万事俱备,只欠东风,下面咱们来说讲咱们的重点之一,Transformer,你能够先记住这一句话:Transformer 简单点看其实就是 self-attention 模型的叠加,首先咱们来看看 Transformer 的总体框架。

Transformer 的总体框架以下图所示:

上图所示的总体框架乍一眼一看很是复杂,因为 Transformer 起初是做为翻译模型,所以咱们以翻译举例,简化一下上述的总体框架:

从上图能够看出 Transformer 至关于一个黑箱,左边输入 “Je suis etudiant”,右边会获得一个翻译结果 “I am a student”。

再往细里讲,Transformer 也是一个 Seq2Seq 模型(Encoder-Decoder 框架的模型),左边一个 Encoders 把输入读进去,右边一个 Decoders 获得输出,以下所示:

在这里,咱们穿插描述下 Encoder-Decoder 框架的模型是如何进行文本翻译的:

  1. 将序列 \((x_1,x_2,\cdots,x_n)\) 做为 Encoders 的输入,获得输出序列 \((z_1,z_2,\cdots,z_n)\)
  2. 把 Encoders 的输出序列 \((z_1,z_2,\cdots,z_n)\) 做为 Decoders 的输入,生成一个输出序列 \((y_1,y_2,\cdots,y_m)\)。注:Decoders 每一个时刻输出一个结果

第一眼看到上述的 Encodes-Decoders 框架图,随之产生问题就是 Transformer 中 左边 Encoders 的输出是怎么和右边 Decoders 结合的。由于decoders 里面是有N层的,再画张图直观的看就是这样:

也就是说,Encoders 的输出,会和每一层的 Decoder 进行结合

如今咱们取其中一层进行详细的展现:

经过上述分析,发现咱们想要详细了解 Transformer,只要了解 Transformer 中的 Encoder 和 Decoder 单元便可,接下来咱们将详细阐述这两个单元。

8.2 Encoder

有了上述那么多知识的铺垫,咱们知道 Eecoders 是 N=6 层,经过上图咱们能够看到每层 Encoder 包括两个 sub-layers:

  • 第一个 sub-layer 是 multi-head self-attention,用来计算输入的 self-attention;
  • 第二个 sub-layer 是简单的前馈神经网络层 Feed Forward;

注意:在每一个 sub-layer 咱们都模拟了残差网络(在下面的数据流示意图中会细讲),每一个sub-layer的输出都是 \(LayerNorm(x+Sub\_layer(x))\),其中 \(sub\_layer\) 表示的是该层的上一层的输出

如今咱们给出 Encoder 的数据流示意图,一步一步去剖析

  1. 深绿色的 \(x_1\) 表示 Embedding 层的输出,加上表明 Positional Embedding 的向量以后,获得最后输入 Encoder 中的特征向量,也就是浅绿色向量 \(x_1\)
  2. 浅绿色向量 \(x_1\) 表示单词 “Thinking” 的特征向量,其中 \(x_1\) 通过 Self-Attention 层,变成浅粉色向量 \(z_1\)
  3. \(x_1\) 做为残差结构的直连向量,直接和 \(z_1\) 相加,以后进行 Layer Norm 操做,获得粉色向量 \(z_1\)
    1. 残差结构的做用:避免出现梯度消失的状况
    2. Layer Norm 的做用:为了保证数据特征分布的稳定性,而且能够加速模型的收敛
  4. \(z_1\) 通过前馈神经网络(Feed Forward)层,通过残差结构与自身相加,以后通过 LN 层,获得一个输出向量 \(r_1\)
    1. 该前馈神经网络包括两个线性变换和一个ReLU激活函数:\(FFN(x) = max(0,xW_1+b_1)W_2+b2\)
  5. 因为 Transformer 的 Encoders 具备 6 个 Encoder,\(r_1\) 也将会做为下一层 Encoder 的输入,代替 \(x_1\) 的角色,如此循环,直至最后一层 Encoder。

须要注意的是,上述的 \(x、z、r\) 都具备相同的维数,论文中为 512 维。

8.3 Decoder

Decoders 也是 N=6 层,经过上图咱们能够看到每层 Decoder 包括 3 个 sub-layers:

  • 第一个 sub-layer 是 Masked multi-head self-attention,也是计算输入的 self-attention;
    • 在这里,先不解释为何要作 Masked,后面在 “Transformer 动态流程展现” 这一小节会解释
  • 第二个 sub-layer 是 Encoder-Decoder Attention 计算,对 Encoder 的输入和 Decoder 的Masked multi-head self-attention 的输出进行 attention 计算;
    • 在这里,一样不解释为何要对 Encoder 和 Decoder 的输出一同作 attention 计算,后面在 “Transformer 动态流程展现” 这一小节会解释
  • 第三个 sub-layer 是前馈神经网络层,与 Encoder 相同。

8.4 Transformer 输出结果

以上,就讲完了 Transformer 编码和解码两大模块,那么咱们回归最初的问题,将 “机器学习” 翻译成 “machine learing”,解码器的输出是一个浮点型的向量,怎么转化成 “machine learing” 这两个词呢?让咱们来看看 Encoders 和 Decoders 交互的过程寻找答案:

从上图能够看出,Transformer 最后的工做是让解码器的输出经过线性层 Linear 后接上一个 softmax

  • 其中线性层是一个简单的全链接神经网络,它将解码器产生的向量 A 投影到一个更高维度的向量 B 上,假设咱们模型的词汇表是10000个词,那么向量 B 就有10000个维度,每一个维度对应一个唯一的词的得分。
  • 以后的softmax层将这些分数转换为几率。选择几率最大的维度,并对应地生成与之关联的单词做为此时间步的输出就是最终的输出啦!

假设词汇表维度是 6,那么输出最大几率词汇的过程以下:

9、Transformer 动态流程展现

首先咱们来看看拿 Transformer 做翻译时,如何生成翻译结果的:

继续进行:

假设上图是训练模型的某一个阶段,咱们来结合 Transformer 的完整框架描述下这个动态的流程图:

  1. 输入 “je suis etudiant” 到 Encoders,而后获得一个 \(K_e\)\(V_e\) 矩阵;
  2. 输入 “I am a student” 到 Decoders ,首先经过 Masked Multi-head Attention 层获得 “I am a student” 的 attention 值 \(Q_d\),而后用 attention 值 \(Q_d\) 和 Encoders 的输出 \(K_e\)\(V_e\) 矩阵进行 attention 计算,获得第 1 个输出 “I”;
  3. 输入 “I am a student” 到 Decoders ,首先经过 Masked Multi-head Attention 层获得 “I am a student” 的 attention 值 \(Q_d\),而后用 attention 值 \(Q_d\) 和 Encoders 的输出 \(K_e\)\(V_e\) 矩阵进行 attention 计算,获得第 2 个输出 “am”;
  4. ……

如今咱们来解释咱们以前遗留的两个问题。

9.1 为何 Decoder 须要作 Mask

  • 训练阶段:咱们知道 “je suis etudiant” 的翻译结果为 “I am a student”,咱们把 “I am a student” 的 Embedding 输入到 Decoders 里面,翻译第一个词 “I” 时

    • 若是对 “I am a student” attention 计算不作 mask,“am,a,student” 对 “I” 的翻译将会有必定的贡献
    • 若是对 “I am a student” attention 计算作 mask,“am,a,student” 对 “I” 的翻译将没有贡献
  • 测试阶段:咱们不知道 “我爱中国” 的翻译结果为 “I love China”,咱们只能随机初始化一个 Embedding 输入到 Decoders 里面,翻译第一个词 “I” 时:

    • 不管是否作 mask,“love,China” 对 “I” 的翻译都不会产生贡献
    • 可是翻译了第一个词 “I” 后,随机初始化的 Embedding 有了 “I” 的 Embedding,也就是说在翻译第二词 “love” 的时候,“I” 的 Embedding 将有必定的贡献,可是 “China” 对 “love” 的翻译毫无贡献,随之翻译的进行,已经翻译的结果将会对下一个要翻译的词都会有必定的贡献,这就和作了 mask 的训练阶段作到了一种匹配

总结下就是:Decoder 作 Mask,是为了让训练阶段和测试阶段行为一致,不会出现间隙,避免过拟合

9.2 为何 Encoder 给予 Decoders 的是 K、V 矩阵

咱们在讲解 Attention 机制中曾提到,Query 的目的是借助它从一堆信息中找到重要的信息。

如今 Encoder 提供了 \(K_e、V_e\) 矩阵,Decoder 提供了 \(Q_d\) 矩阵,经过 “我爱中国” 翻译为 “I love China” 这句话详细解释下。

当咱们翻译 “I” 的时候,因为 Decoder 提供了 \(Q_d\) 矩阵,经过与 \(K_e、V_e\) 矩阵的计算,它能够在 “我爱中国” 这四个字中找到对 “I” 翻译最有用的单词是哪几个,并以此为依据翻译出 “I” 这个单词,这就很好的体现了注意力机制想要达到的目的,把焦点放在对本身而言更为重要的信息上。

  • 其实上述说的就是 Attention 里的 soft attention机制,解决了曾经的 Encoder-Decoder 框架的一个问题,在这里很少作叙述,有兴趣的能够参考网上的一些资料。
    • 早期的 Encoder-Decoder 框架中的 Encoder 经过 LSTM 提取出源句(Source) “我爱中国” 的特征信息 C,而后 Decoder 作翻译的时候,目标句(Target)“I love China” 中的任何一个单词的翻译都来源于相同特征信息 C,这种作法是极其不合理的,例如翻译 “I” 时应该着眼于 “我”,翻译 “China” 应该着眼于 “中国”,而早期的这种作法并无体现出,然而 Transformer 却经过 Attention 的作法解决了这个问题。

10、BERT 模型

10.1 BERT:公认的里程碑

BERT 模型能够做为公认的里程碑式的模型,可是它最大的优势不是创新,而是集大成者,而且这个集大成者有了各项突破,下面让咱们看看 BERT 是怎么集大成者的。

  • BERT 的意义在于:从大量无标记数据集中训练获得的深度模型,能够显著提升各项天然语言处理任务的准确率。
  • 近年来优秀预训练语言模型的集大成者:参考了 ELMO 模型的双向编码思想、借鉴了 GPT 用 Transformer 做为特征提取器的思路、采用了 word2vec 所使用的 CBOW 方法
  • BERT 和 GPT 之间的区别:
    • GPT:GPT 使用 Transformer Decoder 做为特征提取器、具备良好的文本生成能力,然而当前词的语义只能由其前序词决定,而且在语义理解上不足
    • BERT:使用了 Transformer Encoder 做为特征提取器,并使用了与其配套的掩码训练方法。虽然使用双向编码让 BERT 再也不具备文本生成能力,可是 BERT 的语义信息提取能力更强
  • 单向编码和双向编码的差别,以该句话举例 “今每天气很{},咱们不得不取消户外运动”,分别从单向编码和双向编码的角度去考虑 {} 中应该填什么词:
    • 单向编码:单向编码只会考虑 “今每天气很”,以人类的经验,大几率会从 “好”、“不错”、“差”、“糟糕” 这几个词中选择,这些词能够被划为大相径庭的两类
    • 双向编码:双向编码会同时考虑上下文的信息,即除了会考虑 “今每天气很” 这五个字,还会考虑 “咱们不得不取消户外运动” 来帮助模型判断,则大几率会从 “差”、“糟糕” 这一类词中选择

10.2 BERT 的结构:强大的特征提取能力

  • 以下图所示,咱们来看看 ELMo、GPT 和 BERT 三者的区别

    • ELMo 使用自左向右编码和自右向左编码的两个 LSTM 网络,分别以 \(P(w_i|w_1,\cdots,w_{i-1})\)\(P(w_i|w_{i+1},\cdots,w_n)\) 为目标函数独立训练,将训练获得的特征向量以拼接的形式实现双向编码,本质上仍是单向编码,只不过是两个方向上的单向编码的拼接而成的双向编码
    • GPT 使用 Transformer Decoder 做为 Transformer Block,以 \(P(w_i|w_1,\cdots,w_{i-1})\) 为目标函数进行训练,用 Transformer Block 取代 LSTM 做为特征提取器,实现了单向编码,是一个标准的预训练语言模型,即便用 Fine-Tuning 模式解决下游任务。
    • BERT 也是一个标准的预训练语言模型,它以 \(P(w_i|w_1,\cdots,w_{i-1},w_{i+1},\cdots,w_n)\) 为目标函数进行训练,BERT 使用的编码器属于双向编码器
      • BERT 和 ELMo 的区别在于使用 Transformer Block 做为特征提取器,增强了语义特征提取的能力;
      • BERT 和 GPT 的区别在于使用 Transformer Encoder 做为 Transformer Block,而且将 GPT 的单向编码改为双向编码,也就是说 BERT 舍弃了文本生成能力,换来了更强的语义理解能力。

BERT 的模型结构以下图所示:

从上图能够发现,BERT 的模型结构其实就是 Transformer Encoder 模块的堆叠。在模型参数选择上,论文给出了两套大小不一致的模型。

\(BERT_{BASE}\) :L = 12,H = 768,A = 12,总参数量为 1.1 亿

\(BERT_{LARGE}\):L = 24,H = 1024,A = 16,总参数量为 3.4 亿

其中 L 表明 Transformer Block 的层数;H 表明特征向量的维数(此处默认 Feed Forward 层中的中间隐层的维数为 4H);A 表示 Self-Attention 的头数,使用这三个参数基本能够定义 BERT的量级。

BERT 参数量级的计算公式:

\[\begin{align*} & 词向量参数+ 12 * (Multi-Heads参数 + 全链接层参数 + layernorm参数)\\ & = (30522+512 + 2)* 768 + 768 * 2 \\ & + 12 * (768 * 768 / 12 * 3 * 12 + 768 * 768 + 768 * 3072 * 2 + 768 * 2 * 2) \\ & = 108808704.0 \\ & \approx 110M \end{align*} \]

训练过程也是很花费计算资源和时间的,总之表示膜拜,普通人即使有 idea 没有算力也只能跪着。

10.3 BERT 之无监督训练

BERT 采用二段式训练方法:

  1. 第一阶段:使用易获取的大规模无标签余料,来训练基础语言模型;
  2. 第二阶段:根据指定任务的少许带标签训练数据进行微调训练。

不一样于 GPT 等标准语言模型使用 \(P(w_i|w_1,\cdots,w_{i-1})\) 为目标函数进行训练,能看到全局信息的 BERT 使用 \(P(w_i|w_1,\cdots,w_{i-1},w_{i+1},\cdots,w_n)\) 为目标函数进行训练。

而且 BERT 用语言掩码模型(MLM)方法训练词的语义理解能力;用下句预测(NSP)方法训练句子之间的理解能力,从而更好地支持下游任务。

10.4 BERT 之语言掩码模型(MLM)

BERT 做者认为,使用自左向右编码和自右向左编码的单向编码器拼接而成的双向编码器,在性能、参数规模和效率等方面,都不如直接使用深度双向编码器强大,这也是为何 BERT 使用 Transformer Encoder 做为特征提取器,而不使用自左向右编码和自右向左编码的两个 Transformer Decoder做为特征提取器的缘由。

因为没法使用标准语言模型的训练模式,BERT 借鉴完形填空任务和 CBOW 的思想,使用语言掩码模型(MLM )方法训练模型。

MLM 方法也就是随机去掉句子中的部分 token(单词),而后模型来预测被去掉的 token 是什么。这样实际上已经不是传统的神经网络语言模型(相似于生成模型)了,而是单纯做为分类问题,根据这个时刻的 hidden state 来预测这个时刻的 token 应该是什么,而不是预测下一个时刻的词的几率分布了。

随机去掉的 token 被称做掩码词,在训练中,掩码词将以 15% 的几率被替换成 [MASK],也就是说随机 mask 语料中 15% 的 token,这个操做则称为掩码操做。注意:在CBOW 模型中,每一个词都会被预测一遍。

可是这样设计 MLM 的训练方法会引入弊端:在模型微调训练阶段或模型推理(测试)阶段,输入的文本中将没有 [MASK],进而致使产生由训练和预测数据误差致使的性能损失。

考虑到上述的弊端,BERT 并无总用 [MASK] 替换掩码词,而是按照必定比例选取替换词。在选择 15% 的词做为掩码词后这些掩码词有三类替换选项:

  • 80% 练样本中:将选中的词用 [MASK] 来代替,例如:
“地球是[MASK]八大行星之一”
  • 10% 的训练样本中:选中的词不发生变化,该作法是为了缓解训练文本和预测文本的误差带来的性能损失,例如:
“地球是太阳系八大行星之一”
  • 10% 的训练样本中:将选中的词用任意的词来进行代替,该作法是为了让 BERT 学会根据上下文信息自动纠错,例如:
“地球是苹果八大行星之一”

做者在论文中提到这样作的好处是,编码器不知道哪些词须要预测的,哪些词是错误的,所以被迫须要学习每个 token 的表示向量,另外做者也表示双向编码器比单项编码器训练要慢,进而致使BERT 的训练效率低了不少,可是实验也证实 MLM 训练方法可让 BERT 得到超出同期全部预训练语言模型的语义理解能力,牺牲训练效率是值得的。

10.5 BERT 之下句预测(NSP)

在不少天然语言处理的下游任务中,如问答和天然语言推断,都基于两个句子作逻辑推理,而语言模型并不具有直接捕获句子之间的语义联系的能力,或者能够说成单词预测粒度的训练到不了句子关系这个层级,为了学会捕捉句子之间的语义联系,BERT 采用了下句预测(NSP )做为无监督预训练的一部分。

NSP 的具体作法是,BERT 输入的语句将由两个句子构成,其中,50% 的几率将语义连贯的两个连续句子做为训练文本(连续句对通常选自篇章级别的语料,以此确保先后语句的语义强相关),另外 50% 的几率将彻底随机抽取两个句子做为训练文本。

连续句对:[CLS]今每天气很糟糕[SEP]下午的体育课取消了[SEP]

随机句对:[CLS]今每天气很糟糕[SEP]鱼快被烤焦啦[SEP]

其中 [SEP] 标签表示分隔符。 [CLS] 表示标签用于类别预测,结果为 1,表示输入为连续句对;结果为 0,表示输入为随机句对。

经过训练 [CLS] 编码后的输出标签,BERT 能够学会捕捉两个输入句对的文本语义,在连续句对的预测任务中,BERT 的正确率能够达到 97%-98%。

10.6 BERT 之输入表示

BERT 在预训练阶段使用了前文所述的两种训练方法,在真实训练中通常是两种方法混合使用

因为 BERT 经过 Transformer 模型堆叠而成,因此 BERT 的输入须要两套 Embedding 操做:

  1. 一套为 One-hot 词表映射编码(对应下图的 Token Embeddings);
  2. 另外一套为位置编码(对应下图的 Position Embeddings),不一样于 Transformer 的位置编码用三角函数表示,BERT 的位置编码将在预训练过程当中训练获得(训练思想相似于Word Embedding 的 Q 矩阵)
  3. 因为在 MLM 的训练过程当中,存在单句输入和双句输入的状况,所以 BERT 还须要一套区分输入语句的分割编码(对应下图的 Segment Embeddings),BERT 的分割编码也将在预训练过程当中训练获得

对于分割编码,Segment Embeddings 层只有两种向量表示。前一个向量是把 0 赋给第一个句子中的各个 token,后一个向量是把 1 赋给第二个句子中的各个 token ;若是输入仅仅只有一个句子,那么它的 segment embedding 就是全 0,下面咱们简单举个例子描述下:

[CLS]I like dogs[SEP]I like cats[SEP] 对应编码 0 0 0 0 0 1 1 1 1

[SEP]I Iike dogs and cats[SEP] 对应编码 0 0 0 0 0 0 0

11、BERT 下游任务改造

BERT 根据天然语言处理下游任务的输入和输出的形式,将微调训练支持的任务分为四类,分别是句对分类、单句分类、文本问答和单句标注,接下来咱们将简要的介绍下 BERT 如何经过微调训练适应这四类任务的要求。

11.1 句对分类

给定两个句子,判断它们的关系,称为句对分类,例如判断句对是否类似、判断后者是否为前者的答案。

针对句对分类任务,BERT 在预训练过程当中就使用了 NSP 训练方法得到了直接捕获句对语义关系的能力。

以下图所示,句对用 [SEP] 分隔符拼接成文本序列,在句首加入标签 [CLS],将句首标签所对应的输出值做为分类标签,计算预测分类标签与真实分类标签的交叉熵,将其做为优化目标,在任务数据上进行微调训练。

针对二分类任务,BERT 不须要对输入数据和输出数据的结构作任何改动,直接使用与 NSP 训练方法同样的输入和输出结构就行。

针对多分类任务,须要在句首标签 [CLS] 的输出特征向量后接一个全链接层和 Softmax 层,保证输出维数与类别数目一致,最后经过 arg max 操做(取最大值时对应的索引序号)获得相对应的类别结果。

下面给出句对分类似性任务的实例:

任务:判断句子 “我很喜欢你” 和句子 “我很中意你” 是否类似

输入改写:“[CLS]我很喜欢你[SEP]我很中意你”

取 “[CLS]” 标签对应输出:[0.02, 0.98]

经过 arg max 操做获得类似类别为 1(类别索引从 0 开始),即两个句子类似

11.2 单句分类

给定一个句子,判断该句子的类别,统称为单句分类,例如判断情感类别、判断是否为语义连贯的句子。

针对单句二分类任务,也无须对 BERT 的输入数据和输出数据的结构作任何改动。

以下图所示,单句分类在句首加入标签 [CLS],将句首标签所对应的输出值做为分类标签,计算预测分类标签与真实分类标签的交叉熵,将其做为优化目标,在任务数据上进行微调训练。

一样,针对多分类任务,须要在句首标签 [CLS] 的输出特征向量后接一个全链接层和 Softmax 层,保证输出维数与类别数目一致,最后经过 argmax 操做获得相对应的类别结果。

下面给出语义连贯性判断任务的实例:

任务:判断句子“海大球星饭茶吃” 是否为一句话

输入改写:“[CLS]海大球星饭茶吃”

取 “[CLS]” 标签对应输出:[0.99, 0.01]

经过 arg max 操做获得类似类别为 0,即这个句子不是一个语义连贯的句子

11.3 文本问答

给定一个问句和一个蕴含答案的句子,找出答案在后这种的位置,称为文本问答,例如给定一个问题(句子 A),在给定的段落(句子 B)中标注答案的其实位置和终止位置。

文本问答任何和前面讲的其余任务有较大的差异,不管是在优化目标上,仍是在输入数据和输出数据的形式上,都须要作一些特殊的处理。

为了标注答案的起始位置和终止位置,BERT 引入两个辅助向量 s(start,判断答案的起始位置) 和 e(end,判断答案的终止位置)。

以下图所示,BERT 判断句子 B 中答案位置的作法是,将句子 B 中的每个次获得的最终特征向量 \(T_i'\) 通过全链接层(利用全链接层将词的抽象语义特征转化为任务指向的特征)后,分别与向量 s 和 e 求内积,对全部内积分别进行 softmax 操做,便可获得词 Tok m(\(m\in [1,M]\))做为答案其实位置和终止位置的几率。最后,去几率最大的片断做为最终的答案

文本回答任务的微调训练使用了两个技巧:

  1. 用全链接层把 BERT 提取后的深层特征向量转化为用于判断答案位置的特征向量
  2. 引入辅助向量 s 和 e 做为答案其实位置和终止位置的基准向量,明确优化目标的方向和度量方法

下面给出文本问答任务的实例:

任务:给定问句 “今天的最高温度是多少”,在文本 “天气预报显示今天最高温度 37 摄氏度” 中标注答案的起始位置和终止位置

输入改写:“[CLS]今天的最高温度是多少[SEP]天气预报显示今天最高温度 37 摄氏度”

BERT Softmax 结果:

篇章文本 天气 预报 显示 今天 最高温 37 摄氏度
起始位置几率 0.01 0.01 0.01 0.04 0.10 0.80 0.03
终止位置几率 0.01 0.01 0.01 0.03 0.04 0.10 0.80

对 Softmax 的结果取 arg max,获得答案的起始位置为 6,终止位置为 7,即答案为 “37 摄氏度”

11.4 单句标注

给定一个句子,标注每一个次的标签,称为单句标注。例如给定一个句子,标注句子中的人名、地名和机构名。

单句标注任务和 BERT 预训练任务具备较大差别,但与文本问答任务较为类似。

以下图所示,在进行单句标注任务时,须要在每一个词的最终语义特征向量以后添加全链接层,将语义特征转化为序列标注任务所需的特征,单句标注任务须要对每一个词都作标注,所以不须要引入辅助向量,直接对通过全链接层后的结果作 Softmax 操做,便可获得各种标签的几率分布。

因为 BERT 须要对输入文本进行分词操做,独立词将会被分红若干子词,所以 BERT 预测的结果将会是 5 类(细分为 13 小类):

  • O(非人名地名机构名,O 表示 Other)
  • B-PER/LOC/ORG(人名/地名/机构名初始单词,B 表示 Begin)
  • I-PER/LOC/ORG(人名/地名/机构名中间单词,I 表示 Intermediate)
  • E-PER/LOC/ORG(人名/地名/机构名终止单词,E 表示 End)
  • S-PER/LOC/ORG(人名/地名/机构名独立单词,S 表示 Single)

将 5 大类的首字母结合,可得 IOBES,这是序列标注最经常使用的标注方法。

下面给出命名实体识别(NER)任务的示例:

任务:给定句子 “爱因斯坦在柏林发表演讲”,根据 IOBES 标注 NER 结果

输入改写:“[CLS]爱 因 斯坦 在 柏林 发表 演讲”

BERT Softmax 结果:

BOBES 斯坦 柏林 发表 演讲
O 0.01 0.01 0.01 0.90 0.01 0.90 0.90
B-PER 0.90 0.01 0.01 0.01 0.01 0.01 0.01
I-PER 0.01 0.90 0.01 0.01 0.01 0.01 0.01
E-PER 0.01 0.01 0.90 0.01 0.01 0.01 0.01
S-LOC 0.01 0.01 0.01 0.01 0.01 0.01 0.01

对 Softmax 的结果取 arg max,获得最终地 NER 标注结果为:“爱因斯坦” 是人名;“柏林” 是地名

11.5 BERT效果展现

不管如何,从上述讲解能够看出,NLP 四大类任务均可以比较方便地改形成 Bert 可以接受的方式,总之不一样类型的任务须要对模型作不一样的修改,可是修改都是很是简单的,最多加一层神经网络便可。这实际上是 Bert 的很是大的优势,这意味着它几乎能够作任何NLP的下游任务,具有普适性,这是很强的。

可是讲了这么多,一个新模型好很差,效果才是王道。那么Bert 采用这种两阶段方式解决各类 NLP 任务效果如何?

在 11 个各类类型的 NLP 任务中达到目前最好的效果,某些任务性能有极大的提高。

12、BERT 总结

最后,我讲讲我对Bert的评价和见解,我以为 Bert 是 NLP 里里程碑式的工做,对于后面 NLP 的研究和工业应用会产生长久的影响,这点毫无疑问。可是从上文介绍也能够看出,从模型或者方法角度看,Bert 借鉴了 ELMO,GPT 及 CBOW,主要提出了 Masked 语言模型及 Next Sentence Prediction,可是这里 Next Sentence Prediction 基本不影响大局,而 Masked LM 明显借鉴了 CBOW 的思想。因此说 Bert 的模型没什么大的创新,更像最近几年 NLP 重要进展的集大成者,这点若是你看懂了上文估计也没有太大异议,若是你有大的异议,杠精这个大帽子我随时准备戴给你。

若是概括一下这些进展就是:首先是两阶段模型,第一阶段双向语言模型预训练,这里注意要用双向而不是单向,第二阶段采用具体任务 Fine-tuning 或者作特征集成;第二是特征抽取要用Transformer 做为特征提取器而不是 RNN 或者 CNN;第三,双向语言模型能够采起 CBOW 的方法去作(固然我以为这个是个细节问题,不算太关键,前两个因素比较关键)。Bert 最大的亮点在于效果好及普适性强,几乎全部 NLP 任务均可以套用 Bert 这种两阶段解决思路,并且效果应该会有明显提高。能够预见的是,将来一段时间在 NLP 应用领域,Transformer 将占据主导地位,并且这种两阶段预训练方法也会主导各类应用。

另外,咱们应该弄清楚预训练这个过程本质上是在作什么事情,本质上预训练是经过设计好一个网络结构来作语言模型任务,而后把大量甚至是无穷尽的无标注的天然语言文本利用起来,预训练任务把大量语言学知识抽取出来编码到网络结构中,当手头任务带有标注信息的数据有限时,这些先验的语言学特征固然会对手头任务有极大的特征补充做用,由于当数据有限的时候,不少语言学现象是覆盖不到的,泛化能力就弱,集成尽可能通用的语言学知识天然会增强模型的泛化能力。如何引入先验的语言学知识其实一直是 NLP 尤为是深度学习场景下的 NLP 的主要目标之一,不过一直没有太好的解决办法,而 ELMO/GPT/Bert 的这种两阶段模式看起来无疑是解决这个问题天然又简洁的方法,这也是这些方法的主要价值所在。

对于当前 NLP 的发展方向,我我的以为有两点很是重要:

  1. 一个是须要更强的特征抽取器,目前看 Transformer 会逐渐担当大任,可是确定仍是不够强的,须要发展更强的特征抽取器;
  2. 第二个就是如何优雅地引入大量无监督数据中包含的语言学知识,注意我这里强调地是优雅,而不是引入,此前至关多的工做试图作各类语言学知识的嫁接或者引入,可是不少方法看着让人牙疼,就是我说的不优雅。

目前看预训练这种两阶段方法仍是颇有效的,也很是简洁,固然后面确定还会有更好的模型出现。

完了,这就是预训练语言模型的前世此生。

因为我的刚入门 NLP 方向,就不妄自总结,上述总结所有来自知乎文章:从Word Embedding到Bert模型—天然语言处理中的预训练技术发展史-张俊林

十3、参考资料

我只是知识的搬运工,想详细了解各个知识点的读者能够自行选择参考下列资料。

相关文章
相关标签/搜索