本文是对bert的细节进行整理,分成3个部分的问题:
目录
输入
- 与transformer相比输入有什么不同?
- bert的3种embedding分别有什么意义,如果实现的?
- Bert 的三个 Embedding 为什么可以进行相加?
- word piece 怎么做的?
- Bert的长度限制为512,如何处理长文本?
模型结构
- transformer是如何被使用的?
- 如何体现双向的?
- 为什么要 mask?怎么做的mask?为什么要这么做?
- 标注的mask会被attention吗?
- 关于layer normalization
- MLM和NSP是同时训练还是分开训练?损失函数如何表示的?
- 如何做下游任务?
其他问题
- Bert如何解决一词多义?
- 与GPT的区别是什么?
输入
与transformer相比输入有什么不同?
- 多了一个segment embedding,用来表示句子。在NSP任务中,标记上句和下句,上句中的每个token全为0,下句中的每个token全为1。(个人想法,0,1其实也是不同的标记,也可以换成其他值。)
- 在BERT中,Token,Position,Segment Embeddings 都是通过学习来得到的;而transformer中的Position是公式直接算的。
bert的3种embedding分别有什么意义,如果实现的?
3种embedding分别是:
- token embedding
输入文本在送入token embeddings 层之前要先进行tokenization处理。此外,两个特殊的token会被插入到tokenization的结果的开头 ([CLS])和结尾 ([SEP]) 。 tokenization使用的方法是WordPiece tokenization. - segment embedding
Bert在处理句子对的任务时,需要区分句子对中的上句/下句,因此用segment embedding来做识别。上句所有token的segment embedding均相同,下句所有token的segment embedding也相同;换句话说,如果是句子对,segment embedding只会有两种值,如图1所示。如果任务为单句的话,那segment embedding只有一个值。 - position embedding
与transformer不同的是,Bert的position embedding是学习出来的。相同的是,position embedding仍然用的是相对位置编码。
Bert 的三个 Embedding 为什么可以进行相加?
https://www.zhihu.com/question/374835153
简单点说,embedding本身就是信息的一种表示,也是一种信息的融合,因为可以从多种角度理解embedding。因此不妨将三个 Embedding相加也看作是一种特征融合。
另外,将token,position,segment三者都用one hot表示,然后concat起来,然后才去过一个单层全连接,等价的效果就是三个Embedding相加。
word piece 怎么做的?
待补充
Bert的长度限制为512,如何处理长文本?
Bert 如何解决长文本问题?
总的来说,用特征提取的思路,就是尽量保留有用的信息。有专门的论文研究这个问题,感兴趣可以仔细看看。
目前的处理方式有:
- head:保存前 510 个 token (留两个位置给 [CLS] 和 [SEP] )
- tail :保存最后 510 个token
- head+tail :选择前128个 token 和最后382个 token(文本在800以内)或者前256个token+后254个token(文本大于800tokens)
模型结构
transformer是如何被使用的?
这个问题只是想让自己了解多一点结构的细节,而不是模糊地说用到了transformer。
Bert只用到了transformer的encoder部分,在encoder的输出后连接分类层:MLM模型直接预测token,NSP预测是不是下一句。另外,Bert中模型的层数指的是encoder中block的个数(这个在论文和代码中都可以找到)。
如何体现双向的?/为什么要 mask?
这里的解释是结合关于BERT,面试官们都怎么问这篇文章后我自己的一些思考。
这两个问题要放在一起解释。为什么要mask?因为想构造双向模型。换句话说,是因为想做双向,所以才需要mask。为什么呢?下面先解释以下,如何体现双向。
双向是因为可以从左往右,也可以从右往左进行学习。像transformer的encoder其实也是如此,self-attention就是双向的。既然self-attention是双向的,为什么需要mask呢?
- 为什么transformer没有mask呢?因为Bert只有encoder部分,没有decoder;与transformer的任务不同。
- 可以像word2vec的CBOW一样用上下文预测中间的词吗?我认为也是不行的,因为word2vec其实不是深层网络,而Bert是深层;正如论文中说到的多层的网络结构会暴露预测词,失去学习的意义。另外,这里Bert用的是整句话作为输入,而不是滑动窗口内的上下文。
Unfortunately, standard conditional language models can only be trained left-to-right or right-to-left, since bidirectional conditioning would allow each word to indirectly “see itself”, and the model could trivially predict the target word in a multi-layered context.
因此,为了让bert是双向的,提出mask LM避免深层的双向网络模型泄漏target。
怎么做的mask?为什么要这么做?
随机mask掉每个序列所有token的15%,并且只预测mask的token,其他词不预测。但是,在fine-tuning时根本不会有mask出现,因此为了解决这个问题,实际在训练中的做法,在这选中的15%token中:
- 80%被mask
- 10%被替换成其他token
- 10%不变
这样做也带来了其他好处或者缺点:
- 好处: 预测一个词汇时,模型并不知道输入对应位置的词汇是否为正确的词汇( 10% 概率),这就迫使模型更多地依赖于上下文信息去预测词汇,并且赋予了模型一定的纠错能力。
- 缺点:每批次数据中只有 15% 的标记被预测,这意味着模型可能需要更多的预训练步骤来收敛。
标注的mask会被attention吗?
attention不区分mask和其他字符,因此mask也是一起attention
关于layer normalization
MLM和NSP是同时训练还是分开训练?损失函数如何表示的?
MLM和NSP相当于是multi-task一起训练,总体的损失函数=MLM损失函数+NSP损失函数。从下图可以看出,输入与Bert主体结果是共享的,只是在输出层根据各自任务进行预测。
另外,NSP任务也是随机选择50%的数据作为下一句当作负样本,50%保持原数据为正样本。
如何做下游任务?
针对句子语义相似度的任务bert fine tuning classification
实际操作时,最后一句话之后还会加一个[SEP] token,语义相似度任务将两个句子按照上述方式输入即可,之后与论文中的分类任务一样,将[CLS] token 位置对应的输出,接上 softmax 做分类即可(实际上 GLUE 任务中就有很多语义相似度的数据集)。
针对多标签分类的任务
多标签分类任务,即 MultiLabel,指的是一个样本可能同时属于多个类,即有多个标签。以商品为例,一件 L 尺寸的棉服,则该样本就有至少两个标签——型号:L,类型:冬装。
对于多标签分类任务,显而易见的朴素做法就是不管样本属于几个类,就给它训练几个分类模型即可,然后再一一判断在该类别中,其属于那个子类别,但是这样做未免太暴力了,而多标签分类任务,其实是可以「只用一个模型」来解决的。
利用 BERT 模型解决多标签分类问题时,其输入与普通单标签分类问题一致,得到其 embedding 表示之后(也就是 BERT 输出层的 embedding),有几个 label 就连接到几个全连接层(也可以称为 projection layer),然后再分别接上 softmax 分类层,这样的话会得到不同的loss,最后再将所有的 loss 相加起来即可。这种做法就相当于将 n 个分类模型的特征提取层参数共享,得到一个共享的表示(其维度可以视任务而定,由于是多标签分类任务,因此其维度可以适当增大一些),最后再做多标签分类任务。
针对翻译的任务
针对翻译的任务,我自己想到一种做法,因为 BERT 本身会产生 embedding 这样的“副产品”,因此可以直接利用 BERT 输出层得到的 embedding,然后在做机器翻译任务时,将其作为输入/输出的 embedding 表示,这样做的话,可能会遇到 UNK 的问题,为了解决 UNK 的问题,可以将得到的词向量 embedding 拼接字向量的 embedding 得到输入/输出的表示(对应到英文就是 token embedding 拼接经过 charcnn 的 embedding 的表示)。
针对文本生成的任务
关于生成任务,在Bert论文中没有提及。搜到以下几篇论文:
BERT has a Mouth, and It Must Speak: BERT as a Markov Random Field Language Model[2]
MASS: Masked Sequence to Sequence Pre-training for Language Generation[3]
Unified Language Model Pre-training for Natural Language Understanding and Generation[4]
其他问题
Bert如何解决一词多义?
提出结合上下文的动态表征,如ELMO、GPT、BERT基于语言模型的表征。
我的理解应该是不仅仅考虑了token信息,而且考虑了position,segment等信息,结合上下文最终得到一个token表示向量。
ELMO 的本质思想是:我事先用语言模型学好一个单词的 Word Embedding,此时多义词无法区 分,不过这没关系。在我实际使用 Word Embedding 的时候,单词已经具备了特定的 上下文了,这个时候我可以根据上下文单词的语义去调整单词的 Word Embedding 表 示,这样经过调整后的 Word Embedding 更能表达在这个上下文中的具体含义,自然 也就解决了多义词的问题了。所以 ELMO 本身是个根据当前上下文对 Word Embedding 动态调整的思路。
与GPT的区别是什么?
- 语言模型: Bert和GPT-2虽然都采用transformer,但是Bert使用的是transformer的encoder,即:Self Attention,是双向的语言模型;而GPT-2用的是transformer中去掉中间Encoder-Decoder Attention层的decoder,即:Masked Self Attention,是单向语言模型。
- 结构: Bert是pre-training + fine-tuning的结构;而GPT-2只有pre-training
- 输入向量:GPT-2是token embedding + prosition embedding;Bert是 token embedding + position embedding + segment embedding。
- 参数量:Bert是3亿参数量;而GPT-2是15亿参数量。
- 训练任务:Bert引入Masked LM和Next Sentence Prediction;而GPT-2只是单纯的用单向语言模型进行训练,没引入这两个。