BERT模型学习与分析
前段时间Google推出了重磅的模型BERT(Bidirectional Encoder Representations from Transformers),刷新的多项记录,因为前面分析了一下Transformer模型,构建了基础,然后现在总结学习一下Bert模型。
1、什么是BERT模型?
BERT=基于Transformer 的双向编码器表征,顾名思义,BERT模型的根基就是Transformer,来源于attention is all you need。其中双向的意思表示它在处理一个词的时候,能考虑到该词前面和后面单词的信息,从而获取上下文的语义。
它们三者与Word2Vec、单向LSTM之间的对比
Model | 获取长距离语义信息程度 | 能否左右上下文语义 | 是否可以并行 |
---|---|---|---|
Word2Vec | 1 | 能 | 能 |
单向LSTM | 2 | 不能 | 不能 |
ELMo | 2 | 能 | 不能 |
GPT | 3 | 不能 | 能 |
BERT | 3 | 能 | 能 |
ELMo采用的是双向的LSTM的架构,所以能够抓取到左右上下文的语义
由于GPT和BERT都采用了Transformer,所有它们都是能够完成并行计算,但是由于GPT采用的是单向的,导致了每个token只能关注左侧的语境,在文献中被称为了“Transformer解码器”,而BERT采用了双向的双向的自注意机制,所以被称为了“Transformer编码器”。
预训练语言表征
2、BERT模型核心点
1、BERT的架构
BERT的模型架构基于了Transformer,实现了多层双向的Transformer编码器。文中有两个模型,一个是1.1亿参数的base模型,一个是3.4亿参数的large模型。里面所设置的参数如下:
Model | Transformer层数(L) | Hidden units(H) | self-attention heads(A) | 总参数 |
---|---|---|---|---|
BERT(base) | 12 | 768 | 12 | 1.1亿 |
BERT(large) | 24 | 1024 | 16 | 3.4亿 |
其中base模型的参数和OpenAI的GPT的参数一致。目的就是为了同GPT的效果进行一个比较。
2、BERT的输入表征
下图表示了BERT的输入表征
下面的思维导图说明了各个部分的作用是什么:
3、BERT中最核心的部分
(1)Masked Language Model(MLM)
为了实现深度的双向表示,使得双向的作用让每个单词能够在多层上下文中间接的看到自己。文中就采用了一种简单的策略,也就是MLM。
MLM:随机屏蔽掉部分输入token,然后再去预测这些被屏蔽掉的token。
这里实现的时候有两个缺点
缺点1:预训练与微调之间的不匹配,因为微调期间是没有看到[Mask]token。
- Solution:不是总用实际的[Mask]token替换被“masked”的词汇,而是采用训练数据生成器随机去选择15%的token。
- 例子:句子= my dog is hairy, 选择的token是hairy。执行的流程为:
Transformer不知道它将被要求预测哪些单词或哪些单词已被随机单词替换,因此它被迫保持每个输入词块的分布式语境表征。此外,因为随机替换只发生在所有词块的1.5%(即15%的10%),这似乎不会损害模型的语言理解能力。
缺点2:每个batch只预测了15%的token,这说明了模型可能需要更多的预训练步骤才能收敛。
(2)Next Sentence Prediction
现在从句子的角度来考虑问题,预训练了一个二值化下一句预测任务,该任务可以从任何单语语料库中轻松生成。具体来说,选择句子A和B作为预训练样本:A的下一句有50%的可能是B,另外50%的可能是来自语料库的。
例子:
- 输入=[CLS]男子去[MASK]商店[SEP]他买了一加仑[MASK]牛奶[SEP]
Label= IsNext - 输入=[CLS]男人[面具]到商店[SEP]企鹅[面具]是飞行##少鸟[SEP]
Label= NotNext
4、预训练过程
训练批量大小为256个序列(256个序列*512个词块=128,000个词块/批次),持续1,000,000个步骤,这比33亿个单词语料库大约40个周期
Item | 值或名称 |
---|---|
学习率 | |
Adam β1 | 0.9 |
Adam β2 | 0.999 |
L2权重衰减 | 0.01 |
dropout | 0.1 |
激活函数 | gelu |
Model | TPU个数 | TPU芯片个数 | 每次预训练天数 |
---|---|---|---|
BERT(Base) | 4 | 16 | 4 |
BERT(Large) | 16 | 64 | 4 |
5、微调过程
微调过程中,大多数模型超参数与预训练相同。批量大小、学习率和训练周期数量会有区别。最佳超参数值是特定于任务的,但我们发现以下范围的可能值可以在所有任务中很好地工作:
参数 | 值 |
---|---|
Batch | 16,32 |
学习率Adam | 5e-5,3e-5,2e-5 |
周期 | 3,4 |
4、实验部分
BERT应用到了11项NLP的任务上面
(1)GLUE数据集
上图中,(a)和(b)是序列级任务,(c)和(d)是词块级任务。图中E代表其输入嵌入,Ti代表词块i的语境表征,[CLS]是分类输出的特殊符号,[SEP]是分割非连续词块序列的特殊符号。
(2)斯坦福问答数据集SQuAD v1.1
斯坦福问答数据集SQuAD v1.1:一种100k众包问答对的集合
任务:给出一个问题和包含答案的来自维基百科的一个段落,任务是预测该段落中的其答案文本的跨度
(3)命名实体识别(NER)
数据集:CoNLL 2003命名实体识别(NER)数据集,由200k个训练单词组成,这些单词已注释为人员、组织、位置、杂项或其他(非命名实体)。
5、实践部分
尝试用github上面的bert-ner中文的项目,跑了一下ner,具体操作如下:
git clone https://github.com/ProHiryu/bert-chinese-ner
然后需要将Google写的bert的源码给放到当前的文件夹下,可以采用git clone的方式
git clone https://github.com/google-research/bert
同时需要下载Google遇训练好了模型,然后放到了checkpoint文件夹里面。下载地址是:https://github.com/ProHiryu/bert-chinese-ner
最后的文件目录树是
准好了之后,就可以进行训练了:
python BERT_NER.py --data_dir=data/ --bert_config_file=checkpoint/bert_config.json --init_checkpoint=checkpoint/bert_model.ckpt --vocab_file=vocab.txt --output_dir=./output/result_dir/
最后写在output文件下面,可以找到eval_results.txt文件,然后我们可以看到本次训练的结果如下:
image.png
持续更新中...
参考资料
1、BERT
2、https://www.cnblogs.com/huangyc/p/9898852.html