🌈Transformer说人话版(二)位置编码 【持续更新ing】

🟡序章:Transformer的并行缺陷

Transformer有超强的视力,它的核心武器------自注意力机制正是让它能一步到位地处理句子中的所有词,计算它们之间错综复杂的关系,这比 RNN/LSTM 那样一个词一个词地"读"要快得多,也强大得多。所以它可以一瞬间看到一本书里的每一个字(并行处理)。但他有个的缺陷:他看到的所有字都像是漂浮在空中,分不清哪个字在哪个字前面。对他来说,"我爱你"和"你爱我"看起来毫无区别,都是"我"、"爱"、"你"三个字。

而语言中,顺序就是一切。"狗咬人"和"人咬狗"天差地别。因此,Transformer 必须有一个额外的机制来弥补这个缺陷,每个漂浮的字挂上一个"位置坐标牌"。这个机制,就是位置编码PE (Positional Encoding)

我们以 "小姜今天没有撸铁"这个句子为例,看这个"坐标"是怎么制作,怎么挂上去的。

🟡第一步:词语到数字------Tokenization词元化

计算机只认数字(本质还是二进制)。第一步就是把文字转换成它能理解的数字ID。这个过程叫 Tokenization

  • "小姜" -> Token 1、 "今天" -> Token 2、 "没有" -> Token 3、"撸铁" -> Token 4

实际应用中模型其实会用更细的粒度,比如把"撸铁"拆成"撸"和"铁"两个子词(Subword),原理完全一样。

🟡第二步:词语到语义------Embedding (词嵌入)

有了数字ID,模型依然不知道这些词是什么意思。我们需要一个"含义字典",把每个ID转换成一个具有意义的向量。这个字典就是 Embedding Layer

🔥 千万别混淆Embedding LayerEmbedding Model

Embedding Layer 只是一个层而已,是一个静态字典,不能单独使用。而 Embedding Model 是一个完整的神经网络架构,用于训练或生成词向量。像 Word2Vec 就是一个 Embedding Model,它通过预测上下文等任务训练出词向量,训练完成后输出的其实就是一个固定的 Embedding Layer,没有自注意力,不能根据上下文动态改变词义。而像 BERT 也是Embedding Model,它不仅包含 Embedding Layer,还通过自注意力机制动态生成上下文相关的语义向量,能真正体现词在不同语境中的意义。

  • 向量维度 (d_model) : 我们设定为 5维,方便观察。真实模型中通常是 768 或更高。
  • "小姜"的肖像: 可能在"人名"这个特征维度上数值很高。
  • "撸铁"的肖像: 可能在"动作"这个特征维度上数值很高。

这些特征具体是什么,我们不用管,模型会在训练中自己学习。假设模型学完后,我们得到了每个词的"含义向量"

  1. Token 1 ("小姜") : embedding_小姜 = [0.1, 0.5, -0.2, 0.8, 0.3]
  2. Token 2 ("今天") : embedding_今天 = [-0.3, 0.7, 0.1, -0.5, 0.9]
  3. Token 3 ("没有") : embedding_没有 = [0.6, -0.1, 0.3, 0.2, -0.4]
  4. Token 4 ("撸铁") : embedding_撸铁 = [-0.4, 0.2, -0.7, 0.9, 0.1]

到此为止,我们有了四个包含"词义"的向量。但就像前面说的,如果我们把这四个向量直接丢给 Transformer,它看到的是一团乱麻,不知道谁是谁的前后桌。


🟡 补充: One-Hot Encoding (独热编码)------最纯粹的稀疏编码

在 Tokenization 和 Embedding 这俩环节之间,还存在一个"稀疏编码"的概念阶段。切记,这是概念阶段, 是因为在实际操作中,它被 Embedding 层这个更高效率的机制"吸收"掉了。但讲清楚这个东西可以让你对 Embedding 的理解瞬间清晰好几倍。

在你得到 Token ID 之后,比如:

  • "小姜" -> ID: 28、"今天" -> ID: 15、 "没有" -> ID: 99、 "撸铁" -> ID: 1024

