NLP学习之BERT

bert的双向体现在?
mask+attention,mask的word结合全部其他encoder word的信息。
Bert的是怎样实现mask构造的?
MLM:将完整句子中的部分字mask,预测该mask词
NSP:为每个训练前的例子选择句子 A 和 B 时,50% 的情况下 B 是真的在 A 后面的下一个句子, 50% 的情况下是来自语料库的随机句子,进行二分预测是否为真实下一句。
在数据中随机选择 15% 的标记,其中80%被换位[mask],10%不变、10%随机替换其他单词,这样做的原因是什么?
mask只会出现在构造句子中,当真实场景下是不会出现mask的,全mask不match句型了
随机替换也帮助训练修正了[unused]和[UNK]
强迫文本记忆上下文信息
为什么BERT有3个嵌入层,它们都是如何实现的?
input_id是语义表达,和传统的w2v一样,方法也一样的lookup
segment_id是辅助BERT区别句子对中的两个句子的向量表示,从[1,embedding_size]里面lookup
position_id是为了获取文本天生的有序信息,否则就和传统词袋模型一样了,从[511,embedding_size]里面lookup
bert的损失函数?
MLM:在 encoder 的输出上添加一个分类层,用嵌入矩阵乘以输出向量,将其转换为词汇的维度,用 softmax 计算mask中每个单词的概率
NSP:用一个简单的分类层将 [CLS] 标记的输出变换为 2×1 形状的向量,用 softmax 计算 IsNextSequence 的概率
MLM+NSP即为最后的损失
长文本预测如何构造Tokens?
head-only:保存前 510 个 token (留两个位置给 [CLS] 和 [SEP] )
tail-only:保存最后 510 个token
head + tail :选择前128个 token 和最后382个 token(文本在800以内)或者前256个token+后254个token(文本大于800tokens)
知道分词模块:FullTokenizer做了哪些事情么?
BasicTokenizer:根据空格等进行普通的分词,包括了一些预处理的方法:去除无意义词,跳过’\t’这些词,unicode变换,中文字符筛选等等。
WordpieceTokenizer:前者的结果再细粒度的切分为WordPiece,中文不处理,因为有词缀一说:解决OOV。
Bert中如何获得词意和句意?
get_pooled_out代表了涵盖了整条语句的信息
get_sentence_out代表了这个获取每个token的output 输出,用的是cls向量
源码中Attention后实际的流程是如何的?
Transform模块中:在残差连接之前,对output_layer进行了dense+dropout后再合并input_layer进行的layer_norm得到的attention_output
所有attention_output得到并合并后,也是先进行了全连接,而后再进行了dense+dropout再合并的attention_output之后才进行layer_norm得到最终的layer_output.
为什么要在Attention后使用残差结构?
残差结构能够很好的消除层数加深所带来的信息损失问题.
你觉得BERT比普通LM的新颖点?
mask机制
next_sentence_predict机制
elmo、GPT、bert三者之间有什么区别?
特征提取器:elmo采用LSTM进行提取,GPT和bert则采用Transformer进行提取。很多任务表明Transformer特征提取能力强于LSTM,elmo采用1层静态向量+2层LSTM,多层提取能力有限,而GPT和bert中的Transformer可采用多层,并行计算能力强。
单/双向语言模型:GPT采用单向语言模型,elmo和bert采用双向语言模型。但是elmo实际上是两个单向语言模型(方向相反)的拼接,这种融合特征的能力比bert一体化融合特征方式弱。
GPT和bert都采用Transformer,Transformer是encoder-decoder结构,GPT的单向语言模型采用decoder部分,decoder的部分见到的都是不完整的句子;bert的双向语言模型则采用encoder部分,采用了完整句子
bert的词向量维度?
768
bert的具体网络结构,以及训练过程,bert为什么火,它在什么的基础上改进了些什么?
bert是用了transformer的encoder侧的网络,作为一个文本编码器,使用大规模数据进行预训练,预训练使用两个loss,一个是mask LM,遮蔽掉源端的一些字(可能会被问到mask的具体做法,15%概率mask词,这其中80%用[mask]替换,10%随机替换一个其他字,10%不替换,至于为什么这么做,那就得问问BERT的作者了{捂脸}),然后根据上下文去预测这些字,一个是next sentence,判断两个句子是否在文章中互为上下句,然后使用了大规模的语料去预训练。在它之前是GPT,GPT是一个单向语言模型的预训练过程(它和gpt的区别就是bert为啥叫双向 bi-directional),更适用于文本生成,通过前文去预测当前的字。下图为transformer的结构,bert的网络结构则用了左边的encoder。
NLP学习之BERT_第1张图片
讲讲multi-head attention的具体结构?
BERT由12层transformer layer(encoder端)构成,首先word emb , pos emb(可能会被问到有哪几种position embedding的方式,bert是使用的哪种), sent emb做加和作为网络输入,每层由一个multi-head attention, 一个feed forward 以及两层layerNorm构成,一般会被问到multi-head attention的结构,具体可以描述为,
step1

