【BERT】详解

BERT 简介

  • BERT 是谷歌在 2018 年时提出的一种基于 Transformer 的双向编码器的表示学习模型,它在多个 NLP 任务上刷新了记录。它利用了大量的无标注文本进行预训练,预训练任务有掩码语言模型和下一句预测,掩码语言模型指的是随机地替换文本中的一些词为掩码符号,并让它通过上下文信息来预测原来的词是什么。而下一句预测则是给定两个句子,然后让它预测第二个句子是不是第一个句子的下一句。

  • 由于 BERT 中编码器的强大学习能力,特别是上下文信息学习能力,使得它在预训练任务时学习到了大量通用的语言知识,而这些知识可以应用在下游任务中来提高性能。下游任务指的是句子对关系、文本分类、阅读理解、序列标注、语言翻译等任务。同时它也很容易适应不同的下游任务,只需在模型后面加上下游任务所需的输出层,然后使用少量的有标注文本数据来进行微调,这样可以节省大量的时间和资源,而且可以不用针对不同的任务重新设计模型结构,并从头开始训练模型。

  • BERT 的缺点在于需要大量的算力和无标注文本数据来进行预训练,从而使得下游任务只能在 BERT 的模型权重上进行微调。同时由于掩码符号的存在,使得预训练时的数据和微调、预测时的数据格式的不一致。

BERT 文本数据的 Mask 机制的规则如下

  • 随机选择一个样本中 15% 的词,然后有 80% 的概率替换为 [MASK] 符号,10 % 的概率替换为任意一个词,10% 的概率不替换。

Token 和 Token 化

  • Token

    将文本分割成一个个的最小单元,最小单元可以是字、词或者字符。Token 的目的是为了让模型能够理解和表示文本的语义和结构,同时也可以避免出现未登录词和新词无法识别的问题。

  • Token

    将文本分割成 Token,然后还会添加一些特殊的符号,例如 [CLS]、[SEP]、[PAD]、[UNK] 等,用来表示文本的开始、结束、填充、未知等含义。最后给每个 Token 分配一个唯一的 ID ,方便通过 Embedding 层来进行向量化。它的好处是可以减小词表的大小和解决未登录词和新词无法识别的问题,从而提高模型的泛化能力。

    一般不同的模型会有不同的 Token 化,而且同一个模型在面对不同语言时,也会有不同的 Token 化。

  • BERT 的 WordPiece Token

    WordPiece Token 化是 BERT 用来对文本进行 Token 化的过程。WordPiece Token 化是一个基于统计的 Token 化方法,它的基本思想是基于一个预先构建的词表,从最长的子词开始,逐步将单词分割成更小的子词,直到所有的子词都在词表中,或者达到最小的字符为止。