在理论上,最朴素地表示这些词的方法,就是 One-Hot Encoding,假设我们的整个词典里有 10,000 个不同的词(Tokens)。那么,我们可以用一个长度为 10,000 的向量来表示任何一个词。这个向量只有一个位置是 1,这个 1 所在的位置,就对应着这个词的 ID,其余的位置,全部都是0。举个例子 (假设词典大小为 10,000):

  • 小姜" (ID=28) 的独热编码向量是: [0, 0, ..., 0, 1, 0, ..., 0] (只在第28个位置是1)
  • 今天" (ID=15)的独热编码向量是: [0, ..., 0, 1, 0, ..., 0] (只在第15个位置是1)
  • 撸铁" (ID=1024)的独热编码向量是: [0, ..., 0, 1, 0, ..., 0] (只在第1024个位置是1)

这种编码方式虽然简单纯粹,但有几个致命的缺陷,这也是为什么我们需要 Embedding 层的原因:(1)首先是维度灾难和计算效率低下,如果你的词典有5万个词,那每个词的向量就是5万维,两个5万维的向量做乘法,其中99.99%的计算都是"乘以0",这是巨大的浪费,(2)而且点积本身也没任何意义,这就是最致命的一点,因为任意两个不同的独热编码向量都是正交的。这意味着它们的点积永远是0。 对于模型来说,"国王"和"王后"的相似度,与"国王"和"香蕉"的相似度,竟然是一样的(都是0),这完全丢失了词语之间的语义关联。

Embedding 层的作用,就是为了解决上述稀疏编码的所有问题。你可以把 Embedding 层想象成一个高效的可学习的"压缩机"。输入一个词的 ID (比如 28)。输出一个低维度的、包含丰富语义的稠密向量。从概念上讲,Embedding 层就是一个巨大的 "查询表" 而已。你可以想象它是一张有 10,000 行、5 列的表格(行数=词典大小,列数=Embedding维度)。

erlang 复制代码
                                   Embedding Layer

                  |  dim_0 |  dim_1 |  dim_2 |  dim_3 |  dim_4
            ------|--------|--------|--------|--------|--------
            ID 0  |  ...   |  ...   |  ...   |  ...   |  ...
            ...   |  ...   |  ...   |  ...   |  ...   |  ...
            ID 15 | -0.3   |  0.7   |  0.1   | -0.5   |  0.9     <-- "今天"的Embedding
            ...   |  ...   |  ...   |  ...   |  ...   |  ...
            ID 28 |  0.1   |  0.5   | -0.2   |  0.8   |  0.3     <-- "小姜"的Embedding
            ...   |  ...   |  ...   |  ...   |  ...   |  ...
            ID 1024| -0.4  |  0.2   | -0.7   |  0.9   |  0.1     <-- "撸铁"的Embedding
            ...   |  ...   |  ...   |  ...   |  ...   |  ...

当我们给 Embedding 层输入 ID 28 时,它就去这个大表格里,把第 28 行的那个 5 维向量取出来,作为输出。这个大表格里的所有数值,都不是固定的,它们是模型的可训练参数。在模型训练的过程中,这些数值会不断被优化调整,最终使得意思相近的词在向量空间中的位置也相互靠近。怎么训练?那就是靠神经网络BP训练了

🔥Embedding Layer 本身在训练完成后是静态的。无论是 Word2Vec 还是 Transformer

因为Embedding 层本质上就是一个固定的查询表:一旦模型训练完成,这个矩阵就固定下来了。输入相同 ID就会输出相同向量,对于同一个词 ID无论是 Word2Vec 还是训练好的 Transformer 模型,Embedding 层本身总是会输出完全相同的那个 D 维向量。这一点上,两者没有区别。所以再次强调,推理阶段(使用模型时)的参数是冻结的,不变的。

🔥Transformer的"动态语义" 不是 Embedding Layer本身,而是整个架构最终输出的词表示