一个768的hidden向量,被映射成query, key, value。 然后三个向量分别切分成12个小的64维的向量,每一组小向量之间做attention。不妨假设batch_size为32,seqlen为512,隐层维度为768,12个head

hidden(32 x 512 x 768) -> query(32 x 512 x 768) -> 32 x 12 x 512 x 64

hidden(32 x 512 x 768) -> key(32 x 512 x 768) -> 32 x 12 x 512 x 64

hidden(32 x 512 x 768) -> val(32 x 512 x 768) -> 32 x 12 x 512 x 64
step2

然后query和key之间做attention,得到一个32 x 12 x 512 x 512的权重矩阵,然后根据这个权重矩阵加权value中切分好的向量,得到一个32 x 12 x 512 x 64 的向量,拉平输出为768向量。

32 x 12 x 512 x 64(query_hidden) * 32 x 12 x 64 x 512(key_hidden) -> 32 x 12 x 512 x 512

32 x 12 x 64 x 512(value_hidden) * 32 x 12 x 512 x 512 (权重矩阵) -> 32 x 12 x 512 x 64

然后再还原成 -> 32 x 512 x 768

简言之是12个头,每个头都是一个64维度分别去与其他的所有位置的hidden embedding做attention然后再合并还原。
Bert 采用哪种Normalization结构,LayerNorm和BatchNorm区别,LayerNorm结构有参数吗,参数的作用?
采用LayerNorm结构,和BatchNorm的区别主要是做规范化的维度不同,BatchNorm针对一个batch里面的数据进行规范化,针对单个神经元进行,比如batch里面有64个样本,那么规范化输入的这64个样本各自经过这个神经元后的值(64维),LayerNorm则是针对单个样本,不依赖于其他数据,常被用于小mini-batch场景、动态网络场景和 RNN,特别是自然语言处理领域,就bert来说就是对每层输出的隐层向量(768维)做规范化,图像领域用BN比较多的原因是因为每一个卷积核的参数在不同位置的神经元当中是共享的,因此也应该被一起规范化。

class BertLayerNorm(nn.Module):
    def __init__(self, hidden_size, eps=1e-5):
        super(BertLayerNorm, self).__init__()
        self.weight = nn.Parameter(torch.ones(hidden_size))
        self.bias = nn.Parameter(torch.zeros(hidden_size))
        self.variance_epsilon = eps

    def forward(self, x):
        u = x.mean(-1, keepdim=True)
        s = (x - u).pow(2).mean(-1, keepdim=True)
        x = (x - u) / torch.sqrt(s + self.variance_epsilon)
        return self.weight * x + self.bias