BERT 模型的结构

  • 结构图

  • 结构详解
    BERT 的网络结构主要是由 输入层编码器(Encoder)层输出层组成,其中:

    • 输入层是由 Token Embedding、句子 Embedding、位置 Embedding 组成的,一般是将它们的值进行相加来作为输入层的输出。

      • Token Embedding 会先将句子进行 Token 化,也就是将文本分割成一个个的最小单元 Token,然后再给它分配一个唯一的 ID,再经过 Embedding 层映射后得到一个对应的向量。

      • 句子(Sentence) Embedding 会分别给第一个句子的所有 Token 都分配 0 作为 ID,用来标记它们属于第一个句子。给第二个句子的所有 Token 都分配 1 作为 ID,用来标记它们属于第二个句子。

      • 位置(Position) Embedding :因为 BERT 的注意力层是并行化计算的,因此无法知道每个 Token 对应的位置是什么,所以需要输入一个位置信息给模型。BERT 会给每一个位置分配一个可学习的固定长度为 768 的向量,这些向量作为模型的参数,可以在训练的过程中进行更新。BERT 的最大的位置为 512,也就是最长可以输入的句子长度为 512.

      • 维度变化过程

        输入: [512]

        中间: [512]

          Token Embedding -> [512, 768]Sentence Embedding -> [512]         ->(相加)-> [512, 768]Position Embedding -> [512, 768]
        

        输出:[512, 768]

    • 编码器层 :编码器层由多个 Transformer 中的编码器堆叠组成,而每个编码器又包括了两个子层,分别是多头自注意力层和前馈神经网络层。每个子层后面都有残差连接和归一化层。它可以对输入的文本序列进行编码,学习序列中 Token 之间的关系,从而提取序列的上下文信息。

      • 多头自注意力层 :由多个自注意力组成,自注意力指的是计算注意力时的张量都是同一个输入经过乘以不同的矩阵得到的。每一个自注意力都可以独立地学习上下文信息,从而可以学习到不同的上下文信息,使得多头自注意力层可以捕捉到更丰富的上下文信息。计算自注意力的时候,使用的是缩放点乘注意力公式:

        S o f t m a x ( Q K T d k ) Softmax(\frac{QK^T}{\sqrt{d_k}}) Softmax(dk QKT)

        其中,张量 Q Q Q K K K 分别是输入 X 分别乘以矩阵 W q W_q Wq W k W_k Wk 得到的。而 K T K^T KT 则是张量 K K K 的转置。而 d k d_k dk 则是 Embedding 的维度。 S o f t m a x Softmax Softmax 则是将计算结果转换为概率,其公式为:
        S o f t m a x ( x i ) = exp ⁡ x i ∑ j = 1 N exp ⁡ x j Softmax(x_i) = \frac{\exp^{x_i}}{\sum_{j=1}^{N}\exp^{x_j}} Softmax(xi)=j=1Nexpxjexpxi

        Q K T {QK^T} QKT 除以 d k {\sqrt{d_k}} dk 的作用是可以将 Q K T {QK^T} QKT 的结果缩放到一定的范围,避免计算出来的结果太大或太小,从而在使用 S o f t m a x Softmax Softmax 计算概率时,出现概率太大和太小的问题,使得模型更容易学习。具体解释可以参看:在计算注意力时为什么要除以词向量维度的开方?

      • 前馈神经网络层 :由两个全连接层组成,作用是进一步提高网络的参数量,使得编码器具备更强大的学习能力。它的激活函数为 ReLU,也就是 m a x ( x , 0 ) max(x, 0) max(x,0)

    • 残差连接 :残差连接是将输入加到输出上作为新的输出,它的作用是让模型学习目标变成了学习输入和输出之间的差值,同时也减小了输入和输出之间的变化幅度,同时也可以避免梯度爆炸和梯度消失,这些作用都可以降低模型的学习难度。进而加速模型的收敛速度和减少训练时间,还能使得设计和训练更多的网络层数变得可能。

    • 层归一化 ( LayerNorm ) :层归一化可以对输入和输出进行缩放,使每一层的输入和输出服从相同的分布,降低模型的学习难度,提高模型的收敛速度。

      • 层归一化是按照最后一个维度来算的,也就是特征维度。这是因为在 BERT 模型中,每个输入的单词都会被表示为一个高维的向量,这个向量包含了单词的语义、语法、上下文等信息。如果我们按照其他的维度来进行归一化,比如句子维度或者批次维度,那么就会导致不同的单词之间的差异被消除,从而损失了单词的重要特征。而如果我们按照特征维度来进行归一化,那么就可以保证每个单词的特征向量都有相同的分布,从而提高模型的稳定性和泛化能力。

      • 层归一化的公式是:

      LayerNorm ( x ) = γ x − μ σ 2 + ϵ + β \text{LayerNorm}(x) = \gamma \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta LayerNorm(x)=γσ2+ϵ xμ+β

      • 参数说明: x x x 是输入张量, γ \gamma γ β \beta β 是缩放因子和偏移因子, μ \mu μ σ 2 \sigma^2 σ2 是沿着最后一个维度计算的均值和方差, ϵ \epsilon ϵ 是一个很小的正数,用于防止除以 0。

      • 计算过程:

        假设有张量 a ,它的维度为 [batch_size, sequence_len, embedding_dim],以下面的例子为例来计算。

        a = [
        [
        [1, 2, 3],
        [4, 5, 6]
        ]
        ]

        因此 a 的实际维度为 [1, 2, 3]。那么根据层归一化的计算规则,按照特征维度 embedding_dim 来计算均值和方差,以 [4, 5, 6] 来计算的过程如下:

          均值 = (4 + 5 + 6) / 3 = 5方差 = ((4-5)^2 + (5-5)^2 + (6-5)^2) / 3 = 2/3
        
    • 维度变化

      • 多头自注意力层:

        输入: [512, 768]
        输出:[512, 768]

      • 前馈神经网络层:

        输入: [512, 768]
        中间: [2048, 768]
        输出:[512, 768]

      输入: [512, 768]

      中间: [512, 768]

        多头自注意力 -> [512, 768]残差连接 -> [512, 768]层归一化 -> [512, 768]前馈神经网络:第一个全连接层:输入: [512, 768]输出: [2048, 768]第二个全连接层:输入: [2048, 768]输出: [512, 768]残差连接 -> [512, 768]层归一化 -> [512, 768]
      

      输出:[512, 768]

    • 输出层 :输出层一般是根据下游任务来决定的,例如文本分类则是一个全连接层。