这才是关键的区别: Word2Vec 模型输出的就是EmbeddingLayer这个表 。 因为Word2Vec 模型本身非常浅,它的输出层(那个 <math xmlns="http://www.w3.org/1998/Math/MathML"> W W </math>W 矩阵)只用于训练,最终产品就是那个 Embedding 矩阵,没有下一步了!所以它没啥使用阶段,没有推理阶段,它就是训练出一个表给被人当做一个层用而已。

而Transformer是有训练阶段和推理阶段的,Embedding Layer 仅仅是模型的第一层而已,提供个基本语义就行,真正的动态上下文理解能力是由后续强大的 Transformer 层赋予的。想象你是一个机器人,面对一个对话或句子,你需要判断"苹果"是水果还是手机。你会:

  1. 读取"苹果"的基础属性(TokenID 直接从 Embedding Layer 里去找稠密向量 )。
  2. 观察周围词(上下文)的描述(进入到注意力层,Query--Key 机制)。
  3. 根据这些描述决定你更应该关注哪几个词(注意力分配)。
  4. 从这些词那里"取材"来补充或调整你对"苹果"的理解(加权组合 Value 向量)。

🟡 第三步:词语与位置------Positional Encoding

首先回答这个问题,为什么同一位置在不同句子里,位置向量必须是一样的?

  • 因为位置编码不关心词的内容,只关心句中顺序,你八竿子打不着的句子无所谓,但是位置3的PE,都是一样的
  • 它的目的只是给模型一个"坐标系"而已,让模型去组合词Embedding和位置Embedding共同决定含义。
  • 词Embedding告诉你"这是什么词",位置Embedding告诉你"它在什么位置"。

因为位置向量在任何上下文里都一致,模型才能稳定地学会相对位置规律,而不是死记硬背特定的组合。

在看公式前,先搞清楚为什么不直接用整数0,1,2...当作位置?

这是很多人一开始最自然的想法: "给'小姜'的向量加0,给'今天'的向量加1,依次递增,多直观!"但这样神经网络的训练会崩盘,有三个原因:

🔘数值灾难(盐比菜多)

词嵌入(Embedding)向量里的数,通常都是-1到1之间的小数,比如 0.1-0.3,这是它们经过训练自动调节出来的范围。如果你直接把位置编号当作一个整数加进去,比如第500个词加上499,这个499就像一勺比菜还多的盐,把词本身的语义彻底"淹没"掉。模型只会盯着这个巨大数字,完全失去对词语含义的敏感度。

🔘泛化灾难(没见过世面)

这里最容易搞混:

位置ID(pos)只是一个整数
但我们用它生成的是一个高维连续向量,它和词Embedding是同样维度(比如512或1024)才能直接相加。

所以:"100比99大1"这个整数关系对神经网络没有任何意义。因为它只看位置ID映射成的向量,而新的编号就对应从未见过的新向量。假设训练时,你的模型只见过最长100个词的句子,所以它只接触过0到99这100个位置编号。测试时突然来了一句120个词的句子,于是模型看到了全新的位置ID:100、101、102...

虽然在我们人看来,"100比99大1",它们有清晰的顺序,但对模型来说,位置编码不是整数本身,而是把这个编号映射成一个高维的向量。重要的事情再说一遍:位置编码不是ID,是和EmbeddingLayer一样的高维向量!ID只是生成这个PE的一个参数而已,所以对于ID而言,100比99大,100在99后面没问题,但是PE是高维向量,你怎么能知道ID为100的token的PE,在ID为99的token的后面?理解不了,因为它压根都没见过 EmbeddingID100

scss 复制代码
ID
99 和 100

机器中看到是PE
PE(99) =  [a₁, a₂, a₃, ...a1024]
PE(100) = [b₁, b₂, b₃, ...b1024] (这是俩向量的位置比较!)

所以,要用一种数学函数,把任意位置编号映射成固定的、连续的、高维向量,这样即使位置编号再大,生成的向量依然是可解释、规律的。


🔘关系灾难(远近不分)

Transformer的核心是Self-Attention,它最关心的不是绝对位置,而是词与词之间的相对距离

