自然语言处理(NLP)精选13道面试题

文末彩蛋:七月在线干货组最新升级的《名企AI面试100题》免费送!

1、为什么BERT在第一句前会加一个[CLS]标志?

BERT在第一句前会加一个[CLS]标志,最后一层该位对应向量可以作为整句话的语义表示,从而用于下游的分类任务等。

为什么选它呢,因为与文本中已有的其它词相比,这个无明显语义信息的符号会更“公平”地融合文本中各个词的语义信息,从而更好的表示整句话的语义。

具体来说,self-attention 是用文本中的其它词来增强目标词的语义表示,但是目标词本身的语义还是会占主要部分的,因此,经过 BERT 的12层,每次词的 embedding 融合了所有词的信息,可以去更好的表示自己的语义。

而 [CLS] 位本身没有语义,经过12层,得到的是 attention 后所有词的加权平均,相比其他正常词,可以更好的表征句子语义。

当然,也可以通过对最后一层所有词的 embedding 做 pooling 去表征句子语义。

这里补充一下bert的输出,有两种,在BERT TF源码中对应:

一种是get_pooled_out(),就是上述[CLS]的表示,输出shape是[batch size,hidden size]。

一种是get_sequence_out(),获取的是整个句子每一个token的向量表示,输出shape是[batch_size, seq_length, hidden_size],这里也包括[CLS],因此在做 token 级别的任务时要注意它。

2、BERT的三个Embedding直接相加会对语义有影响吗?

这是一个非常有意思的问题,苏剑林老师也给出了回答,真的很妙:

Embedding的数学本质,就是以one hot为输入的单层全连接。

也就是说,世界上本没什么Embedding,有的只是one hot。

可参考:
https://kexue.fm/archives/4122

在这里想用一个例子再尝试解释一下:

假设 token Embedding 矩阵维度是 [4,768];position Embedding 矩阵维度是 [3,768];segment Embedding 矩阵维度是 [2,768]。

对于一个字,假设它的 token one-hot 是[1,0,0,0];它的 position one-hot 是[1,0,0];它的 segment one-hot 是[1,0]。

那这个字最后的 word Embedding,就是上面三种 Embedding 的加和。

如此得到的 word Embedding,和concat后的特征:[1,0,0,0,1,0,0,1,0],再过维度为 [4+3+2,768] = [9, 768] 的全连接层,得到的向量其实就是一样的。

再换一个角度理解:

直接将三个one-hot 特征 concat 起来得到的 [1,0,0,0,1,0,0,1,0] 不再是one-hot了,但可以把它映射到三个one-hot 组成的特征空间,空间维度是 432=24 ,那在新的特征空间,这个字的one-hot就是[1,0,0,0,0…] (23个0)。

此时,Embedding 矩阵维度就是 [24,768],最后得到的 word Embedding 依然是和上面的等效,但是三个小Embedding 矩阵的大小会远小于新特征空间对应的Embedding 矩阵大小。

当然,在相同初始化方法前提下,两种方式得到的 word Embedding 可能方差会有差别,但是,BERT还有Layer Norm,会把 Embedding 结果统一到相同的分布。

BERT的三个Embedding相加,本质可以看作一个特征的融合,强大如 BERT 应该可以学到融合后特征的语义信息的。

3、在BERT中,token分3种情况做mask,分别的作用是什么?

在 BERT 的 Masked LM 训练任务中, 会用 [MASK] token 去替换语料中 15% 的词,然后在最后一层预测。但是下游任务中不会出现 [MASK] token,导致预训练和 fine-tune 出现了不一致,为了减弱不一致性给模型带来的影响,在这被替换的 15% 语料中:

  1. 80% 的 tokens 会被替换为 [MASK] token

  2. 10% 的 tokens 会称替换为随机的 token

  3. 10% 的 tokens 会保持不变但需要被预测

第一点中的替换:是 Masked LM 中的主要部分,可以在不泄露 label 的情况下融合真双向语义信息;

第二点的随机替换:因为需要在最后一层随机替换的这个 token 位去预测它真实的词,而模型并不知道这个 token 位是被随机替换的,就迫使模型尽量在每一个词上都学习到一个 全局语境下的表征,因而也能够让 BERT 获得更好的语境相关的词向量(这正是解决一词多义的最重要特性);