在计算注意力时为什么要除以词向量维度的开方?

  • 在计算注意力时,要除以词向量维度的开方,是为了避免注意力分数过大或过小,导致梯度爆炸或消失的问题。这个方法是基于以下的数学原理:

    假设我们有两个词向量 q \mathbf{q} q k \mathbf{k} k,它们的维度是 d d d,它们的点积是 q ⋅ k \mathbf{q} \cdot \mathbf{k} qk,它们的范数是 ∥ q ∥ \|\mathbf{q}\| q ∥ k ∥ \|\mathbf{k}\| k。那么,我们可以得到以下的关系:

    q ⋅ k = ∥ q ∥ ∥ k ∥ cos ⁡ θ \mathbf{q} \cdot \mathbf{k} = \|\mathbf{q}\| \|\mathbf{k}\| \cos \theta qk=q∥∥kcosθ

    其中, θ \theta θ q \mathbf{q} q k \mathbf{k} k 之间的夹角。如果我们假设 q \mathbf{q} q k \mathbf{k} k 的每个元素都是从一个均值为 0,方差为 1 的正态分布中采样的随机变量,那么,我们可以得到以下的期望和方差:

    E [ q ⋅ k ] = 0 \mathbb{E}[\mathbf{q} \cdot \mathbf{k}] = 0 E[qk]=0

    V [ q ⋅ k ] = d \mathbb{V}[\mathbf{q} \cdot \mathbf{k}] = d V[qk]=d

    这意味着,当 d d d 很大时, q ⋅ k \mathbf{q} \cdot \mathbf{k} qk 的值也会很大,从而导致注意力分数的 softmax 函数的梯度接近于 0,这会影响模型的学习效率。为了解决这个问题,我们可以将 q ⋅ k \mathbf{q} \cdot \mathbf{k} qk 除以 d \sqrt{d} d ,这样就可以使得注意力分数的期望和方差都接近于 1,从而保持梯度的稳定性。这就是为什么要除以词向量维度的开方的原因。

