一文搞定自注意力机制(Self-Attention)-CSDN博客

一文彻底搞懂Transformer - Word Embedding(词嵌入)-CSDN博客

如何表示文字?

Word Embedding(词嵌入)

        词嵌入是自然语言处理(NLP)中语言模型与表征学习技术的统称,它是NLP里的早期预训练技术。它是指把一个维数为所有词的数量的高维空间嵌入到一个维数低得多的连续向量空间中(也就是把用one-hot编码的字词映射到一到一个维数更低的向量空间)

        每个单词或词组被映射为实数域上的向量,这也是分布式表示:向量的每一维度都没有实际意义,而整体代表一个具体概念

        Word Embedding的输入是原始文本中的一组不重叠的词汇,假设有句子:apple on a apple tree。那么为了便于处理,我们可以将这些词汇放置到一个dictionary里,例如:[“apple”, “on”, “a”, “tree”],这个dictionary就可以看作是Word Embedding的一个输入。

        Word Embedding的输出就是每个word的向量表示。对于上文中的原始输入,假设使用最简单的one hot编码方式,那么每个word都对应了一种数值表示。例如,apple对应的vector就是[1, 0, 0, 0],a对应的vector就是[0, 0, 1, 0],各种机器学习应用可以基于这种word的数值表示来构建各自的模型。当然,这是一种最简单的映射方法,但却足以阐述Word Embedding的意义。

        one-hot :这种方法无法表达词语之间的关系。“苹果”和“香蕉”都是水果,但它们的独热向量是正交的(点积为0),没有任何相似性。

        词嵌入解决了这个问题。它的目标是:语义相似的词,在向量空间中的位置也应该接近。

        词语的向量表示体现了机器对于这个词的含义的认识,向量中的每个元素都代表了词语的某种特征。所以,如果要让机器对词的理解进一步加深,以至于根据语境分辨词语的不同含义,那么就想办法让它发现一组更适合这个词的特征,使其能够进一步更新向量即可。

关键特性

  1. 稠密向量:每个词被映射为一个相对较短(比如50维、100维、300维)的稠密向量,而不是一个极长的、大部分是0的稀疏向量。

  2. 语义编码:向量的每一维都代表了某种潜在的语义或语法特征。这些特征是模型自动学习到的,我们无法直接解释每一维的具体含义,但最终效果是:

    • king - man + woman ≈ queen

    • 北京 - 中国 + 法国 ≈ 巴黎

    • 词“猫”和“狗”的向量距离,会比“猫”和“汽车”的向量距离近得多。

        词嵌入模型通过在大量的文本数据(如维基百科、新闻文章)上训练,学习词语的分布式表示。核心假设是:一个词的含义可以由它周围经常出现的词(上下文)来定义。

        例如,在大量句子中,“苹果”这个词可能经常和“吃”、“水果”、“甜”、“iPhone”、“公司”等词一起出现。模型通过分析这些共现模式,学习为“苹果”生成一个向量,这个向量与“吃”、“水果”等词的向量在某个维度上相近。

        一句话是一种序列输入,词与词之间有先后关系,这种关系对于一个词在句中表达的意思有很大的影响,如果模型只根据一个词本身去学习它的种种含义,那么就不能完成读懂句子这样的任务。        

RNN模型

        

        循环神经网络(Recurrent Neural Network,RNN) 是一种专门处理序列数据(如文本、语音、时间序列)的神经网络。

        与传统的前馈神经网络不同,RNN 具有"记忆"能力,能够保存之前步骤的信息。

        循环神经网络能够利用前一步的隐藏状态(Hidden State)来影响当前步骤的输出,从而捕捉序列中的时序依赖关系。

LSTM

        LSTM(Long Short-Term Memory,长短期记忆网络)是 1997 年提出的RNN 经典核心变体

        针对标准 RNN 梯度消失、无法有效学习长距离时序依赖的核心问题设计,通过独创的门控机制细胞状态通道,实现对序列信息的选择性保留、输入和输出,精准控制历史信息的传递,成为多年来序列建模的基础模型(GRU、双向 LSTM 等均基于其思路改进),广泛用于长文本处理、机器翻译、语音识别、长周期时间序列预测等场景。

        简单来说:标准 RNN 是 “一股脑传递信息,容易丢失长距离有用信息、累积无用信息”,而 LSTM 是 “带‘筛选阀门’的信息通道,有用的留、无用的删、新信息按需加”。

RNN/LSTM 的共性遗留问题(LSTM 未解决,也是核心痛点)

        这是循环结构的底层缺陷,无论 LSTM 如何优化门控,都无法突破循环的本质限制,也是自注意力机制被提出的关键原因,这部分是二者真正被取代的核心

