欢迎光临
我们一直在努力

BERT自然语言处理框架深度解析:从Transformer到双向预训练模型

文章目录

  • 一、为什么需要BERT?传统方法的局限
    • 1.1 传统RNN网络的问题
    • 1.2 传统word2vec的问题
  • 二、BERT框架概述
  • 三、Transformer基础架构
    • 3.1 Encoder-Decoder编码解码框架
    • 3.2 Self-Attention自注意力机制
      • 第一步:构造Q、K、V三个矩阵
      • 第二步:计算注意力得分
      • 第三步:归一化(Scaling)
      • 第四步:加权求和
    • 3.3 Multi-Head Attention多头注意力
    • 3.4 多层堆叠
    • 3.5 位置编码(Positional Encoding)
      • 方法一:0-1范围归一化位置
      • 方法二:1-n正整数编号
      • 方法三:三角函数位置编码(Transformer采用)
    • 3.6 Add & Norm 残差与归一化
    • 3.7 Transformer整体框架
    • 3.8 Decoder的Shifted Right操作
  • 四、BERT预训练任务详解
    • 4.1 Masked Language Model(MLM)遮蔽语言模型
    • 4.2 Next Sentence Prediction(NSP)下一句预测
  • 五、BERT模型变体与参数规格
  • 六、BERT微调与下游应用
    • 常见下游任务与微调方式
  • 七、总结
      • BERT的历史地位

一、为什么需要BERT?传统方法的局限

在BERT出现之前,NLP领域主要面临两大痛点:传统RNN的串行计算瓶颈与word2vec词向量的静态表示问题。

1.1 传统RNN网络的问题

RNN(循环神经网络)通过隐藏状态

h

1

→

h

2

→

⋯

→

h

m

h_1 \\rightarrow h_2 \\rightarrow \\dots \\rightarrow h_m