BERT 的损失函数

  • 损失函数 是由两部分组成的,分别是掩码语言模型(MLM)的损失和下一句预测(NSP)的损失。这两个损失都是使用交叉熵(Cross Entropy)来计算的,但是具体的计算方式有所不同。而交叉熵的作用是用来衡量两个分布的差异程度,所以可以用来衡量真实值和预测值之间的差异程度。下面我将详细介绍 BERT 的损失函数的计算过程。

  • 掩码语言模型(MLM) 的损失是指模型在预测被掩码的词时产生的损失。具体来说,对于输入的每个词,模型会输出一个概率分布,表示该词是词表中每个词的可能性。然后,模型会根据真实的词和预测的概率分布来计算交叉熵损失。由于只有 15% 的词被掩码,所以只有这些词的损失会被计算,其他词的损失会被忽略。最后,模型会将所有被掩码的词的损失求平均,得到 MLM 的损失。MLM 的损失可以用下面的公式表示:

    L MLM = − 1 N ∑ i = 1 N log ⁡ P ( w i ∣ C i ) L_{\text{MLM}} = -\frac{1}{N}\sum_{i=1}^{N} \log P(w_i|C_i) LMLM=N1i=1NlogP(wiCi)

    其中, N N N 是被掩码的词的数量, w i w_i wi 是第 i i i 个被掩码的词, C i C_i Ci 是第 i i i 个被掩码的词的上下文, P ( w i ∣ C i ) P(w_i|C_i) P(wiCi) 是模型预测的概率分布。

  • 下一句预测(NSP) 的损失是指模型在判断两个句子是否连续时产生的损失。具体来说,对于输入的每个句子对,模型会输出一个二元概率分布,表示该句子对是连续的(IsNext)或者不连续的(NotNext)的可能性。然后,模型会根据真实的标签和预测的概率分布来计算交叉熵损失。最后,模型会将所有句子对的损失求平均,得到 NSP 的损失。NSP 的损失可以用下面的公式表示:

L NSP = − 1 M ∑ j = 1 M log ⁡ P ( y j ∣ S j ) L_{\text{NSP}} = -\frac{1}{M}\sum_{j=1}^{M} \log P(y_j|S_j) LNSP=M1j=1MlogP(yjSj)

其中, M M M 是句子对的数量, y j y_j yj 是第 j j j 个句子对的真实标签(0 表示 NotNext,1 表示 IsNext), S j S_j Sj 是第 j j j 个句子对, P ( y j ∣ S j ) P(y_j|S_j) P(yjSj) 是模型预测的概率分布。

BERT 的总损失是 MLM 的损失和 NSP 的损失的加权和,可以用下面的公式表示:

L BERT = L MLM + λ L NSP L_{\text{BERT}} = L_{\text{MLM}} + \lambda L_{\text{NSP}} LBERT=LMLM+λLNSP

其中, λ \lambda λ 是一个超参数,用来控制两个损失的相对重要性。在原始的 BERT 论文¹中, λ \lambda λ 被设置为 1,表示两个损失的权重相同。

BERT 的激活函数

  • ReLU :是一个计算简单的非线性函数,但是它可能会导致神经节点死亡和梯度消失,也就是当神经节点的输出为 0 之后,它之后的输出都将会一直是 0,无法再更新参数。它的公式为:
    m a x ( x , 0 ) max(x, 0) max(x,0)
    它的图像只在第一象限,且是一条 y=x 的直线。

  • GeLU :是一个基于高斯误差函数的激活函数,它的公式较为复杂,计算量也较大,但是它可以避免出现神经节点死亡和梯度消失的问题,而且它的非线性也比 ReLU 更好。它的公式为:

GELU ( x ) = x Φ ( x ) = x 1 2 [ 1 + erf ( x 2 ) ] \text{GELU}(x) = x \Phi(x) = x \frac{1}{2} \left[ 1 + \text{erf} \left( \frac{x}{\sqrt{2}} \right) \right] GELU(x)=xΦ(x)=x21[1+erf(2 x)]

其中, erf ( x ) \text{erf}(x) erf(x) 是高斯误差函数,它的定义是:

erf ( x ) = 2 π ∫ 0 x e − t 2 d t \text{erf}(x) = \frac{2}{\sqrt{\pi}} \int_{0}^{x} e^{-t^2} dt erf(x)=π 20xet2dt

GELU 激活函数的特点是,当 x x x 趋近于正无穷时,它的输出趋近于 x x x,当 x x x 趋近于负无穷时,它的输出趋近于 0,当 x x x 等于 0 时,它的输出等于 0。GELU 激活函数的图像如下:

GeLU

erf 函数的图像如下:

erf

BERT 的激活函数的使用情况是:

  • 在前馈神经网络中,BERT 使用了 GELU 激活函数,这是为了增加模型的非线性和复杂度,从而提高模型的表达能力。
  • 在自注意力机制中,BERT 使用了 ReLU 激活函数,这是为了减少模型的计算量,从而提高模型的运行速度。

BERT 的优化器

  • Adam:Adam 是一个自适应的优化器,它可以利用参数的梯度的均值和方差来动态地调整每个参数的学习率,从而实现一个平滑和稳定的优化过程。

    Adam 的公式是:

    m t = β 1 m t − 1 + ( 1 − β 1 ) g t \mathbf{m}_t = \beta_1 \mathbf{m}_{t-1} + (1 - \beta_1) \mathbf{g}_t mt=β1mt1+(1β1)gt

    v t = β 2 v t − 1 + ( 1 − β 2 ) g t 2 \mathbf{v}_t = \beta_2 \mathbf{v}_{t-1} + (1 - \beta_2) \mathbf{g}_t^2 vt=β2vt1+(1β2)gt2

    m ^ t = m t 1 − β 1 t \hat{\mathbf{m}}_t = \frac{\mathbf{m}_t}{1 - \beta_1^t} m^t=1β1tmt

    v ^ t = v t 1 − β 2 t \hat{\mathbf{v}}_t = \frac{\mathbf{v}_t}{1 - \beta_2^t} v^t=1β2tvt

    θ t + 1 = θ t − α m ^ t v ^ t + ϵ \mathbf{\theta}_{t+1} = \mathbf{\theta}_t - \alpha \frac{\hat{\mathbf{m}}_t}{\sqrt{\hat{\mathbf{v}}_t} + \epsilon} θt+1=θtαv^t +ϵm^t

    其中, g t \mathbf{g}_t gt 是第 t t t 步的梯度, m t \mathbf{m}_t mt v t \mathbf{v}_t vt 是第 t t t 步的一阶矩和二阶矩的估计, m ^ t \hat{\mathbf{m}}_t m^t v ^ t \hat{\mathbf{v}}_t v^t 是第 t t t 步的一阶矩和二阶矩的偏差修正, θ t \mathbf{\theta}_t θt 是第 t t t 步的参数, α \alpha α 是学习率, β 1 \beta_1 β1 β 2 \beta_2 β2 是一阶矩和二阶矩的衰减率, ϵ \epsilon ϵ 是一个很小的常数,用于防止除以零的错误。

    Adam 优化器的特点是,它可以自适应地调整每个参数的学习率,从而加速模型的收敛,同时也可以避免梯度的爆炸或消失的问题。Adam 优化器的优点是,它可以适用于各种类型的模型和数据,它也可以很容易地实现和使用。Adam 优化器的缺点是,它需要存储每个参数的一阶矩和二阶矩的估计,这会占用较多的内存空间,它也可能会导致一些参数的学习率过低,从而影响模型的性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/414029.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lucas求大组合数C(n,m)%p

将大组合数C&#xff08;n,m&#xff09;%p分解为小组合数C&#xff08;n,m&#xff09;%p乘积的模&#xff0c;n<10^18,m<10^18。 其中求解小组合数可以根据定义式计算&#xff08;质因子分解&#xff09;&#xff0c;也可以通过定义式的变形计算&#xff08;逆元&…

边缘计算AI智能分析网关V4客流统计算法的概述

客流量统计AI算法是一种基于人工智能技术的数据分析方法&#xff0c;通过机器学习、深度学习等算法&#xff0c;实现对客流量的实时监测和统计。该算法主要基于机器学习和计算机视觉技术&#xff0c;其基本流程包括图像采集、图像预处理、目标检测、目标跟踪和客流量统计等步骤…

Cinder组件作用

