参考链接
论文链接:https://arxiv.org/pdf/1810.04805v1.pdf
代码链接:https://github.com/google-research/bert
参考博客https://arxiv.org/pdf/1810.04805v1.pdf
模型架构
模型图
- BERT模型架构是:一个多层的双向的Transformer的encoder。Encoder如下图所示:
- B E R T B A S E BERT_{BASE} BERTBASE: L=12, H=768, A=12, Total Parameters=110M
- B E R T L A R G E BERTL_{ARGE} BERTLARGE: L=24, H=1024, A=16, Total Parameters=340M
输入表示
- 我们的输入表示能够在一个标记序列中明确地表示单个文本句子或一对文本句子(例如,[问题,答案])。一个词的输入=词的embeding+段embeding+位置embeding
- 对于词embeding论文使用WordPiece embeddings
- 每个序列的第一个字符始终是特殊分类embedding([CLS])。对应于该字符的最终隐藏状态(即,Transformer的输出)被视为整个序列表示常用于聚合用作分类任务。对于非分类任务,将忽略此向量。
- 句子对被打包成一个序列,我们以两种方式区分句子, 第一种:我们用特殊标记([SEP])将它们分开。第二种:我们添加一个学习句子A嵌入到第一个句子的每个标记中,一个句子B嵌入到第二个句子的每个标记中,对于单句输入,我们只使用句子A嵌入。
预训练
- 任务一:Masked LM
- 标准条件语言模型只能从左到右或从右到左进行训练,因为双向条件语言模型将允许每个单词在多层self-attention中间接看到自己。为了避免当前要预测的词在self-attention中看到要预测的答案我们采样的方法是:随机屏蔽掉(mask)输入序列中一定比例的输入词,然后仅预测那些被屏蔽的词,称这个方法叫masked LM(MLM),最后我们将这个被mask的词的最后隐藏层输出,输入到softmax层中预测这个被mask的词
- 在论文的实验中我们每次mask掉一个序列的15%词
- 该任务的两个缺点:
- 第一个:这种操作使得预训练和微调之间不匹配,因为在微调期间可能没有[MASK]字符。为了缓解这种情况我们不总是用[MASK]词来替换被mask掉的词,而是80%的用[MASK]词来替换被mask掉的词,10%用一个随机词来替换被mask掉的词,再,10%保存源词不变。例子:
- 原句:my dog is hairy 我们要mask掉hairy
- 80%:my dog is [MASK]
- 10%:my dog is apple
- 10%:my dog is hairy
- 第二个:每个batch中只预测了15%的词,这表明模型可能需要更多的预训练步骤才能收敛。实验证明该任务的训练略微慢一点比起预测每一个词的语言模型。
- 第一个:这种操作使得预训练和微调之间不匹配,因为在微调期间可能没有[MASK]字符。为了缓解这种情况我们不总是用[MASK]词来替换被mask掉的词,而是80%的用[MASK]词来替换被mask掉的词,10%用一个随机词来替换被mask掉的词,再,10%保存源词不变。例子:
- 任务二:Next Sentence Prediction
- 为了训练理解句子关系的模型,我们预先训练下一句话预测任务,该任务可以从任何单语言语料库中生成。具体地,在构建每个预训练样本时,选择句子A和B,50%B是A的实际下一句子, 50%B是来自语料库的一个随机句子,例子如下:
- Input = [CLS] the man went to [MASK] store [SEP] he bought a gallon [MASK] milk [SEP]
- Label = IsNext
- Input = [CLS] the man [MASK] to the store [SEP] penguin [MASK] are flight ##less birds [SEP]
- Label = NotNext
- 为了训练理解句子关系的模型,我们预先训练下一句话预测任务,该任务可以从任何单语言语料库中生成。具体地,在构建每个预训练样本时,选择句子A和B,50%B是A的实际下一句子, 50%B是来自语料库的一个随机句子,例子如下:
- 预训练过程设置:
- 输入序列长度为512,batch_size=256,训练1000000步近似在33亿词的预料库上40 epochs
- 使用Adam优化器,learning_rate=1e-4, β_1= 0.9, β_2= 0.999,权重的L2正则项系数为0.01,学习率是预热步数:10000,学习率线性衰退,在每一层使用概率为0.1的dropout,激活函数使用gelu
微调
- 对于序列水平的分类任务,我们获取第一个词[CLS]的最后隐藏层状态 C ∈ R H C∈R^H C∈RH,再将C经过一个全连接层 ( W ∈ R K × H ) + s o t f m a x (W∈R^{K×H})+sotfmax (W∈RK×H)+sotfmax层得到最后的预测分布 ( P = s o f t m a x ( C W T ) ) (P=softmax(CW^T)) (P=softmax(CWT)),其中K是类别数。W也是这种特殊任务唯一添加的模型参数。
- 在微调的过程中BERT和W被同时微调。
- 在微调中,大多数模型超参数与预训练相同,一般修改的超参数是:batch_size, learning_rate, epochs。 Dropout的概率始终保持在0.1。理论上说最佳超参数值随特定于任务不同而不同,但我们发现以下范围的可能值可以在所有任务中很好地工作:
- Batch size: 16, 32
- Learning rate (Adam): 5e-5, 3e-5, 2e-5
- Number of epochs: 3, 4
- 我们还观察到,大数据集对超参数选择的敏感性远小于小数据集
- 微调总结图:
模型对比

总结
词嵌入语言模型的方法
- NLP词嵌入语言模型的方法:
- Feature-based方法
- Feature-based指利用预先训练好的语言模型的结果,作为当前特定任务模型(task-specific)的一个额外的特征引入到当前特定任务模型中,例如下图的语言模型
- 通常feature-based方法包括两步:
- 首先在大的语料A上无监督地训练语言模型,训练完毕得到语言模型。
- 然后构造task-specific model例如序列标注模型,采用有label的语料B来有监地训练task-sepcific model,将语言模型的参数固定,语料B的训练数据经过语言模型得到LM embedding,作为task-specific model的额外特征
- ELMo是这方面的典型代表
- Feature-based指利用预先训练好的语言模型的结果,作为当前特定任务模型(task-specific)的一个额外的特征引入到当前特定任务模型中,例如下图的语言模型
- Feature-based方法
- Fine-tuning方法
- Fine-tuning方式是指在已经训练好的语言模型的基础上,加入少量的task-specific parameters, 例如对于分类问题在语言模型基础上加一层softmax网络,然后在新的语料上重新训练来进行fine-tune。
- OpenAI GPT 是这一方法的典型代表,其模型如下所示:
- Fine-Tuning的方法工作包括两步:
- 构造语言模型,采用大的语料A来训练语言模型
- 在语言模型基础上增加少量神经网络层来完成specific task model例如序列标注、分类等,然后采用有label的语料B来有监督地训练模型,这个过程中语言模型的参数并不固定.
- 而BERT采用了fine-tuning的方法,并且在许多task-specific model中取得了最好的效果