Google 在18年发布的Bert(Bidirectional Encoder Representations from Transformer)预训练模型在近期的NLP非常火爆,它的微调在各种NLP任务(GLUE,MultiNLI,SQuAD等评价基准和数据集)中达到最优,直到XLNet的出现。本文我想总结一下Bert的原理和使用方法,之后我会总结XLNet的原理和使用方法。
1.Bert模型的整体结构
Bert在结构上比Transformer要简单,因为Bert只使用了Transfomer的Encoder部分。
Embedding层,包括token embedding, position embedding和segment embedding
Encode层,实际上是多层encoder的堆叠。基本上和Transformer里的encoder保持一致
Bert的整体结构是以Transformer为基础构建,使用WordPiece的方法处理数据,最后通过Masked Language Model(MLM)和Next Sentence Prediction(NSP)二类任务进行预训练的语言表示建模。
1.1Embedding层
Bert包含3个embedding
Token embedding和transformer是一致的
Position embedding使用绝对位置进行位置编码
Segment embedding是为了区分不同的序列
Bert预训练模型的输入是一个序列。
处理输入训练的方式是把两个序列拼接起来,具体做法为:
在序列的开头处加上[cls]标记。
在第一个序列结尾处和第二个序列结尾处,增加[sep]标记
例子:
[CLS] bert is awesome.[SEP] i love it[SEP]
token ids: 100 34 3 6 5 101 2 9 4 101
position ids: 0 1 2 3 4 5 6 7 8 9
segment ids: 0 0 0 0 0 0 1 1 1 1
1.2 Encoder层
上面是Trasformer论文中一张图(注意Bert的输入不仅仅是input embedding+positional encodding) 输入的inputs经过input Embedding模块进行向量化,然后加上对其的Positional Encoding,然后数据向上进入由Multi-Head Attention, Add&Norm, Feed Forward以及一个Add&Norm构成的N个整体之中。
Embedding之后是Transformer里的encoder层,一般默认为12层的encoder堆叠而成。Transformer是一个完全基于注意力机制的模块。对比RNN(Recurrent Neural Network),当输入的句子是长句子时,RNN可能会遗忘之前句子中出现的字词,而Transformer的注意力机制会让句子中重要的字词的权重增大,从而保证不会被遗忘。这里也可以使用并行计算加快计算速度。这里进入一个很重要的感念multi-head attention。attention机制和Transformer里面是一模一样。Multi-Head Attention的组成因子是Self-Attention,即语句对自身计算注意力权重。多层叠加的Self-Attention组成了Multi-Head Attention。因为多层的原因,最后所有Self-Attention会生成多个大小相同的矩阵,然后把这些矩阵拼接起来,通过乘上一个参数矩阵得到最后的计算结果。
Muti-head attention内部是一个scaled dot-product attention。在Transformer的encoder部分是self-attention,因为计算attention score 的Q,K,V三个张量是相同的。
1.3 目标任务:
Encoder之后的两个任务,其中一个就是Masked Language Model(MLM),用一句话概况一下:对于输入的序列,按照一定概率随机替换原始token成[mask],然后让模型重建原始的输入序列。
original tokens: [CLS] bert is awesome . [SEP] i love it [SEP]
token ids: 100 34 3 6 5 101 2 9 4 101
position ids: 0 1 2 3 4 5 6 7 8 9
segment ids: 0 0 0 0 0 0 1 1 1 1
masked tokens: [CLS] bert is [MASK] . [SEP] i love it [SEP]
masked token ids: 100 34 3 103 5 101 2 9 4 101
position ids: 0 1 2 3 4 5 6 7 8 9
segment ids: 0 0 0 0 0 0 1 1 1 1
使用Masked_token_ids作为输入,进入Embedding层。
第二个任务是Next Sentence Prediction (NSP),是一个预测第二个序列是否是第一个序列的下一句的简单二分类问题。
2.Keras实现Bert
感谢CyberZHG提供了 Keras Bert的实现方法:
安装keras-bert
pip install keras-kert
一般人都不会自己训练bert模型,可以从google下载bert预训练模型
如果只想提取词/句子的特征,则可以使用extract_embedding来简化流程,
from keras_bert import extract_embeddings
model_path='xxx/yyy/uncased_L-12_H-768_A-12'
texts=['all work and no play','makes jack a dull boy~']
embeddings=extract_embeddings(model_path,texts)
返回的结果是一个list,长度和输入文本的个数相同。
另一种便捷实用bert的方法是通过bert-as-service服务提取词或者句子的特征:
首先,同样需要下载好预训练模型
之后安装服务端和用户端
pip install bert-serving-server (服务端需要python>=3.5并且TensorFlow>=1.10)
pip install bert-serving-client
启动服务端
bert-serving-start -model_dir /tmp/english_L-12_H-768_A-12/ -num_worker=4
使用用户端得到句向量
from bert_serving.client import BertClient
bc=BertClient()
bc.encode(['First do it','then do it right','then do it better'])
使用Bert情感分类项目:https://github.com/haoyijiang/keras_bert_text_classification
3.参考文档:
1.苏剑林 https://kexue.fm/archives/6915
2. 罗周杨 https://luozhouyang.github.io/bert_in_keras
3.keras-bert https://github.com/CyberZHG/keras-bert
4.bert-as-service https://github.com/hanxiao/bert-as-service
出自:世相科技
欢迎点赞支持