举个例子:

  • "我吃苹果"里,"我"在"吃"前面一个位置。
  • "苹果吃我"里,"我"在"吃"后面一个位置。

如果你只把位置当整数编号(0,1,2...),模型必须死记硬背每一对位置的关系:

(3,5)、(10,12)、 (57,59)...这都是隔了2,但是还是那句话,你能知道这都是隔了2,但是它的PE是高维向量,不是ID,就是需要死死记住 [a₁, a₂, a₃, ...a1024] [b₁, b₂, b₃, ...b1024] 这是一对儿,中间隔了2,是必须"背下来"所有可能组合,而不是"理解"它们之间的共同规律。而最理想的方式,不管哪个绝对位置,只要相对距离是2,就能用一模一样的方式来表示它们的关系。而不是让模型单独死死记住(5,3)和(50,48),都是距离2。

🔘绝对位置与相对位置

为啥两者都需要:

  • 绝对位置:告诉模型"这是句首"或"这是句尾",有些特殊含义(比如BERT中第一个位置是[CLS])。
  • 相对位置:帮助模型理解词语之间的距离关系。更重要

绝对位置的核心作用是为句子中的每个词提供一个"全局标签"告诉模型"这个词在句子的哪个位置",就是特殊位置的"锚点",语言中存在大量依赖"绝对位置"的特殊场景:

  • 句首标记:如BERT中的[CLS]必须固定在第一个位置,作为全句的"代表符号";
  • 句尾标记:如句号.通常出现在最后一个位置,标志句子结束;
  • 结构化文本:如诗歌的"起承转合"、代码的"缩进层级",都依赖绝对位置定义规则。

绝对位置和相对位置哪个重要? 其实就是相对位置更重要,后续的RoPE的旋转矩阵等技术就走向了更纯粹的相对位置编码,并取得了更好的效果。但原始 Transformer 用一个巧妙的绝对位置编码方案来高效实现相对位置的计算,同时保留了绝对位置的"锚点"作用。

终极方案:用绝对位置来实现相对位置计算

就像给每个城市一个固定的GPS坐标(经纬度):

  • 经纬度是绝对的。
  • 任意两点之间的相对距离,可以直接从经纬度计算出来。而不用把所有城市两两距离都预先存下来。

Transformer的PE,就是让每个位置有一个绝对的高维"坐标" ,而这个坐标用sincos函数生成就具备以下能力:

  • 解决数值灾难:不会溢出(所有值在[-1,1]之间)
  • 解决变长问题:无限扩展(任何大编号都能算)10个token的句子,9992321个token的句子,无所谓。
  • 解决关系灾难:因为三角函数具有平移规律,所以相对关系本身就编码进去了,不用死记硬背

🔘数学定义Positional Encoding公式

当Embedding维度为1024时,位置编码(PE)的维度与Embedding维度一致(1024维)。根据公式:

  • 偶数维度(0, 2, 4...1022)共512维,由 <math xmlns="http://www.w3.org/1998/Math/MathML"> sin ⁡ ( p o s 1000 0 2 i / d m o d e l ) \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right) </math>sin(100002i/dmodelpos)计算;
  • 奇数维度(1, 3, 5...1023)共512维,由 <math xmlns="http://www.w3.org/1998/Math/MathML"> cos ⁡ ( p o s 1000 0 2 i / d m o d e l ) \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right) </math>cos(100002i/dmodelpos)计算。

因此,位置888的PE向量其实由512个sin值和512个cos值拼接而成。

每个位置索引(pos)唯一对应一组sin和cos值。例如,pos=0时,所有偶数维的sin值为 <math xmlns="http://www.w3.org/1998/Math/MathML"> sin ⁡ ( 0 ) = 0 \sin(0)=0 </math>sin(0)=0,奇数维的cos值为 <math xmlns="http://www.w3.org/1998/Math/MathML"> cos ⁡ ( 0 ) = 1 \cos(0)=1 </math>cos(0)=1;pos=1时,偶数维的sin值为 <math xmlns="http://www.w3.org/1998/Math/MathML"> sin ⁡ ( 1 1000 0 2 i / d m o d e l ) \sin\left(\frac{1}{10000^{2i/d_{model}}}\right) </math>sin(100002i/dmodel1),奇数维的cos值为 <math xmlns="http://www.w3.org/1998/Math/MathML"> cos ⁡ ( 1 1000 0 2 i / d m o d e l ) \cos\left(\frac{1}{10000^{2i/d_{model}}}\right) </math>cos(100002i/dmodel1),与pos=0的向量不同。

