• Bert相关面试题整理


    论文阅读

    Transformer

    李沐视频整理
    论文地址:https://arxiv.org/abs/1706.03762
    在这里插入图片描述

    1 模型结构

    编码器-解码器结构,解码器中词一个一个生成,并且输出长度可以和输入长度不同,AR(自回归)
    编码器包括6个相同层,每层有两个子层,一个是多头自注意力层和一个前馈神经网络,这两个层之间用残差网络+LayNorm。

    2.注意力
    3.2.1 Scaled dot-product attention

    A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dk QKT)V
    Q和K都是dk维的向量,两个向量做内积(基本就是看相似度),V是dv维的向量,自注意做完的向量也是dv维的
    一般有两种注意力机制:加性的(可以处理QK维数不同的情况)和点积的,因为实现起来比较高效。
    除以dk的原因,当dk很大的时候,方差很大,做softmax的时候会导致梯度消失

    3.2.2 多头注意力机制

    多头的实现:
    QKV进入线性层,投影成低维向量再经过一个Scaled dot-product attention,然后拼接成一个矩阵,通过一个线性层输出

    3.2.3注意力机制在模型中的应用

    三个自注意力层
    1.编码器的自注意力层
    输入:Q,K,V(自己本身)
    输出:V的一些加权和(非线性),权重来源于Q和K
    2.解码器的masked 多头自注意力层
    mask掉后面的向量,只关注当前位置之前的向量,具体做法是将后面的向量在softmax之前都变成负无穷的数(例如-1e10,softmax的结果为0)
    3.解码器的多头注意力机制
    输入:V,K来源于编码器的输出,Q来源于解码器刚刚的输出
    目的:从编码器提取有效的信息

    3.3 FFN(前馈网络)

    全连接前馈神经网络:两个线性层+RELU
    独立做MLP,因为attention已经抓取了整个句子的语义信息

    3.4 Embedding和softmax
    3.5 Positional Encoding

    在输入的时候加进位置信息,具体用三角函数

    4.为什么用自注意力机制

    是序列长度,维度是d
    在这里插入图片描述
    自注意力的复杂度O(n2*d)

    5.实验

    Transformer实验用的BPE(byte-pair encoding)
    训练器Adam
    正则化:dropout,label smoothing

    BERT

    1.摘要

    双向

    2.模型

    多层双向编码器,只调了三个参数:transformer块个数,隐藏层大小和自注意层多头的头数

    可以通过可学习参数个数来复习transformer的结构
    输入表示
    切词方法:wordpiece 30k的词典
    [CLS]代表整个句子的语义
    输入三个向量:token embedding、segment embedding、postion embedding(和transformer静态的不同)相加的向量

    3.1 预训练

    预训练两个很重要:目标函数和训练数据
    任务一:Masked LM(掩码的语言模型)
    如果一个词元是由wordpiece生成的,它有15%的概率会被随机替换成一个掩码
    带来的问题:微调的时候没有[MASK]这个标签会导致微调和预训练的不匹配
    改进:这15%的词里有80%的替换成[MASK],有10%换成其他词元,还有10%保持不变(目的:bias the represention towards the actual observed word,使表示偏向实际观察到的单词)
    任务二:Next Sentence Prediction
    50%的句子相邻,还有一半后一句被替换
    训练数据:BOOKCORPUS和WIKIPIEDIE

    3.2 微调

    跟encoder-decoder的不同:可以看到源端和目标端的关系
    [CLS]做分类或者隐层表示

    3.实验

    不同任务上的结果

    面试题汇总

    1. transformer架构

    当我们对每个位置的token都有一个hidden_size大小的embedding之后,把这个序列输入到Transformer中。由以下的代码可以知道,每层Transformer都先计算multi-head self-attention,之后的结果再经过dropout, residual connection, layernorm, 还有feed-forward network。
    在这里插入图片描述
    问题:

    1.1.FFN(前馈神经网络)的作用

    提供非线性变换的单元。
    QKV矩阵都是经过输入和对应的W_q 、W_v、W_v 矩阵相乘得到,中间没有经过激活函数,QK用于计算self-attention 的权重,self-attention模块的输出是对 V 的权重加和,还是线性变换。之后的多个self-attention输出的拼接,拼接后经过一个全连接层(无激活函数),所以经过Multi-head attention 层都是没有经过非线性变换。在之后的FFN中,共有两个全连接层,其中第一个全连接层有激活函数。

    1.2.GELU的原理,相比RELU的缺点

    ReLU会确定性的将输入乘上一个0或者1(当x<0时乘上0,否则乘上1),Dropout则是随机乘上0。而GELU虽然也是将输入乘上0或1,但是输入到底是乘以0还是1,是在取决于输入自身的情况下随机选择的。
    所以,GELU的优点就是在ReLU上增加随机因素,x越小越容易被mask掉。

    1.3为什么用LN,不用BN

    BN公式:
    B N ( x i ) = α ∗ x i − μ b ( σ b 2 + ϵ ) + β BN(x_i)=\alpha*\frac{x_i-\mu_b}{\sqrt(\sigma^2_b+ \epsilon)}+\beta BN(xi)=α( σb2+ϵ)xiμb+β
    LN公式:
    B N ( x i ) = α ∗ x i − μ L ( σ L 2 + ϵ ) + β BN(x_i)=\alpha*\frac{x_i-\mu_L}{\sqrt(\sigma^2_L+ \epsilon)}+\beta BN(xi)=α( σL2+ϵ)xiμL+β
    Batch normalization — 为每一个小batch计算每一层的平均值和方差
    Layer normalization — 独立计算每一层每一个样本的均值和方差
    对于RNN来说,sequence的长度不一致,很多padding表示无意义的信息,如果用BN会导致有意义的embedding损失信息,所以,BN一般用于CNN,而LN用于RNN。
    layernorm是在hidden size的维度进行的,跟batch和seq_len无关。每个hidden state都计算自己的均值和方差,这是因为不同hidden state的量纲不一样。beta和gamma的维度都是(hidden_size,),经过白化的hidden state * beta + gamma得到最后的结果。

    1.4LN在bert的哪个位置

    embedding层结束,self_attention层结束(后置LN层)或self_attention层前面(前置LN层),FFN层结束(后置LN层)或FFN层前面(前置LN层)

    1.5.bert的归一化作用

    LN在BERT中起白化的作用,增强模型稳定性,如果删除则无法收敛

    1.6.残差连接作用

    transformer堆叠很多层,减缓梯度消失
    (深度学习依靠误差的链式反向传播来进行参数更新,它有隐患,一旦其中某一个导数很小,多次连乘后梯度可能越来越小,这就是常说的梯度消散,对于深层网络,传到浅层几乎就没了。但是如果使用了残差,每一个导数就加上了一个恒等项1,dh/dx=d(f+x)/dx=1+df/dx。此时就算原来的导数df/dx很小,这时候误差仍然能够有效的反向传播,这就是核心思想。)

    2.多头

    具体实现(字节)

    如果是单头只要对每个位置的embedding对应Q,K,V三个向量,这三个向量分别是embedding点乘W_Q,W_K,W_V得来的,每个位置的Q向量去乘上所有位置的K向量,其结果经过softmax变成attetion score,以此为权重对V向量做加权求和即可。
    A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T / ( d k ) ) V Attention(Q,K,V)=softmax(QK^T/\sqrt(d_k))V Attention(Q,K,V)=softmax(QKT/( dk))V
    如果是多头,要先去切头再分别进行Scaled Dot-Product 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然后再合并还原。

    问题
    2.1.attention为什么要除以 ( d k ) \sqrt(d_k) ( dk)?(字节)为什么是根号dk,dk是谁的维度

    作者在论文中的解释是点积后的结果大小是跟维度成正比的,所以经过softmax以后,梯度就会变很小,除以 ( d k ) \sqrt(d_k) ( dk) 后可以让attention的权重分布方差为1,而不是 d k d_k dk。当输入信息的维度 d 比较高,会导致 softmax 函数接近饱和区,梯度会比较小。因此,缩放点积模型可以较好地解决这一问题。就是对向量长度做归一化,防止方差过大。
    Q和K都是dk维的向量,假设向量 q 和 k的各个分量是互相独立的随机变量,均值是0,方差是1,那么点积 q*k 的均值是0,方差是 ( d k ) \sqrt(d_k) ( dk),在相乘时引入一次对所有位置的求和,整体的分布就会扩大到 ( d k ) \sqrt(d_k) ( dk)

    2.2 为什么用双线性点积模型,即Q,K两个向量

    双线性点积模型使用Q,K两个向量,而不是只用一个Q向量,这样引入非对称性,更具健壮性(Attention对角元素值不一定是最大的,也就是说当前位置对自身的注意力得分不一定最高)

    2.3.多头机制为什么有效?(为什么用多头)

    类似于CNN中通过多通道机制进行特征选择。Transformer中使用切头(split)的方法,是为了在不增加复杂度( O ( n 2 d ) O(n^2d) O(n2d))的前提下享受类似CNN中“不同卷积核”的优势。
    多头可以使参数矩阵形成多个子空间,有助于捕获到更丰富的信息
    一是多个组可以并行计算,二是不同的组可以捕获不同的子空间的信息。

    2.4.Transformer的非线性来自于哪里?

    FFN的gelu激活函数和self-attention,注意self-attention是非线性的(因为有相乘和softmax)

    3.BERT

    3.1预训练任务
    MLM里如何mask,为什么选10%词不动

    15%token做mask;其中80%用[MASK]替换,10%用random token替换,10%不变
    目的:

    NSP不好

    损失函数:
    L ( θ , θ 1 , θ 2 ) = L 1 ( θ . θ 1 ) + L 2 ( θ , θ 2 ) L(\theta,\theta_1,\theta_2)=L_1(\theta.\theta_1)+L_2(\theta,\theta_2) L(θ,θ1,θ2)=L1(θ.θ1)+L2(θ,θ2)
    L 1 L_1 L1是MLM上的损失函数,如果被mask的词的集合为M,它是一共词典大小为V上的多分类问题:
    L 1 ( θ , θ 1 ) = − ∑ i = 1 M l o g p ( m = m i ∣ θ , θ 1 ) , m i ∈ [ 1 , 2 , . . . , ∣ V ∣ ] L_1(\theta,\theta_1)=-\sum_{i=1}^{M}logp(m=m_i|\theta,\theta_1),m_i\in[1,2,...,|V|] L1(θ,θ1)=i=1Mlogp(m=miθ,θ1),mi[1,2,...,V]
    句子预测任务上,也是一个分类问题的损失函数
    L 2 ( θ , θ 2 ) = − ∑ j = 1 N l o g p ( n = n i ∣ θ , θ 2 ) , n i ∈ [ I s N e x t , N o t N e x t ] L_2(\theta,\theta_2)=-\sum_{j=1}^{N}logp(n=n_i|\theta,\theta_2),n_i\in[IsNext,NotNext] L2(θ,θ2)=j=1Nlogp(n=niθ,θ2),ni[IsNext,NotNext]
    note:分类问题的损失函数

    学习率warm-up策略

    针对学习率的一种优化方式,它在训练开始的时候先选择使用一个较小的学习率,训练了一些epoches或者steps(比如4个epoches,10000steps),再修改为预先设置的学习来进行训练。
    原因:由于刚开始训练时,模型的权重(weights)是随机初始化的,此时若选择一个较大的学习率,可能带来模型的不稳定(振荡),选择Warmup预热学习率的方式,可以使得开始训练的几个epoches或者一些steps内学习率较小,在预热的小学习率下,模型可以慢慢趋于稳定,等模型相对稳定后再选择预先设置的学习率进行训练,使得模型收敛速度变得更快,模型效果更佳。

    训练器Adam
    BERT后续的预训练模型

    (1)Roberta:更大的参数量、训练数据和batch
    预训练加入a.动态掩码(每次向模型输入一个序列时都会生成新的掩码模式。)
    b.去掉NSP。虽然是句子对输入,但其实一个句子不只有一句,而是文章里面的连续片段,可以包含多句。操作:采用去掉NSP而且一个样本是从同一个文档里面进行采样
    BPE编码
    (2)T5:生成式模型首选
    首先,将tokens的输入序列映射到嵌入序列,然后将嵌入序列传递给编码器。该编码器由一堆“块”组成,每个“块”由两个子组件组成:一个自注意层,后面是一个小型前馈网络。对每个子组件的输入进行层归一化。我们使用一种简化版本的层归一化,激活仅做重新缩放,不应用附加偏差。在层归一化之后,残差连接将每个子组件的输入添加到输出。Dropout应用于前馈网络、跳跃连接、注意权重以及整个stack的输入和输出。解码器类似于编码器,除了在每一个自注意层后包括一个标准的注意机制,其连接到编码器的输出。解码器中的自注意机制也使用了一种自回归或因果的自注意形式,它只允许模型关注过去的输出。最终解码器的输出被送入softmax输出层,其权值与输入嵌入矩阵共享。Transformer中的所有注意机制都被分割成独立的“头”,其输出在被进一步处理之前被连接起来。

    self-attention为什么效果很好,LSTM为什么对长文本效果差
    BERT的CLS标志作用

    更公平地融合文本各个词的语义信心,从而更好的表示整句语义

    BERT三个embedding直接相加

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

    BERT、GPT、ELMO的区别

    双向
    ELMO基于双向LSTM学习一共语言模型,通过特征融合将特征输入到任务模型
    GPT基于transformer解码器结构,将单向语言模型作为预训练阶段的目标函数
    BERT的改进点
    (1)真正的双向,ELMO是分别学习上文和下文,GPT只利用上文,而BERT有MLM任务,能很好地学习句子上下文信息
    (2)显式地对句子关系建模,更好地表征句子的语义。具体引入了segment向量和特殊标记

    3.2BERT应用
    语义相似度

    实际操作时,上述最后一句话之后还会加一个[SEP] token,语义相似度任务将两个句子按照上述方式输入即可,之后与论文中的分类任务一样,将[CLS] token位置对应的输出,接上softmax做分类即可(实际上GLUE任务中就有很多语义相似度的数据集)。

    事实上,用BERT做语义相似度任务效果不好,训练出来的词向量相似度很高。如果直接以cosine similariy>0.5之类的阈值来判断相似不相似那肯定效果很差;如果用做排序,也就是cosine(a,b)>cosine(a,c)->b相较于c和a更相似,是可以用的
    评价指标是AUC
    长短文本相似度也有区别:

    • 短文本用先进的embedding技术:fasttext等
    • 长文本用普通的词频算法就可以了
      https://www.cnblogs.com/shona/p/12021304.html
    多标签分类任务

    多标签分类任务,即MultiLabel,指的是一个样本可能同时属于多个类,即有多个标签。以商品为例,一件L尺寸的棉服,则该样本就有至少两个标签——型号:L,类型:冬装。

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

    利用BERT模型解决多标签分类问题时,其输入与普通单标签分类问题一致,得到其embedding表示之后(也就是BERT输出层的embedding),有几个label就连接到几个全连接层(也可以称为projection layer),然后再分别接上softmax分类层,这样的话会得到​ l o s s 1 , l o s s 2 , . . . , l o s s n loss_1,loss_2,...,loss_n loss1,loss2,...,lossn ,最后再将所有的loss相加起来即可。这种做法就相当于将n个分类模型的特征提取层参数共享,得到一个共享的表示(其维度可以视任务而定,由于是多标签分类任务,因此其维度可以适当增大一些),最后再做多标签分类任务。

  • 相关阅读:
    代理模式(Proxy模式)
    tomcat多实例部署jenkins
    [附源码]计算机毕业设计小太阳幼儿园学生管理系统Springboot程序
    前端研习录(17)——JavaScript数据类型讲解及示例分析
    GBRank:一种基于回归的排序方法
    是的,决定放弃算法去机器学习了
    linux内核printk的一些并发处理
    Spring Security-自定义登录页面和认证过程其他常用配置
    图像形态学操作:基于CUDA的图像处理算法---灰度图像腐蚀
    移动Web
  • 原文地址:https://blog.csdn.net/skicth/article/details/123364364