1.什么是BERT
- BERT是2018年10⽉由Google AI研究院提出的⼀种预训练模型(已经在大型数据集上被训练好的模型).
- BERT的全称是Bidirectional Encoder Representation from Transformers. BERT在机器阅读理解顶级⽔平测试SQuAD1.1中表现出惊⼈的成绩:
全部两个衡量指标上全⾯超越⼈类, 并且在11种不同NLP测试中创出SOTA表现. 包括将GLUE基准推⾼⾄80.4% (绝对改进7.6%),MultiNLI准确度达到86.7% (绝对改进5.6%). 成为NLP发展史上的⾥程碑式的模型成就.注:SOTA代表的是State-of-the-Art,即当前的最佳技术或方法。在各个领域,SOTA通常指的是在该领域内最新的、最先进的技术或模型,这些技术和模型在相应的基准测试中取得了最好的性能表现。
2.BERT架构
如图左一为BERT架构,其余两个分别是GPT和ELMo的架构图。
相同点:
- 都是预训练模型,包含有Embedding层、Transformer层和最后输出层(预微调层)
- BERT 和OpenAI GPT 是微调方法,而 ELMo 是基于特征的方法。
不同点:
- BERT:采⽤Transformer Encoder block进⾏连接, 因为是⼀个典型的双向编码模型;
- OpenAI GPT:仅包含左到右的编码形式;
- ELMo:独立包含左到右和右到左的LSTM(双向LSTM模型)编码形式。(ELMo模型用于获得词向量)ELMo模型详解
2.1BERT架构详解
2.1.1 Embedding层
2.1.2 Transformer层
2.1.3 预微调层
2.2 BERT模型经验参数
2.3 BERT的预训练任务
即:抽取15%的样本数据,将其中token(理解为一个单词或字符)按照一定比例进行遮掩(mask),之后和剩下的数据一起进行训练学习,进而掌握原语言的规则。
注:token意义: 在人工智能领域,尤其是自然语言处理(NLP)中, “token” 指的是处理文本的最小单元或基本元素。
3.Transformer
3.1 Transformer诞生背景
2018年10⽉,Google发出⼀篇论⽂《BERT: Pre-training of Deep Bidirectional
Transformers for Language Understanding》, BERT模型横空出世,并横扫NLP领域11项任务的最佳成绩!
- 论⽂地址: https://arxiv.org/pdf/1810.04805.pdf
虽然BERT后被淘汰,但BERT的核心就是Transformer,一直沿用至今。
相⽐之前占领市场的LSTM和GRU模型,Transformer有两个显著的优势: 下⾯是⼀张在测评⽐较图:
- 1、Transformer能够利⽤分布式GPU进⾏并⾏训练,提升模型训练效率.
- 2、 在分析预测更⻓的⽂本时,捕捉间隔较⻓的语义关联效果更好.
注:BLEU:衡量机器翻译的好坏.
3.2Transformer结构
以下架构图为Transformer文本翻译结构。
Transformer架构共四个部分:
输入层、编码层、解码层、输出层
3.3 Encoder模块
- 经典的Transformer结构中的Encoder模块包含6个Encoder Block.
- 每个Encoder Block包含⼀个多头⾃注意⼒层, 和⼀个前馈全连接层. (每一层都还包括规范化层以及⼀个残差连接)
下面以一个Encoder Block为例进行分析:
3.3.1多头自注意层
- self-attention结构
即Scaled Dot-Product Attention的计算⽅式(缩放点积注意力)
- 所谓的多头self-attention层, 则是先将Q, K, V经过参数矩阵进⾏映射, 再做self-attention, 最后将结果拼接起来送⼊⼀个全连接层即可.(下图中紫色方块即为self-attention)
数学公式:
- 多头self-attention层的作⽤: 实验结果表明, Multi-head可以在更细致的层⾯上提取不同head的特征, 总体计算量和单⼀head相同的情况下, 提取特征的效果更佳.
3.3.2 前馈全连接层模块
前馈全连接层模块, 由两个线性变换组成, 中间有⼀个Relu激活函数, 对应的数学公式形式如下:
前馈全连接层的作⽤:
- 单纯的多头注意⼒机制并不⾜以提取到理想的特征, 因此增加全连接层来提升⽹络的能⼒.
3.4 Decoder模块
Decoder模块的结构和作⽤:
- 经典的Transformer结构中的Decoder模块包含6个Decoder Block.
- 每个Decoder Block包含三个⼦层.:⼀个多头self-attention层、⼀个Encoder-Decoder attention层、一个前馈全连接层
3.4.1 多头self-attention层 、Encoder-Decoder attention层、前馈全连接层
Decoder Block中的多头self-attention层:
- Decoder中的多头self-attention层与Encoder模块⼀致, 但需要注意的是Decoder模块的多头self-attention需要做look-ahead-mask, 因为在预测的时候"不能看⻅未来的信息", 所以要将当前的token和之后的token全部mask.
即,只有之前步的token可见,将现在和未来的token全部mask掉,以使得在对之后decode之前不可见之后的token,防止模型将已知的token当作结果。
Decoder Block中的Encoder-Decoder attention层:(即Decoder模块中的中间部分)
- 这⼀层区别于⾃注意⼒机制的Q = K = V, 此处矩阵Q来源于Decoder端经过上⼀个 Decoder Block的输出, ⽽矩阵K, V则来源于Encoder端的输出, 造成了Q != K = V的情况.
- 这样设计是为了让Decoder端的token能够给予Encoder端对应的token更多的关注.
前馈全连接层模块:和Encoder模块的一样
Decoder Block中有2个注意⼒层的作⽤:
- 多头self-attention层是为了拟合Decoder端⾃身的信息,
- ⽽Encoder-Decoder attention层是为了整合Encoder和Decoder的信息.
3.4.2 Add & Norm模块
Add & Norm模块接在每⼀个Encoder Block和Decoder Block中的每⼀个⼦层的后⾯. 具体来说Add表示残差连接, Norm表示LayerNorm.
对于每⼀个Encoder Block, ⾥⾯的两个⼦层后⾯都有Add & Norm.
对于每⼀个Decoder Block,⾥⾯的三个⼦层后⾯都有Add & Norm.
具体的数学表达形式为: LayerNorm(x + Sublayer(x)), 其中Sublayer(x)为⼦层的输出.
- 其中x + Sublayer(x)为残差;LayerNorm为规范化
Add残差连接的作⽤:
和其他神经⽹络模型中的残差连接作⽤⼀致, 都是为了将信息传递的更深, 增强模型的拟合能⼒.(防止层数过多导致梯度爆炸和梯度消失)Norm的作⽤: 随着⽹络层数的额增加, 通过多层的计算后参数可能会出现过⼤, 过⼩, ⽅差变⼤等现象, 这会导致学习过程出现异常, 模型的收敛⾮常慢. 因此对每⼀层计算后的数值进⾏规范化可以提升模型的表现.
3.4.3 位置编码器
输出部分经过的位置编码。
3.4.4 Decoder端的输⼊解析
6个Block的输⼊不完全相同:
- 最开始的⼀层Block接收的输⼊是经历了MASK之后的Decoder端的输⼊ + Encoder端的输出.
- 其他5层Block接收的输⼊模式⼀致, 都是前⼀层Block的输出 + Encoder端的输出.
可以看到,对于Decoder的输入6个Block都包括Encoder端的输出(K、V),只是对于Decoder端的部分不尽相同。
3.4.4.1 训练阶段的输⼊解析:
- 从第⼆层Block到第六层Block的输⼊模式⼀致, ⽆需特殊处理, 都是固定操作的循环处理.
- 聚焦在第⼀层的Block上:训练阶段每⼀个time step的输⼊是上⼀个time step的输⼊加上真实标签序列向后移⼀位.
- 具体来说,假设现在的真实标签序列等于"How are you?",
- 当 time step=1时, 输⼊张量为⼀个特殊的token, ⽐如"SOS"(起始位);
- 当time step=2时, 输⼊张量 为"SOS How"; 当time step=3时, 输⼊张量为"SOS How are",
- 以此类推…
- 注意: 在真实的代码实现中, 训练阶段不会这样动态输⼊, ⽽是⼀次性的把⽬标序列全部输⼊给第⼀层的Block, 然后通过多头self-attention中的MASK机制对序列进⾏同样的遮掩 即可.
- 即:当 time step=1时, 输⼊张量为⼀个特殊的token, ⽐如"SOS"(起始位);
- 当time step=2时, 输⼊张量 为"SOS How",此时输入了整个真实序列"How are you?",只是将“are you?”进行遮掩;
- 当time step=3时, 输⼊张量为"SOS How are",将“you?”进行遮掩;
- 以此类推…
3.4.4.2 在预测阶段的输⼊解析:
- 同理于训练阶段, 预测时从第⼆层Block到第六层Block的输⼊模式⼀致, ⽆需特殊处理, 都
是固定操作的循环处理.- 聚焦在第⼀层的Block上: 因为每⼀步的输⼊都会有Encoder的输出张量, 因此这⾥不做特殊讨论, 只专注于纯粹从Decoder端接收的输⼊.
- 预测阶段每⼀个time step的输⼊是从 time step=0,input_tensor="SOS"开始, ⼀直到上⼀个time step的预测输出的累计拼接张 量. 具体来说:
- 当time step=1时, 输⼊的input_tensor=“SOS”, 预测出来的输出值是 output_tensor=“What”;
- 当time step=2时, 输⼊的input_tensor=“SOS What”, 预测出来的输出值是 output_tensor=“is”;
- 当time step=3时, 输⼊的input_tensor=“SOS What is”, 预测出来的输出值是output_tensor=“the”;
- 当time step=4时, 输⼊的input_tensor=“SOS What is the”, 预测出来的输出值是 output_tensor=“matter”;
- 当time step=5时, 输⼊的input_tensor=“SOS What is the matter”, 预测出来的输出值 是output_tensor=“?”;
- 当time step=6时,输⼊的input_tensor=“SOS What is the matter ?”, 预测出来的输出值是output_tensor=“EOS”, 代表句⼦的结束符, 说明解码结束, 预测结束.