第三点的保持不变:也就是真的有 10% 的情况下是 泄密的(占所有词的比例为15% * 10% = 1.5%),这样能够给模型一定的 bias ,相当于是额外的奖励,将模型对于词的表征能够拉向词的 真实表征(此时输入层是待预测词的真实 embedding,在输出层中的该词位置得到的embedding,是经过层层 Self-attention 后得到的,这部分 embedding 里多少依然保留有部分输入 embedding 的信息,而这部分就是通过输入一定比例的真实词所带来的额外奖励,最终会使得模型的输出向量朝输入层的真实 embedding 有一个 偏移)。

而如果全用 mask 的话,模型只需要保证输出层的分类准确,对于输出层的向量表征并不关心,因此 可能会导致最终的向量输出效果并不好。

4、为什么BERT选择mask掉15%这个比例的词,可以是其他的比例吗?

BERT采用的Masked LM,会选取语料中所有词的15%进行随机mask,论文中表示是受到完形填空任务的启发,但其实与CBOW也有异曲同工之妙。

从CBOW的角度,这里 有一个比较好的解释是:在一个大小为 1/p = 100/15 约等于 7 的窗口中随机选一个词,类似CBOW中滑动窗口的中心词,区别是这里的滑动窗口是非重叠的。

那从CBOW的滑动窗口角度,10%~20%都是还ok的比例。

5、针对句子语义相似度/多标签分类/机器翻译翻译/文本生成的任务,利用BERT结构怎么做fine-tuning?

实际操作时,上述最后一句话之后还会加一个[SEP] token,语义相似度任务将两个句子按照上述方式输入即可,之后与论文中的分类任务一样,将[CLS] token 位置对应的输出,接上 softmax 做分类即可(实际上 GLUE 任务中就有很多语义相似度的数据集)。 针对多标签分类的任务 多标签分类任务,即 MultiLabel,指的是一个样本可能同时属于多个类,即有多个标签。以商品为例,一件 L 尺寸的棉服,则该样本就有至少两个标签——型号:L,类型:冬装。

对于多标签分类任务,显而易见的朴素做法就是不管样本属于几个类,就给它训练几个分类模型即可,然后再一一判断在该类别中,其属于那个子类别,但是这样做未免太暴力了,而多标签分类任务,其实是可以「只用一个模型」来解决的。

利用 BERT 模型解决多标签分类问题时,其输入与普通单标签分类问题一致,得到其 embedding 表示之后(也就是 BERT 输出层的 embedding),有几个 label 就连接到几个全连接层(也可以称为 projection layer),然后再分别接上 softmax 分类层,这样的话会得到 ,最后再将所有的 loss 相加起来即可。这种做法就相当于将 n 个分类模型的特征提取层参数共享,得到一个共享的表示(其维度可以视任务而定,由于是多标签分类任务,因此其维度可以适当增大一些),最后再做多标签分类任务。 针对翻译的任务 针对翻译的任务,我自己想到一种做法,因为 BERT 本身会产生 embedding 这样的“副产品”,因此可以直接利用 BERT 输出层得到的 embedding,然后在做机器翻译任务时,将其作为输入/输出的 embedding 表示,这样做的话,可能会遇到 UNK 的问题,为了解决 UNK 的问题,可以将得到的词向量 embedding 拼接字向量的 embedding 得到输入/输出的表示(对应到英文就是 token embedding 拼接经过 charcnn 的 embedding 的表示)。 针对文本生成的任务 关于生成任务,搜到以下几篇论文:

BERT has a Mouth, and It Must Speak: BERT as a Markov Random Field Language Model

MASS: Masked Sequence to Sequence Pre-training for Language Generation

Unified Language Model Pre-training for Natural Language Understanding and Generation

6、使用BERT预训练模型为什么最多只能输入512个词,最多只能两个句子合成一句? 这是Google BERT预训练模型初始设置的原因,前者对应Position Embeddings,后者对应Segment Embeddings

在BERT中,Token,Position,Segment Embeddings 都是通过学习来得到的,pytorch代码中它们是这样的

自然语言处理(NLP)精选13道面试题_第1张图片
self.word_embeddings = Embedding(config.vocab_size, config.hidden_size)

self.position_embeddings = Embedding(config.max_position_embeddings, config.hidden_size)

self.token_type_embeddings = Embedding(config.type_vocab_size, config.hidden_size)上述BERT pytorch代码来自:https://github.com/xieyufei1993/Bert-Pytorch-Chinese-TextClassification,结构层次非常清晰。

而在BERT config中

“max_position_embeddings”: 512