1. 串行计算,无法并行,效率极低

        这是 RNN/LSTM最大的痛点。循环结构的核心是时间步依赖:每个时间步t的计算必须等待t−1步完成(隐藏状态ht​依赖ht−1​),整个序列只能从左到右串行计算,无法对序列做批量的矩阵化并行运算。序列越长,串行计算的耗时呈线性增长,训练和推理效率极低,无法适配大数据、长序列的建模需求(比如万字长文本、长周期时序数据)。

2. 长距离依赖仍有信息衰减,建模不直接

        LSTM 仅缓解了梯度消失,并未彻底解决:细胞状态的线性传递虽让梯度衰减变慢,但长序列中(如数百 / 数千个时间步),信息通过门控逐步传递时,仍会有轻微的衰减和失真;更关键的是,RNN/LSTM 的长距离依赖是间接捕捉:任意两个位置(如第 1 步和第 100 步)的关联,必须通过中间所有时间步的逐步传递,无法直接建立二者的联系,建模精度受中间步骤干扰。

3. 仅能捕捉局部 / 时序依赖,全局关联能力弱

RNN/LSTM 的依赖建模是时序化、局部化的:

  • 单向 RNN/LSTM 仅能从左到右捕捉前文依赖,双向 BiLSTM 也仅能同时捕捉前文 + 后文的局部双向依赖
  • 无法直接捕捉序列中任意位置、非时序的全局关联(比如文本中 “主语” 和 “远距宾语”、“标题” 和 “文末核心词” 的关联),而全局关联是序列建模(尤其是 NLP)的核心需求。

4. 静态表征,无法适配动态上下文

        RNN/LSTM 的词 / 位置表征是逐步构建、基本固定的:一个词的隐藏状态在其时间步生成后,后续仅能通过门控轻微调整,无法根据整个序列的全局上下文做动态加权;导致同一个词在不同上下文下的表征完全相同(比如 “苹果” 在 “吃苹果” 和 “苹果公司” 中表征一致),无法贴合真实的语义场景,建模精度受限。

********************************************************************************************************

自注意力机制

        自注意力机制 是一种让序列(比如一句话)中的每个元素(比如一个词)都能够“审视”序列中的所有其他元素,并根据相关性动态地分配注意力的计算机制。它的核心是让模型自己学会在同一个序列内部,哪些部分对于理解当前元素是重要的。

        自注意力机制(以缩放点积自注意力 Scaled Dot-Product Attention为基础,Transformer 的核心)是一种基于全局上下文、矩阵化并行、动态加权的关联建模机制,完全抛弃了循环结构的时间步依赖,从底层解决了 RNN/LSTM 的所有缺陷

1. 全并行计算,效率呈数量级提升

        这是自注意力机制最核心的进步,彻底抛弃了 RNN/LSTM 的时间步依赖:自注意力的所有计算都是矩阵化运算,对整个序列的Q/K/V做一次性的矩阵乘法和加权求和,所有位置的关联计算同时完成,无任何串行依赖;训练 / 推理效率不再随序列长度线性增长,而是通过矩阵并行实现算力的充分利用,能轻松处理长序列、大数据集,这也是 Transformer 能被工业界大规模落地的核心原因。

2. 直接捕捉全局依赖,长距离信息无衰减

        自注意力机制能直接计算序列中任意两个位置的关联权重,无论两个位置的距离多远(比如第 1 步和第 1000 步),都能通过QKT直接建立关联,无需中间步骤的传递;这意味着长距离依赖的信息无任何衰减,全局关联的建模精度远高于 RNN/LSTM,完美解决了 “长序列信息衰减、局部依赖建模” 的痛点。

        比如在文本建模中,自注意力能直接捕捉 “标题” 和 “文末”、“主语” 和 “远距宾语” 的关联,而 LSTM 需要逐步传递,易丢失这类关联。

3. 动态加权表征,适配上下文语义

        自注意力机制为每个位置生成基于全局上下文的动态表征:每个位置的新表征Zi​,是对整个序列的V矩阵按注意力权重做的加权求和 ——同一个词在不同上下文下,会因注意力权重的不同,生成完全不同的表征(比如 “苹果” 在 “吃苹果” 中会关注 “吃”,在 “苹果公司” 中会关注 “公司”,表征向量完全不同);这种上下文感知的动态表征,更贴合真实的语义场景,建模精度远超 RNN/LSTM 的静态表征。

注意力怎么分配

        自注意力机制通过三个可学习的权重矩阵(W_Q, W_K, W_V)将每个输入向量映射到三个不同的空间,得到查询向量 Q(Query)、键向量 K(Key)和值向量 V(Value)。