三角函数的平移公式:

sin(a+b)cos(a+b)都可以表示为sin(a)cos(a)的线性组合。

所以:

任意两个位置的相对位置差,可以通过对它们的位置向量做一个线性变换直接计算得到。

这就是为什么模型能够仅凭绝对位置向量推断相对位置 ,不需要把所有组合背下来。任意位置pos+k的PE向量可以通过pos的PE向量进行固定线性变换得到。例如:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> sin ⁡ ( p o s + k 1000 0 2 i / d m o d e l ) = sin ⁡ ( p o s 1000 0 2 i / d m o d e l ) cos ⁡ ( k 1000 0 2 i / d m o d e l ) + cos ⁡ ( p o s 1000 0 2 i / d m o d e l ) sin ⁡ ( k 1000 0 2 i / d m o d e l ) \sin\left(\frac{pos+k}{10000^{2i/d_{model}}}\right) = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right)\cos\left(\frac{k}{10000^{2i/d_{model}}}\right) + \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right)\sin\left(\frac{k}{10000^{2i/d_{model}}}\right) </math>sin(100002i/dmodelpos+k)=sin(100002i/dmodelpos)cos(100002i/dmodelk)+cos(100002i/dmodelpos)sin(100002i/dmodelk)
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> cos ⁡ ( p o s + k 1000 0 2 i / d m o d e l ) = cos ⁡ ( p o s 1000 0 2 i / d m o d e l ) cos ⁡ ( k 1000 0 2 i / d m o d e l ) − sin ⁡ ( p o s 1000 0 2 i / d m o d e l ) sin ⁡ ( k 1000 0 2 i / d m o d e l ) \cos\left(\frac{pos+k}{10000^{2i/d_{model}}}\right) = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right)\cos\left(\frac{k}{10000^{2i/d_{model}}}\right) - \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right)\sin\left(\frac{k}{10000^{2i/d_{model}}}\right) </math>cos(100002i/dmodelpos+k)=cos(100002i/dmodelpos)cos(100002i/dmodelk)−sin(100002i/dmodelpos)sin(100002i/dmodelk)

这意味着,模型只要学会"从pospos+k的变换规则"(即上述线性变换),就能通过任意pos的PE向量推导出pos+k的PE向量,无需重新学习。因此相对位置k的差异信息被编码在向量的线性关系中。通俗解释时,可以简化为:"句中第三个词的PE向量(无论句子多长)会和另一个句子中第三个词的PE向量有相似的'变化规律',模型能通过这种规律推断它们的相对位置。"

🔘为什么要用不同频率?

以一个句子为例感受不同频率的正弦/余弦函数如何捕捉不同粒度的位置信息

共20个词,位置索引0~19

"小明早上8点在公园跑步时遇到了小红,两人聊了关于最近上映的电影《流浪地球3》的剧情,觉得特效非常震撼。"

模型需要理解句子中"词与词的相对位置",比如:

  • 局部关系:"小明"(位置0)和"跑步"(位置4)差4个词(局部距离);
  • 中等距离:"早上8点"(位置2-3)和"公园"(位置5)差3个词;
  • 全局关系:"小明"(位置0)和"电影《流浪地球3》"(位置12-16)差12个词(大跨度)。

频率的数量由词的Embedding维度决定,具体是 <math xmlns="http://www.w3.org/1998/Math/MathML"> d − m o d e l / 2 d-model/2 </math>d−model/2种,比如 <math xmlns="http://www.w3.org/1998/Math/MathML"> d − m o d e l d-model </math>d−model=1024时,i的取值数量是512种,对应512种频率;如果是512维,则i的取值数量是256种,对应256种频率。

