BERT
迁移学习在自然语言处理(NLP)领域同样也是一种强大的技术。由这种技术训练出来的模型,我们称之为预训练模型。
预训练模型首先要针对数据丰富的任务进行预训练,然后再针对下游任务进行微调,以达到下游任务的最佳效果。迁移学习的有效性引起了理论和实践的多样性,
两者相结合,高效地完成了各种NLP的实际任务
1. 预训练模型
BERT的结构是来自Transformers模型的Encoder。
Transformer的内部结构由Self-Attention Layer和Layer Normalization的堆叠而产生。
Bert定义:BERT被设计为通过在所有层的双向上下文上共同进行条件化来预训练未标记文本的深层双向表示
(可以理解为:用未标记的一个文本去训练一个模型,对所有的问题都有很强的泛化性)
我们可以在仅一个附加输出层的情况下对经过预训练的BERT模型进行微调,以创建适用于各种任务( 例如问题解答和语言推断)的最新模型,进而减少了对NLP任务精心设计特定体系结构的需求
通俗易懂来讲就是我们只需要把BERT当成一个深层次的Word2Vec预训练模型,对于一些特定的任务,我们只需要在BERT之后下接一些网络结构就可以出色地完成这些任务。
2. Self-Attention Layer 原理
BERT的结构是来自Transformers模型的Encoder
Transformer的内部结构由Self-Attention Layer和Layer Normalization的堆叠而产生。
Self-Attention Layer的出现原因:为了解决RNN、LSTM等常用于处理序列化数据的网络结构无法在GPU中并行加速计算的问题。
BERT的内部结构: Self Attention Layer的输入
因为有时候训练样本是由两句话组成,因此“[CLS]”是用来分类输入的两句话是否有上下文关系,而“[SEP]"则是用以分开两句话的标志符。
[CLS] 标志放在第一个句子的首位,经过 BERT 得到的的表征向量 C 可以用于后续的分类任务。
[SEP] 标志用于分开两个输入句子,例如输入句子 A 和 B,要在句子 A,B 后面增加 [SEP] 标志。
Input = token embedding + segment embedding + position embedding
因为这里的Input是英文单词,所以在灌入模型之前,需要用BERT源码Tokenization工具对每一个单词进行分词。
分词后的形式:“ Playing”转换成“Play"+“# #ing”,因为英文词汇表是通过词根与词缀的组合来新增单词语义的,所以我们选择用分词方法可以减少整体的词汇表长度。
如果是中文字符的话,输入就不需要分词,整段话的每-一个字用“空格”隔开即可。
注意:模型是无法处理文本字符的,所以不管是英文还是中文,我们都需要通过预训练模型BERT自带的字典vocab.txt将每一一个字
或者单词转换成字典索引(即id) 输入。
segment embedding的目的:有些任务是两句话一起放入输 入x,而segment便是用 来区分这两句话的。在Input那里就是用“[SEP]”作为标志符号。而“[CLS]”用 来分类输入的两句话是否有上下文关系。
position embedding的目的:因为我们的网络结构没有RNN或者LSTM,因此我们无法得到序列的位置信息,所以需要构建一个position embedding。
构建position embedding有两种方法:
- BERT是 初始化一个position embedding,然后通过训练将其学出来。
- Transformer 是通过制定规则来构建一个position embedding:使用正弦函数,位置维度对应曲线,而且方便序列之间的选对位置,使用正弦会比余弦好的原因是可以在训练过程中,将原本序列外拓成比原来序列还要长的序列。
T
E
(
t
,
2
i
)
=
sin
(
t
/
1000
0
2
i
/
m
o
d
e
l
)
T E(t, 2 i)=\sin \left(t / 10000^{2 i / model}\right)
TE(t,2i)=sin(t/100002i/model)
T
E
(
t
,
2
i
+
1
)
=
cos
(
t
/
1000
0
2
i
/
m
o
d
e
l
)
T E(t, 2 i+1)=\cos \left(t / 10000^{2 i / model}\right)
TE(t,2i+1)=cos(t/100002i/model)
Self- Attention Layer的内部逻辑运算: multi-head
单头 Self-Attention运算逻辑多头 Self-Attention运算逻辑
通过Linear线性投影来初始化不同的(Q,K,V),将多个单头的结果融合会比单头Self-Attention的效果好。
整体的运算逻辑: Multi-Head Self-Attention将多个不同单头的Self-Attention输出Concat成一条,然后再经过一个全连接层降维输出
3. Layer Normalization(Bert 内部结构)
数据形状:当一个batch的数据输入模型的时候,形状是长方体大小为(batch_ size, max_ len, embedding),
batch_ size为batch的批数
max_ len为每一批数据的序列最大长度
embedding则为每一个单词或者字的embedding维度大小。
Self- Attention的输出会经过Layer Normalization,为什么选择Layer Normalization而不是Batch Normalization?
Batch Normalization是对每个Batch的每一列做normalization,相当于是对batch里相同位置的字或者单词embedding做归一化。
Layer Normalization是Batch的每一行 做normalization,相当于是对每句话的embedding做归一化。
显然,Layer Normalization更加符合我们处理文本的直觉。
4. Bert 预训练
输入
就是Self- Attention Layer的输入,利用字典将每一个字或者单词用数字表示,
并转换成token embedding + segment embedding +position embedding。
序列的长度一般有512 或者1024,不足用"[PAD]” 补充。
句子开头第一个位置用"[CLS]" 表示,如果是输入两句话,则用‘[SEP]” 隔开。
MaskLM策略
对于输入X,1 5%的字或者英文单词采用随机掩盖策略。
对于这15%的字或者英文单词,80%的概率用"[mask]"替换序列中的某个字或者英文单词
10%的概率替换序列中的某个字或者英文单词,
10%的概率不做任何变换。
训练语料总量
330亿语料
预训练
两种训练同时进行:
(1)预测被掩盖的字或者英文单词(MaskLM)
(2)预测两句话之间是否有顺序关系(Next Sentence Prediction, NSP)
BERT预训练: Pre-training |无监督学习训练数据
NLP的预训练模型与计算机视觉的预训练模型有些许不同,NLP的预训练方式采用的是无监督学习,即我们不需要人工打标签,而计算机视觉需要则需要对图像进行人工分类。
因为NLP的预训练只是预测被掩盖的单词或者字,以及判断是两段话是否有顺序关系,这些只需要写个小程序就可以轻松得到相应的标签,无需人工进行大量的标记。
BERT模型权重
最后经过大量语料的无监督学习,我们得到了BERT预训练模型,BERT自带字典vocab.txt的每- - 个字或者单词都被768维度的embedding (即权重)所表示。
当我们需要完成特定任务时,若对它们的embedding进行微调(即fine-tune),还能更好的适应任务。
5. Bert Fine-tune 过程
1.不选择fine-tune,那就是简单地使用BERT的权重,把它完全当成文本特征提取器使用;
2.使用fine-tune,则相当于在训练过程中微调BERT的权重,以适应我们当前的任务。
BERT的fine- tune:超参数设置
文章提及到如果选择下面这几个参数进行fine-tune调参,任务的完成度会比较好。
- Batch Size:16 or 32;
- Learning Rate: 5e-5, 3e-5, 2e-5;
- Epochs:2, 3, 4;