提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
例如:看过很多次BERT,每次需要再查资料去回忆,特此记录。
提示:以下是本篇文章正文内容,下面案例可供参考
一、BERT是什么?
Bidirectional Encoder Representation from Transformers,Transformer结构的一种,相较于Transformer增加了大批量语料去预训练,参考预训练发展史。
比如一句话 A B C D E
以前train一个Language model(最简单情况 window size =1 也即是1-gram )是这样的
- given [START] 然后Predict (label是A)
- given A 然后再predict (label是B)
- given B 然后再predict (label是C)
…
Bert是这样做
现在变成了我把D 变成mask
give [A, B, C, E] 然后predict(label是D)
this also why BERT paper says “之前都是left to right or right to left",我们bert很牛皮是bidirectional的
一句话TAKE AWAY:
bert的bidirectinonal其实就是让model去从类似初中高中时候英语试卷里的那种完形填空去训练自己,然后得到word representation。
二、细节
1.输入部分
输入部分是个线性序列,两个句子通过分隔符分割,最前面和最后增加两个标识符号。每个单词有三个embedding:位置信息embedding,这是因为NLP中单词顺序是很重要的特征,需要在这里对位置信息进行编码;单词embedding,这个就是我们之前一直提到的单词embedding;第三个是句子embedding,因为前面提到训练数据都是由两个句子构成的,那么每个句子有个句子整体的embedding项对应给每个单词。把单词对应的三个embedding叠加,就形成了Bert的输入。
第一个output的纬度会被reshape为[batch_size, seq_length, embedding_size],后续的width即为这里output[2]的纬度,这里注意下三个要学习的embedding变量纬度
1. 词表embedding
embedding_table = tf.get_variable(
name=word_embedding_name,
shape=[vocab_size, embedding_size],
initializer=create_initializer(initializer_range))
2. 句子token,token_type_vocab_size是句子个数,每句话的每个词共享一个token embedding
token_type_table = tf.get_variable(
name=token_type_embedding_name,
shape=[token_type_vocab_size, width],
initializer=create_initializer(initializer_range))
3. 位置embedding,[最大句长, embedding_size]
full_position_embeddings = tf.get_variable(
name=position_embedding_name,
shape=[max_position_embeddings, width],
initializer=create_initializer(initializer_range))
2.输出部分
Bert的输出最终有两个结果可用
sequence_output:维度【batch_size, seq_length, hidden_size】,这是训练后每个token的词向量。
pooled_output:维度是【batch_size, hidden_size】,通过处理上个输入得到,self.pooled_output=tf.squeeze(self.sequence_output[:, 0:1, :], axis=1),每个sequence第一个位置CLS的向量输出,用于分类任务。