​这里假设用3种不同频率的正弦函数编码(对应i=0、i=1、i=2)​​:

这里简化公式,用 <math xmlns="http://www.w3.org/1998/Math/MathML"> freq i = 1 1000 0 2 i / 5 \text{freq}_i = \frac{1}{10000^{2i/5}} </math>freqi=100002i/51(d_model=5)模拟不同频率,计算每个位置pos的sin值(偶数维)和cos值(奇数维)。

🔵高频编码(i=0,频率最高)

高频编码对"小距离"(如相邻词差1、差2)极其敏感,微小变化会导致sin/cos值剧烈波动。

位置pos 高频sin值(偶数维) 高频cos值(奇数维) 直观解释(小距离敏感)
0 sin(0/10000⁰)=0 cos(0/10000⁰)=1 起点,小距离变化的"基准点"
1 sin(1/10000⁰)=sin(1)≈0.84 cos(1/10000⁰)=cos(1)≈0.54 与pos0差1,sin值从0→0.84(剧变)
2 sin(2/10000⁰)=sin(2)≈0.91 cos(2/10000⁰)=cos(2)≈-0.42 与pos1差1,sin值从0.84→0.91(仍明显变化)
3 sin(3/10000⁰)=sin(3)≈0.14 cos(3/10000⁰)=cos(3)≈-0.99 与pos2差1,sin值从0.91→0.14(骤降)
... ... ... ...

高频编码能清晰捕捉"相邻词"(差1)、"隔1词"(差2)等小距离的变化------模型通过它知道"小明(0)和跑步(4)之间隔了3个词(差3)",甚至"跑步(4)和小红(7)之间差3"。

🔵中频编码(i=1,频率中等)

对"中等距离"(如差5、差10)敏感,需要位置差较大才会引起sin/cos值明显变化。

位置pos 中频sin值(偶数维) 中频cos值(奇数维) 直观解释(中等距离敏感)
0 sin(0/(10000²/5))≈0 cos(0/(10000²/5))≈1 起点,中等距离的"基准点"
5 sin(5/(10000²/5))≈sin(5/40000)≈0.00012 cos(...)≈0.99999999 与pos0差5,sin值几乎不变(0→0.00012)
10 sin(10/(10000²/5))≈sin(10/40000)≈0.00031 cos(...)≈0.99999999 与pos5差5,sin值仍几乎不变(0.00012→0.00031)
15 sin(15/(10000²/5))≈sin(15/40000)≈0.00047 cos(...)≈0.99999999 与pos10差5,sin值缓慢增加(0.00031→0.00047)
... ... ... ...

中频编码对"差5""差10"等中等距离更敏感------模型通过它知道"小明(0)和公园(5)之间差5",但"小明(0)和电影(12)之间差12"需要结合低频编码才能捕捉。

🔵低频编码(i=2,频率最低)

对"大距离"(如差10、差20)敏感,需要位置差极大才会引起sin/cos值明显变化。

位置pos 低频sin值(偶数维) 低频cos值(奇数维) 直观解释(大距离敏感)
0 sin(0/(10000⁴/5))≈0 cos(0/(10000⁴/5))≈1 起点,大距离的"基准点"
10 sin(10/(10000⁴/5))≈sin(10/100000000)≈0 cos(...)≈1 与pos0差10,sin值几乎不变(0→0)
20 sin(20/(10000⁴/5))≈sin(20/100000000)≈0 cos(...)≈1 与pos10差10,sin值仍几乎不变(0→0)
... ... ... ...

低频编码对"差10""差20"等大距离更敏感------模型通过它知道"小明(0)和电影(12)之间差12",但"小明(0)和跑步(4)之间差4"需要结合高频编码才能捕捉。前面维度 (i值小) → 高频 (放大镜)... (平滑过渡) ..到后面维度 (i值大) → 低频 (广角镜) 。 例子中为了简化,将i=0, 1, 2分别作为高、中、低的代表。