贴一个LayerNorm的实现,可以看到module中有weight和bias参数,以Sigmoid激活函数为例,批量归一化之后数据整体处于函数的非饱和区域, 只包含线性变换,破坏了之前学习到的特征分布。为了恢复原始数据分布,具体实现中引入了变换重构以及可学习参数w和b ,也就是上面的weight和bias,简而言之,规范化后的隐层表示将输入数据限制到了一个全局统一的确定范围,为了保证模型的表达能力不因为规范化而下降,引入了[公式]是再平移参数,[公式]是再缩放参数。(过激活函数前规范化,之后还原)。
transformer attention的时候为啥要除以根号D?
至于attention后的权重为啥要除以 根号dk,作者在论文中的解释是点积后的结果大小是跟维度成正比的,所以经过softmax以后,梯度就会变很小,除以根号dk后可以让attention的权重分布方差为1,而不是dk。
wordpiece的作用
wordpiece其核心思想是将单词打散为字符,然后根据片段的组合频率,最后单词切分成片段处理。和原有的分词相比,能够极大的降低OOV的情况,例如cosplayer, 使用分词的话如果出现频率较低则是UNK,但bpe可以把它切分吃cos play er, 模型可以词根以及前缀等信息,学习到这个词的大致信息,而不是一个OOV。
wordpiece与BPE(Byte Pair Encoding)算法类似,也是每次从词表中选出两个子词合并成新的子词。与BPE的最大区别在于,如何选择两个子词进行合并:BPE选择频数最高的相邻子词合并,而WordPiece选择能够提升语言模型概率最大的相邻子词加入词表。
如何优化BERT效果?
1 感觉最有效的方式还是数据。
2 把现有的大模型ERNIE_2.0_large, Roberta,roberta_wwm_ext_large、roberta-pair-large等进行ensemble,然后蒸馏原始的bert模型,这是能有效提高的,只是操作代价比较大。
3 BERT上面加一些网络结构,比如attention,rcnn等,个人得到的结果感觉和直接在上面加一层transformer layer的效果差不多,模型更加复杂,效果略好,计算时间略增加。
4 改进预训练,在特定的大规模数据上预训练,相比于开源的用百科,知道等数据训练的更适合你的任务(经过多方验证是一种比较有效的提升方案)。以及在预训练的时候去mask低频词或者实体词(听说过有人这么做有收益,但没具体验证)。
5 文本对抗。
如何优化BERT性能?
1 压缩层数,然后蒸馏,直接复用12层bert的前4层或者前6层,效果能和12层基本持平,如果不蒸馏会差一些。
2 双塔模型(短文本匹配任务),将bert作为一个encoder,输入query编码成向量,输入title编码成向量,最后加一个DNN网络计算打分即可。离线缓存编码后的向量,在线计算只需要计算DNN网络。
3 int8预估,在保证模型精度的前提下,将Float32的模型转换成Int8的模型。
4 提前结束,大致思想是简单的case前面几层就可以输出分类结果,比较难区分的case走完12层,但这个在batch里面计算应该怎么优化还没看明白,有的提前结束有的最后结束,如果在一个batch里面的话就不太好弄。
5 ALBERT 做了一些改进优化,主要是不同层之间共享参数,以及用矩阵分解降低embedding的参数。
self-attention相比lstm优点是什么?
bert通过使用self-attention + position embedding对序列进行编码,lstm的计算过程是从左到右从上到下(如果是多层lstm的话),后一个时间节点的emb需要等前面的算完,而bert这种方式相当于并行计算,虽然模型复杂了很多,速度其实差不多。
BERT的一些改进?
ERNIE_1.0(baidu) : 模型结构不变,预训练的时候第一阶段基于切词mask,第二阶段基于实体mask,让模型在预训练的过程中根据上下文去学到一些词级别,实体级别,短语级别的信息。
ERNIE_2.0:模型结构加入task embedding(作者将预训练任务分为:Word-aware, Structure-aware,Semantic-aware),不同类型的任务选取不同的task embedding,然后加了很多预训练任务,很多数据。
ALBERT
Factorized Embedding Parameterization,矩阵分解降低embedding参数量。
Cross-layer Parameter Sharing,不同层之间共享参数。
Sentence Order Prediction(SOP),next sentence任务的负样本增强。
个人感觉降低参数量相对于优化效果以及计算速度来说,并不是特别重要。

你可能感兴趣的:(NLP)