注意力的计算步骤

        假设我们有一个输入序列,包含n个词,每个词用d维的向量表示。那么输入可以表示为一个矩阵X,形状为(n, d)。

        自注意力机制通过三个可学习的权重矩阵(W_Q, W_K, W_V)将每个输入向量映射到三个不同的空间,得到查询向量(Query)、键向量(Key)和值向量(Value)。

  • Query(查询):代表"我想要什么信息"

  • Key(键):代表"我拥有什么信息"

  • Value(值):代表"我实际提供的信息"

        具体计算步骤如下:(权重矩阵都是 d × d 的方阵,一般令d_k = d_v)

  1. 计算Q, K, V

    1. Q = X * W_Q (形状:n × d_k)

    2. K = X * W_K (形状:n × d_k)

    3. V = X * W_V (形状:n × d_v)

  2. 计算注意力分数
    • 注意力分数表示两个词之间的相关性。对于每一个查询向量Q_i,我们计算它与所有键向量K_j的点积,然后除以一个缩放因子(sqrt(d_k)),这是为了在softmax时避免梯度消失。

    • 公式:分数 = (Q * K^T) / sqrt(d_k) *   V
      (形状:                【n,n】          *【n,768】= 【n,768】)

    • 对于每个词 a_i 来说,都将其视为一个 1*d 的向量,相应的经过变换后它也还是一个1*d 的向量(Qi 和 Ki 都是这样),那么计算时,a_ij 就是一个行向量与一个列向量相乘得到的一个数,每个向量有 n 个这样的数,共有 n 个向量(词),所以说,最后得到的整体上看就是一个 n×n 的矩阵(其实就是矩阵乘法的计算过程,线代学的不好)

  3. 应用Softmax
    • 对每一行(对应一个查询)的分数进行softmax归一化(因为注意力总和必须是 1 ),使得每一行的分数之和为 1(在每一行内使用softmax,表示一个词对于其他所有词的注意力分配),得到注意力权重矩阵。

    • 公式:注意力权重 = softmax(分数, dim=-1)

  4. **************************************加权求和****************************************
    • 用注意力权重对值向量V进行加权求和,得到每个查询向量对应的输出。

    • 公式:输出 = 注意力权重 * V (形状:n × d_v)

    • 最后的计算结果 b_i 表示第 i 个词在整个句子的语境中的实际含义(原始的 a_i 表示的就是机器原本“以为的”这个词的含义),其中包含了d个维度的特征。

    • 由计算过程可见,注意力的计算并未改变向量的形状,词的表示形式没有变,机器仍然知道这是一个词语,只是改变了机器对一个词的含义的认知。从原始的 a_i ,经过注意力,也就是考虑了上下文的作用,机器更新了对这个词语这个句子中所应具备的含义的认识。

    • 综上,注意力机制实际上进行的是一种 “ 特征转换 ”,引入了上下文对某个词语含义的影响,让机器认识到词语在具体语境下的具体含义,并且反映在其嵌入到的向量上。

  5. 多头注意力(可选但常用):
    • 实际上,Transformer使用的是多头自注意力。即,将Q、K、V分成h组(每组维度为d_k = d_v = d_model / h),分别进行上面的自注意力计算,然后将h个结果拼接起来,再通过一个线性层。

位置信息

        自注意力机制本身是完全忽略词语顺序的——它把整个句子当作一个“词袋”来处理。如果不加入位置信息,模型会认为“猫捉老鼠”和“老鼠捉猫”是完全一样的。

        为了解决这个问题,Transformer架构引入了 位置编码 或 位置嵌入,将词语的顺序信息显式地注入到模型中。

        1. 核心思想

        为序列中的每个位置(第1个词,第2个词...)生成一个独一无二的向量,然后直接加到该位置对应的词嵌入向量上

        输入Transformer = 词嵌入向量 + 位置编码向量

********************************************************************************************************

Transformer

Transformer的两边分开,分别形成了用于文字分类任务的BERT和用于生成任务的GPT

Bert

结合上一篇的内容,bert的上游任务,用于提取特征,其使用的方法就是掩码重建:

  • 随机遮盖输入序列中的一些部分(如文本中的一些词,图像中的一些像素块),让模型预测被遮盖的部分。

  • 模型必须根据上下文(未被遮盖的部分)来推理缺失的信息。这强迫模型建立数据各部分之间的双向关联,学习到深层次的上下文特征。BERT的上游任务(掩码语言模型)就是典型。

结构

Embedding嵌入层

与transformer的不同,bert新增了一层segment embedding,标注“这个词属于哪个句子”

此外还有一些特殊的token:

CLS = classification,可以用于做分类任务(自注意力机制中,它可以看遍全部的词,用于做整体的分析)

SEP = separate,表示句子的间断处

Pooler

把所有字符的token(多个向量)池化为一个向量,输入到后续的分类任务部分。

更多推荐