h1​→h2​→⋯→hm​ 依次处理序列,存在以下缺陷:

  • 串行依赖导致训练慢:必须等

    h

    1

    h_1

    h1​ 计算完成才能计算

    h

    2

    h_2

    h2​,无法并行化,序列越长训练时间越长。

  • 并行计算效果差:难以在多台服务器上同时训练同一个网络,无法充分利用GPU集群。
  • 1.2 传统word2vec的问题

  • 词向量训练好后不再改变:无论上下文如何,同一个词的向量永远相同。
  • 无法区分多义词:不同语境下的同一词语含义不同,但共享同一个向量。例如"机车"在台湾俚语中指"罗嗦",而在普通话中指"摩托车",静态向量无法区分。
  • 核心结论:我们需要一种能根据上下文动态生成词向量、并且可以并行计算的模型架构——这正是Transformer与BERT诞生的背景。


    二、BERT框架概述

    BERT(Bidirectional Encoder Representations from Transformers)是基于Transformer编码器的双向预训练语言模型。

    特性说明
    模型结构 基于Transformer的Encoder部分,采用多层自注意力机制和前馈神经网络
    核心能力 预训练学习丰富的语言表示,可迁移到各类NLP下游任务
    预训练任务 遮蔽语言模型(MLM)+ 下一句预测(NSP)
    双向性 预测一个词时同时考虑左右两侧上下文(区别于GPT的单向自回归)
    微调方式 在特定任务数据集上进一步训练,适配下游任务
    历史影响 刷新11项NLP基准测试记录,奠定预训练模型范式,催生RoBERTa、ALBERT等后续工作

    三、Transformer基础架构

    BERT的核心骨架是Transformer的Encoder部分。要理解BERT,必须先理解Transformer。

    3.1 Encoder-Decoder编码解码框架

    Encoder-Decoder(编码-解码)是大部分注意力模型的基础框架,主要用于处理序列到序列(Seq2Seq) 问题——输入一个序列,输出另一个序列,且两个序列长度可以不同。

    典型应用场景:

    • 机器翻译:输入英文序列 → 输出中文序列
    • 文本摘要:输入文章全文 → 输出摘要
    • 问答系统:输入问题 → 输出答案

    工作流程:

    输入序列 <x1, x2, …, xn> → [Encoder] → 语义编码C → [Decoder] → 输出序列 <y1, y2, …, ym>

    • Encoder(编码器):将输入序列编码为一个语义向量C,C中存储了整个输入序列的信息。传统实现可用RNN/LSTM/GRU/BiLSTM等。
    • Decoder(解码器):根据语义编码C,逐步解码生成输出序列。
    • 编码与解码方式可任意组合:Encoder用BiLSTM,Decoder用GRU,完全可以。

    通俗理解:翻译"Bonjour"时,大脑先把这个词的概念提取出来(编码),再从英语词库中找到对应的"Hello"(解码)。提取出来的"概念"就是语义向量C。

    3.2 Self-Attention自注意力机制

    核心问题:一句话中哪些词是重点?如何让计算机自动关注到话语中的关键词?

    Self-Attention(自注意力)通过让每个词与序列中所有词计算关联程度,动态捕捉上下文语义。

    第一步:构造Q、K、V三个矩阵

    输入词向量通过三个可训练的权重矩阵

    W

    Q

    W^Q

    WQ、

    W

    K

    W^K

    WK、

    W

    V

    W^V

    WV 分别投影得到:

    • Q(Query,查询):当前词"主动查询"其他词
    • K(Key,键):其他词"等待被查询"的特征
    • V(Value,值):其他词实际携带的信息特征

    q

    i

    =

    x

    i

    ⋅

    W

    Q

    ,

    k

    i

    =

    x

    i

    ⋅

    W

    K

    ,

    v

    i

    =

    x

    i

    ⋅

    W

    V

    q_i = x_i \\cdot W^Q, \\quad k_i = x_i \\cdot W^K, \\quad v_i = x_i \\cdot W^V

    qi​=xi​⋅WQ,ki​=xi​⋅WK,vi​=xi​⋅WV

    第二步:计算注意力得分

    每个词的Q与序列中所有词的K计算内积,表示匹配程度:

    Score

    (

    q

    i

    ,

    k

    j

    )

    =

    q

    i

    ⋅

    k

    j

    \\text{Score}(q_i, k_j) = q_i \\cdot k_j

    Score(qi​,kj​)=qi​⋅kj​

    • q

      1

      ⋅

      k

      1

      q_1 \\cdot k_1

      q1​⋅k1​:第1个词与自身的匹配度

    • q

      1

      ⋅

      k

      2

      q_1 \\cdot k_2

      q1​⋅k2​:第1个词与第2个词的匹配度

    第三步:归一化(Scaling)

    直接内积在维度较大时数值会很大,导致Softmax梯度消失。因此除以

    d

    k

    \\sqrt{d_k}

    dk​

    ​ 进行缩放:

    Attention

    (

    Q

    ,

    K

    ,

    V

    )

    =

    Softmax

    (

    Q

    K

    T

    d

    k

    )

    V

    \\text{Attention}(Q, K, V) = \\text{Softmax}\\left(\\frac{QK^T}{\\sqrt{d_k}}\\right)V

    Attention(Q,K,V)=Softmax(dk​

    ​QKT​)V

    其中

    d

    k

    d_k

    dk​ 是K向量的维度。这一步归一化的作用是:防止维度增大导致内积值过大,保持梯度稳定。

    第四步:加权求和

    归一化后的注意力权重与V相乘求和,得到每个词的最终特征表示

    z

    i

    z_i

    zi​。

    关键特性:每个词的Q会与整个序列中每一个K计算得分,再基于得分分配V的权重。因此同样的词在不同句子中会得到不同的特征向量——这正是解决word2vec静态表示问题的核心。

    并行优势:Q、K、V矩阵可以一次性并行计算,完全避免了RNN的串行依赖,极大提升了训练速度。

    3.3 Multi-Head Attention多头注意力

    卷积神经网络中用多组卷积核提取不同特征图。同理,Transformer中用多组Q、K、V可以得到多种词的特征表达。

    多头机制的工作流程:

  • 拆分多头:将

    d

    m

    o

    d

    e

    l

    d_{model}

    dmodel​ 维的Q、K、V拆分为

    h

    h

    h 个低维子空间(通常

    h

    =

    8

    h=8

    h=8),每个头独立计算Attention。

  • 并行计算:每个头独立输出

    Z

    0

    ,

    Z

    1

    ,

    …

    ,

    Z

    h

    −

    1

    Z_0, Z_1, \\dots, Z_{h-1}

    Z0​,Z1​,…,Zh−1​,分别关注不同的语义信息(有的头关注语法,有的头关注指代关系)。

  • 拼接:将所有头的输出沿特征维度拼接:

    Concat

    (

    Z

    0

    ,

    Z

    1

    ,

    …

    ,

    Z

    h

    −

    1

    )

    \\text{Concat}(Z_0, Z_1, \\dots, Z_{h-1})

    Concat(Z0​,Z1​,…,Zh−1​)。

  • 线性降维:拼接后通过一个全连接层

    W

    O

    W^O

    WO 降维,得到最终输出。

  • MultiHead

    (

    Q

    ,

    K

    ,

    V

    )

    =

    Concat

    (

    head

    1

    ,

    …

    ,

    head

    h

    )

    W

    O

    \\text{MultiHead}(Q, K, V) = \\text{Concat}(\\text{head}_1, \\dots, \\text{head}_h) W^O

    MultiHead(Q,K,V)=Concat(head1​,…,headh​)WO

    其中

    head

    i

    =

    Attention

    (

    Q

    W

    i

    Q

    ,

    K

    W

    i

    K

    ,

    V

    W

    i

    V

    )

    \\text{head}_i = \\text{Attention}(QW_i^Q, KW_i^K, VW_i^V)

    headi​=Attention(QWiQ​,KWiK​,VWiV​)。

    3.4 多层堆叠

    单层Self-Attention的表达能力有限,实际使用时将多个Encoder Layer堆叠起来(类似CNN堆多层卷积):

    输入Embedding → [Encoder Layer 1] → [Encoder Layer 2] → … → [Encoder Layer N] → 输出表示

    BERT-base堆叠了12层,BERT-large堆叠了24层。层数越多,模型能捕捉的语义层次越深。

    3.5 位置编码(Positional Encoding)

    问题:Self-Attention本身是"无序"的——它只关心句子中有哪些词,不关心词的顺序。但语序对语言至关重要(“我打你” vs “你打我”)。

    因此必须引入位置信息。

    方法一:0-1范围归一化位置

    我喜欢吃洋葱 → [0, 0.16, 0.32, …, 1.0]
    我真的不喜欢吃洋葱 → [0, 0.125, 0.25, …, 1.0]

    缺陷:句子长度不同,相同位置的编码值不同,无法跨句子比较位置。

    方法二:1-n正整数编号

    我喜欢吃洋葱 → [1, 2, 3, 4, 5, 6]
    我真的不喜欢吃洋葱 → [1, 2, 3, 4, 5, 6, 7]

    缺陷:句子越长,后面的数字越大,导致位置权重被数值大小扭曲。

    方法三:三角函数位置编码(Transformer采用)

    Transformer作者设计了基于正弦/余弦的位置编码公式:

    P

    E

    (

    p

    o

    s

    ,

    2

    i

    )

    =

    sin

    ⁡

    (

    p

    o

    s

    10000

    2

    i

    /

    d

    m

    o

    d

    e

    l

    )

    PE_{(pos, 2i)} = \\sin\\left(\\frac{pos}{10000^{2i/d_{model}}}\\right)

    PE(pos,2i)​=sin(100002i/dmodel​pos​)

    P

    E

    (

    p

    o

    s

    ,

    2

    i

    +

    1

    )

    =

    cos

    ⁡

    (

    p

    o

    s

    10000

    2

    i

    /

    d

    m

    o

    d

    e

    l

    )

    PE_{(pos, 2i+1)} = \\cos\\left(\\frac{pos}{10000^{2i/d_{model}}}\\right)

    PE(pos,2i+1)​=cos(100002i/dmodel​pos​)

    • pos:词在句子中的位置(从0开始)
    • d

      m

      o

      d

      e

      l

      d_{model}

      dmodel​:词向量的维度

    • i

      i

      i:维度索引(

      i

      =

      0

      ,

      1

      ,

      …

      ,

      d

      m

      o

      d

      e

      l

      /

      2

      −

      1

      i = 0, 1, \\dots, d_{model}/2 – 1

      i=0,1,…,dmodel​/2−1)

    • 偶数维用sin,奇数维用cos

    最终输入:将词向量(Word Embedding)与位置编码(Positional Encoding)逐点相加:

    Input

    =

    WordEmbedding

    +

    PositionalEncoding

    \\text{Input} = \\text{WordEmbedding} + \\text{PositionalEncoding}

    Input=WordEmbedding+PositionalEncoding

    优点:

  • PE值分布在

    [

    −

    1

    ,

    1

    ]

    [-1, 1]

    [−1,1] 区间,不会随序列长度增长而放大。

  • 不同句子中相同位置的PE值相同(如pos=0时PE=0),具有跨句子的泛化能力。
  • 相对位置可被学习:

    P

    E

    p

    o

    s

    +

    k

    PE_{pos+k}

    PEpos+k​ 可以表示为

    P

    E

    p

    o

    s

    PE_{pos}

    PEpos​ 的线性函数。

  • 3.6 Add & Norm 残差与归一化

    每个Encoder Layer内部包含两个关键操作:

    • Add(残差连接):将Attention的输入直接加到输出上(类似ResNet的shortcut),缓解深层网络梯度消失问题。

      Output

      =

      Sublayer

      (

      x

      )

      +

      x

      \\text{Output} = \\text{Sublayer}(x) + x

      Output=Sublayer(x)+x

    • Norm(Layer Normalization):对每个样本的特征做归一化,加速收敛、稳定训练。

    完整子层结构:

    x → Multi-Head Attention → Add(x + attn_output) → Norm → Feed Forward → Add → Norm → 输出

    3.7 Transformer整体框架

    Transformer整体由Encoder堆栈和Decoder堆栈组成:

    • Encoder侧:N层Encoder Layer,每层包含 Multi-Head Attention + Feed Forward(两层全连接)。
    • Decoder侧:N层Decoder Layer,包含 Masked Multi-Head Attention + Encoder-Decoder Attention + Feed Forward。
    • Feed Forward层:一个两层的全连接神经网络,中间激活函数为ReLU/GELU。

    重要区分:BERT只用了Encoder部分,没有Decoder。这是BERT与GPT(只用Decoder)、原始Transformer(两者都用)的核心结构区别。

    3.8 Decoder的Shifted Right操作

    Decoder在训练时使用"Shifted Right"技巧:

    • 将目标输出序列右移一位,最左侧添加起始符 <sos>(Start Of Sentence)。
    • 训练时解码器以 <sos> 开头,逐步预测下一个词。

    示例(中译英任务):

    • 输入:我爱中国
    • 目标输出:I love China
    • Decoder输入(shifted right):<sos> I love China
    • Decoder输出预测:I love China <eos>

    这样解码器在生成每个词时,都能基于已经生成的前缀进行预测,实现自回归生成。


    四、BERT预训练任务详解

    BERT在大规模无标注语料上进行预训练,使用两个自监督任务:

    4.1 Masked Language Model(MLM)遮蔽语言模型

    核心思想:随机遮蔽输入中15%的词,让模型根据上下文预测被遮蔽的词。这就是"完形填空"任务。

    15%的Masking策略细节(BERT论文的重要设计):

    被选中的15%的词中:

    • 80% 替换为 [MASK] 标记,如"我今天去面试" → “我[MASK]天去[MASK]试”
    • 10% 随机替换为另一个词(防止模型过度依赖[MASK]标记)
    • 10% 保持原词不变(降低预训练与微调的差距)

    为什么按字Mask而不是按词Mask? 因为词的组合太多(今天、明天、后天、上午、下午……),按字Mask的预测空间更小,模型更容易学。

    双向性的体现:预测被Mask的词时,模型同时看到左右两侧的上下文——这正是BERT"双向"的含义。

    4.2 Next Sentence Prediction(NSP)下一句预测

    核心思想:判断两个句子A和B在原文中是否是连续的上下句。

    输入构造:

    [CLS] 句子A [SEP] 句子B [SEP]

    正样本(Label = IsNext):

    [CLS] 我今天去面试 [SEP] 准备好了简历 [SEP] → Label: yes

    负样本(Label = NotNext):

    [CLS] 我今天去面试 [SEP] 中午吃了包子 [SEP] → Label: no

    特殊标记说明:

    标记全称作用
    [CLS] Classification Token 放在序列开头,最终输出用于分类任务;训练中也作为一个普通token参与学习
    [SEP] Separator Token 分隔两个句子,或表示单句结束
    [MASK] Mask Token MLM任务中被遮蔽的位置

    为什么需要NSP? 许多下游任务(如问答QA、自然语言推理NLI)需要理解句子间的关系,NSP让模型学到句间连贯性,而不仅仅是单词语义。


    五、BERT模型变体与参数规格

    BERT论文中发布了两个版本:

    模型规格层数(Encoder)隐藏维度Attention头数参数量适用场景
    BERT-base 12 768 12 ~110M 日常微调、资源有限场景
    BERT-large 24 1024 16 ~340M 追求SOTA效果、算力充足场景

    其他关键超参数:

    • 最大序列长度:512 tokens
    • Batch Size:128,000 words
    • 训练步数:1,000,000步
    • 训练数据:BooksCorpus(8亿词)+ English Wikipedia(25亿词)
    • 优化器:Adam,

      β

      1

      =

      0.9

      \\beta_1=0.9

      β1​=0.9,

      β

      2

      =

      0.999

      \\beta_2=0.999

      β2​=0.999,

      LR

      =

      1

      e

      −

      4

      \\text{LR}=1e-4

      LR=1e−4

    • Warmup Steps:10,000

    六、BERT微调与下游应用

    预训练完成后,BERT可以通过微调(Fine-tuning) 适配各类下游NLP任务。微调时将预训练参数初始化,用下游任务数据继续训练即可。

    常见下游任务与微调方式

    任务类型输入示例微调方式
    文本分类 单句 → 情感/主题类别 取[CLS]输出接分类层
    命名实体识别(NER) 句子 → 每个词的实体标签 对每个token输出接分类层
    问答系统(QA) 问题+段落 → 答案起止位置 预测答案的start/end span
    自然语言推理(NLI) 前提+假设 → 蕴含/矛盾/中立 用[CLS]做句对分类
    文本相似度 句子A+句子B → 相似度分数 句对表示接回归层

    BERT的灵活性:只需在Encoder输出后接一个简单的任务层(分类层/span预测层等),几乎所有NLP任务都能适配——这是BERT通用性强的根本原因。


    七、总结

  • BERT的本质:一个基于Transformer Encoder的双向预训练语言模型,通过MLM和NSP两个自监督任务学习深层语言表示。
  • 技术突破:
    • 双向上下文建模( vs GPT的单向)
    • Self-Attention并行计算( vs RNN的串行)
    • 预训练+微调范式(取代任务定制模型)
  • 关键组件:Self-Attention → Multi-Head → 位置编码 → 残差连接 → LayerNorm → 多层堆叠。
  • BERT的历史地位

    BERT开启了NLP的"预训练时代",后续涌现了大量改进模型:

    • RoBERTa:去掉NSP、更大batch、更多数据,进一步提升效果
    • ALBERT:缩小参数量(跨层参数共享、词向量分解),提升训练效率
    • DistilBERT:模型蒸馏,参数量减少40%,速度提升60%,保留97%效果
    • GPT系列:Decoder路线的自回归预训练,走向生成式AI
    赞(0)
    未经允许不得转载:171主机测评 » BERT自然语言处理框架深度解析:从Transformer到双向预训练模型
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址