1、Cinder下发的流程 &#xff08;1&#xff09;Cinder-api接受上层发送的创建请求&#xff0c;然后把请求下发给Cinder-scheduler调度服务 &#xff08;2&#xff09;Cinder-scheduler调度服务&#xff0c;计算出哪个主机更适合创建&#xff0c;计算出来之后再把请求下发到Ci…

HarmonyOS 转场动画 ForEach控制

本文 我们继续说组件的专场特效 上文 HarmonyOS 转场动画 我们通过if控制了转场效果 本文 我们通过 ForEach 控制它的加载和删除 这时候就有人会好奇 ForEach 怎么控制删除呢&#xff1f; 很简单 循环次数不同 例如 第一次 10个 第二次 5个 那么后面的五个就相当于删除啦 我们…

C#winform上位机开发学习笔记2-串口助手的中文支持功能添加

分为两步&#xff1a; 1.串口接收支持中文显示 1.1.在软件初始化时写入此代码以支持汉字显示 //串口接收支持中文显示serialPort1.Encoding Encoding.GetEncoding("GB2312"); //串口1的解码支持GB2312汉字 2.串口发送支持中文输出 //支持中文输出Encoding Chine…

使用人工智能助手 Github Copilot 进行编程 01

本章涵盖了 AI 助⼿如何改变新程序员的学习⽅式为什么编程永远不会再⼀样了AI 助⼿如 Copilot 的⼯作原理Copilot 如何解决⼊⻔级编程问题AI 辅助编程的潜在危险 在本章中&#xff0c;我们将讨论人类如何与计算机进行交流。我们将向您介绍您的 AI 助手 GitHub Copilot&#x…

WordPress后台底部版权信息“感谢使用 WordPress 进行创作”和版本号怎么修改或删除?

不知道各位WordPress站长在后台操作时&#xff0c;是否有注意到每一个页面底部左侧都有一个“感谢使用 WordPress 进行创作。”&#xff0c;其中WordPress还是带有nofollow标签的链接&#xff1b;而页面底部右侧都有一个WordPress版本号&#xff0c;如下图中的“6.4.2 版本”。…

关于gltf模型格式文件的学习

目录 glTF模型 小黄鸭的gltf模型 字段分析 scene nodes meshes primitives attributes indices mode material accessors bufferView byteOffset count componentType type materials textures images samplers magFilter与minFilter wrapS与wrapT 进行…

Labview实现用户界面切换的几种方式---通过VI间相互调用

在做用户界面时我们的程序往往面对的对象是程序使用者&#xff0c;复杂程序如果放在同一个页面中&#xff0c;往往会导致程序冗长卡顿&#xff0c;此时通过多个VI之间的切换就可以实现多个界面之间的转换&#xff0c;也会显得程序更加的高大上。 本文所有程序均可下载&#xff…

WINCC读写EXCEL-VBS

原创 RENHQ WINCC 关于VBS操作EXCEL的文档不管在论坛上还是在网上&#xff0c;相关的脚本已经很多&#xff0c;但是依然有很多人在问这个问题&#xff0c;于是把我以前在论坛上发的一个集合帖子的脚本拿来&#xff0c;重新开个帖子&#xff0c;如果再有人问的话&#xff0c;可…

年龄性别预测1:年龄性别数据集说明(含下载地址)

年龄性别预测1&#xff1a;年龄性别数据集说明(含下载地址) 目录 年龄性别预测1&#xff1a;年龄性别数据集说明(含下载地址) 1.前言 2.MegaAge_Asian 3.MORPH 4.IMDB-WIKI 5.数据集下载 6.年龄性别预测和识别(Python/C/Android) 1.前言 本项目将实现年龄性别预测和识…

在线扒站网PHP源码-在线扒站工具网站源码

源码介绍 这是一款在线的网站模板下载程序&#xff0c;也就是我们常说的扒站工具&#xff0c;利用它我们可以很轻松的将别人的网站模板样式下载下来&#xff0c;这样就可以大大提高我们编写前端的速度了&#xff01;注&#xff1a;扒取的任何站点不得用于商业、违法用途&#…