“type_vocab_size”: 2

因此,在直接使用Google 的BERT预训练模型时,输入最多512个词(还要除掉[CLS]和[SEP]),最多两个句子合成一句。这之外的词和句子会没有对应的embedding。

当然,如果有足够的硬件资源自己重新训练BERT,可以更改 BERT config,设置更大max_position_embeddings 和 type_vocab_size值去满足自己的需求。

7、BERT非线性的来源在哪里?

前馈层的gelu激活函数和self-attention,self-attention是非线性的

8、BERT 是如何区分一词多义的?

同一个字在转换为bert的输入之后(id),embedding的向量是一样,但是通过bert中的多层transformer encoder之后,attention关注不同的上下文,就会导致不同句子输入到bert之后,相同字输出的字向量是不同的,这样就解决了一词多义的问题。

9、BERT的输入是什么,哪些是必须的,为什么position id不用给?

BERT的输入:token embedding,position embeddinhg,segment embedding token embedding:词向量表示 ,该向量既可以随机初始化,也可以利用Word2Vector等算法进行预训练以作为初始值,使用WordPiece tokenization让BERT在处理英文文本的时候仅需要存储30,522 个词,而且很少遇到oov的词,token embedding是必须的; position embeddinhg:和Transformer的sin、cos函数编码不同,直接去训练了一个position embedding。给每个位置词一个随机初始化的词向量,再训练; segment embedding:该向量的取值在模型训练过程中自动学习,用于刻画文本的全局语义信息,并与单字/词的语义信息相融合。 输出是文本中各个字/词融合了全文语义信息后的向量表示。 参考:
https://blog.csdn.net/weixin_36378508/article/details/113424992

10、神经网络中 warmup 策略为什么有效 ?

有助于减缓模型在初始阶段对mini-batch的提前过拟合现象,保持分布的平稳有助于保持模型深层的稳定性

11、Bert 采用哪种Normalization结构,LayerNorm和BatchNorm区别,LayerNorm结构有参数吗,参数的作用?

采用LayerNorm结构,和BatchNorm的区别主要是做规范化的维度不同。 BatchNorm针对一个batch里面的数据进行规范化,针对单个神经元进行,比如batch里面有64个样本,那么规范化输入的这64个样本各自经过这个神经元后的值(64维); LayerNorm则是针对单个样本,不依赖于其他数据,常被用于小mini-batch场景、动态网络场景和 RNN,特别是自然语言处理领域,就bert来说就是对每层输出的隐层向量(768维)做规范化,图像领域用BN比较多的原因是因为每一个卷积核的参数在不同位置的神经元当中是共享的,因此也应该被一起规范化。
自然语言处理(NLP)精选13道面试题_第2张图片

return self.weight * x + self.bias贴一个LayerNorm的实现,可以看到module中有weight和bias参数,以Sigmoid激活函数为例,批量归一化之后数据整体处于函数的非饱和区域, 只包含线性变换,破坏了之前学习到的特征分布。为了恢复原始数据分布,具体实现中引入了变换重构以及可学习参数w和b ,也就是上面的weight和bias,简而言之,规范化后的隐层表示将输入数据限制到了一个全局统一的确定范围,为了保证模型的表达能力不因为规范化而下降,引入了b是再平移参数,w 是再缩放参数。(过激活函数前规范化,之后还原)

12、为什么说ELMO是伪双向,BERT是真双向?产生这种差异的原因是什么?

elmo是伪双向,只是将左到右,右到左的信息加起来,而且用的是lstm,同时缺点也是显而易见的,模型参数太多,而且模型太大,少量数据训练时,容易过拟合。

BERT的预训练模型中,预训练任务是一个mask LM ,通过随机的把句子中的单词替换成mask标签, 然后对单词进行预测。

13、BERT和Transformer Encoder的差异有哪些?做出这些差异化的目的是什么?

与Transformer本身的Encoder端相比,BERT的Transformer Encoder端输入的向量表示,多了Segment Embeddings。 加入Segment Embeddings的原因:Bert会处理句对分类、问答等任务,这里会出现句对关系,而两个句子是有先后顺序关系的,如果不考虑,就会出现词袋子之类的问题(如:武松打虎 和 虎打武松 是一个意思了~),因此Bert加入了句子向量。

评论有奖:评论区回复“100题”,免费领取最新升级版《名企AI面试100题》电子书!

你可能感兴趣的:(人工智能,机器学习,自然语言处理,nlp,面试)