每个位置的PE向量由高频、中频、低频的sin/cos值拼接而成(比如d_model=5时,是2组sin+2组cos+1组sin)。模型通过这些值的组合,既能看到"小明和跑步差3"的局部细节,又能看到"小明和电影差12"的全局结构------这就是不同频率位置编码的核心作用,高频编码是"放大镜",专门看"相邻词"的小距离;中频是"望远镜",专门看"隔几句"的中等距离;低频是"广角镜",专门看"句首到句尾"的大距离。三者拼接,模型才能"既看清局部,又看懂全局"!

🟡第四步:语义加位置

万事俱备,只差临门一脚。现在每个词的"含义向量"(Embedding)和它对应位置的"坐标向量"(Positional Encoding)逐个维度相加

scss 复制代码
*   "小姜" (位置 0):
    `Input_小姜 = embedding_小姜       +      pos_encoding_0`
    `=     [0.1, 0.5, -0.2, 0.8, 0.3] + [0.0, 1.0, 0.0, 1.0, 0.0]`
    `= [0.1, 1.5, -0.2, 1.8, 0.3]`

*   "今天" (位置 1)*
    `Input_今天 = embedding_今天       +     pos_encoding_1`
    `= [-0.3, 0.7, 0.1, -0.5, 0.9]    + [0.84, 0.54, 0.016, 0.999, 0.00016]`
    `= [0.54, 1.24, 0.116, 0.499, 0.90016]`

最终,送入 Transformer Encoder 的输入就是这一串融合了"含义"和"位置"的新向量。


©唐山市环境科学规划研究院

唐山市环境规划科学研究院(唐山市生态环境宣传教育中心)是唐山市生态环境局直属的事业单位。我院以科学研究为主体、技术服务为支撑,创新发展模式,注重发展质量,历经唐山市环保事业发展的各个阶段。以"为生态环境保护提供技术服务"为宗旨,开展大气、双碳、水、海洋、土壤、固废、噪声、规划、排污许可等多个领域的研究及成果运用,在生态规划编制、重污染天气应急、减污降碳、水(海洋)资源分析、土壤污染调查、EOD项目、无废城市、企业诊所、环保管家、智慧环保平台开发等方面持续深耕,为生态环境保护提供系统化解决方案。

由作者个人全栈开发的垂直模型系统:唐山小环,是一个知识图谱+混检的双擎多模态RAG系统,专注于环保领域,现位于河北省科技厅持续展示,欢迎相关从业者咨询我院。

相关推荐
叶子爱分享1 小时前
计算机视觉与图像处理的关系
图像处理·人工智能·计算机视觉
鱼摆摆拜拜1 小时前
第 3 章:神经网络如何学习
人工智能·神经网络·学习
一只鹿鹿鹿1 小时前
信息化项目验收,软件工程评审和检查表单
大数据·人工智能·后端·智慧城市·软件工程
张较瘦_1 小时前
[论文阅读] 人工智能 | 深度学习系统崩溃恢复新方案:DaiFu框架的原位修复技术
论文阅读·人工智能·深度学习
cver1231 小时前
野生动物检测数据集介绍-5,138张图片 野生动物保护监测 智能狩猎相机系统 生态研究与调查
人工智能·pytorch·深度学习·目标检测·计算机视觉·目标跟踪
学技术的大胜嗷1 小时前
离线迁移 Conda 环境到 Windows 服务器:用 conda-pack 摆脱硬路径限制
人工智能·深度学习·yolo·目标检测·机器学习
还有糕手1 小时前
西南交通大学【机器学习实验10】
人工智能·机器学习
江瀚视野1 小时前
百度文心大模型4.5系列正式开源,开源会给百度带来什么?
人工智能
聚铭网络2 小时前
案例精选 | 某省级税务局AI大数据日志审计中台应用实践
大数据·人工智能·web安全
涛神-DevExpress资深开发者2 小时前
DevExpress V25.1 版本更新,开启控件AI新时代
人工智能·devexpress·v25.1·ai智能控件