战斗包子
草履虫的transformer初步理解

草履虫的transformer初步理解

架构

The Transformer- model architecture

左侧:编码器(Encoder)—— “理解输入”

左半部分负责处理和理解输入的信息(比如翻译任务中的源语言句子)。

Inputs & Input Embedding(输入与嵌入):

模型首先接收输入(Inputs),将文字转换为计算机能理解的向量(Embedding)。这里应该有一个网络,训练之后便能实现嵌入

Positional Encoding(位置编码):

《Attention Is All You Need》使用了一套基于正弦和余弦函数的数学公式来生成位置信息。

最终输入=词嵌入 (Input Embedding)+位置编码 (Positional Encoding)\text{最终输入} = \text{词嵌入 (Input Embedding)} + \text{位置编码 (Positional Encoding)}

位置编码是一个向量,它的维度(Dimension)和词嵌入的维度(dmodeld_{model})是一模一样的(通常是 512)。模型把这两个向量对应位置相加。

**Transformer 使用不同频率的正弦(Sine)余弦(Cosine)**函数来生成这些向量。

**pospos **是词在句子中的位置(比如第 1 个词,第 2 个词…)。 ii 是向量维度的索引(比如第 0,1,2,...,5110, 1, 2, ..., 511 维)。 dmodeld_{model} 是模型的维度(比如 512)。

偶数维度(2i2i)使用正弦函数:PE(pos,2i)=sin(pos100002i/dmodel)PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right)

奇数维度(2i+12i+1)使用余弦函数:PE(pos,2i+1)=cos(pos100002i/dmodel)PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right)

对于每一个位置 pospos,这 512 个维度的正弦/余弦值组合起来,是独一无二的。模型只要看一眼这个向量的波形,就知道它在句子的哪个位置。

现代演进

BERT / GPT-2: 使用了可学习的位置编码(Learnable Positional Embedding)。简单说就是不给公式,直接初始化一个矩阵,让模型在训练中自己去学每个位置最好的表示向量。

LLaMA / ChatGLM / PaLM: 使用了旋转位置编码(RoPE - Rotary Positional Embedding)。这是目前的业界主流。它不是通过“加法”把位置信息加进去,而是通过“旋转”向量的角度来注入位置信息,数学性质更好,对长文本的支持更强。

BEV特征的位置编码

正弦位置编码的2D扩展

原理:假设我们有一个 H×WH \times W 的 BEV 网格。我们把嵌入向量的维度(比如 256 维)一分为二:前 128 维:用来对 X 轴坐标 进行标准的正弦/余弦编码。后 128 维:用来对 Y 轴坐标 进行标准的正弦/余弦编码。

PE(x,y)=Concat(PE(x),PE(y))PE_{(x, y)} = \text{Concat}(\text{PE}(x), \text{PE}(y))

BEVFormer,它在初始化那层 200×200200 \times 200 的格子时,就给每个格子加上了这种 xy 坐标编码,让每个格子知道自己在车身周围的物理位置。

可学习的位置编码

初始化一个大小为 (H,W,D)(H, W, D) 的矩阵(参数),让神经网络在训练过程中**自己去“学”**每个格子应该长什么样。

优点: 灵活,能适应特定数据集的偏差。

缺点: 外推性差(换个分辨率或网格大小就需要重新训练)。

3D空间位置编码

待深入了解 PETR (Position Embedding Transformation)

核心逻辑: 视锥位置编码 (3D Coordinates Generator)
从图像出发: 对于摄像头拍到的每一张 2D 图片,我们有每个像素的坐标 (u,v)(u, v)
反投影: 利用相机的内参(Intrinsics)和外参(Extrinsics),我们可以把这些 2D 像素通过一条射线射向 3D 空间。
离散化: 在这条射线上取不同的深度点,计算出它们在真实世界(车身坐标系)中的 (x,y,z)(x, y, z) 坐标。
编码: 将这些计算出来的真实 3D 坐标 (x,y,z)(x, y, z) 输入到一个简单的神经网络(MLP)中,生成位置编码。
注入: 把这个包含了 3D 信息的编码直接加到 2D 图片特征上。

多头注意力

缩放点积注意力

与临时抱佛脚中提到的QKV相同

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

Scaled Dot-Product Attention(缩放点积注意力),它是每个“头”内部的计算方式。

为什么要除以 dk\sqrt{d_k} ? :

如果不除以这个数,当维度很高时,QKTQ \cdot K^T 的点积结果数值会非常大。

过程

Multi-Head Attention 模块为了保证输入输出维度一致(方便堆叠),在最后有一步**融合(Concat + Linear)**的操作。

  1. 拆分 (Split):假设模型维度 dmodel=512d_{model} = 512,你有 P=8P=8 个头。我们把输入的 512 维向量切成 8 份,每份 64 维。每个头只处理属于自己的那 64 维信息。
  2. 独立计算 (Parallel Attention):这 8 个头并行工作。头 1 计算出它的结果 Z1Z_1(维度 64)。…头 8 计算出它的结果 Z8Z_8(维度 64)。这里确实产生了 P 个向量(或者说是 P 组结果)。
  3. 拼接 (Concatenate) —— 关键一步:模型把这 8 个结果拼起来:MultiHead=Concat(Z1,Z2,...,Z8)\text{MultiHead} = \text{Concat}(Z_1, Z_2, ..., Z_8)拼完之后,维度又变回了 64×8=51264 \times 8 = 512
  4. 线性变换 (Linear Projection):最后,再通过一个由权重矩阵 WOW^O 控制的线性层(Linear Layer),把拼好的信息混合一下。 Final Output=Concat(Z1,...,ZP)WO\text{Final Output} = \text{Concat}(Z_1, ..., Z_P) \cdot W^O

Add & Norm(残差连接与层归一化)

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

Add (残差连接 / Residual Connection)

把输入 xx 直接加到输出上。

作用: 解决了“梯度消失”

在深层网络中,计算梯度需要运用链式法则(Chain Rule),也就是无数个导数连乘。

Lossx=Lossyyx\frac{\partial Loss}{\partial x} = \frac{\partial Loss}{\partial y} \cdot \frac{\partial y}{\partial x} \cdot \dots如果中间的导数(yx\frac{\partial y}{\partial x})都小于 1(通常如此),乘着乘着,梯度就变成 0 了————梯度消失。

有了 Add 的时候:正向公式是:y=x+F(x)y = x + F(x)我们对 xx 求导,结果是:yx=1+F(x)x\frac{\partial y}{\partial x} = 1 + \frac{\partial F(x)}{\partial x} 不会使梯度为0

右侧:解码器(Decoder)—— “生成输出”

解码器的输入是什么?

在翻译模型中:截至目前为止,已经翻译出来的词
在端到端模型中:一组固定的、可学习的“查询向量” (Learnable Object Queries)

Masked Multi-Head Attention(带掩码的多头注意力)

训练时的因果关系:

假设我们要把 “I love you” 翻译成 “我爱你”。 在训练时,我们把正确答案 “我爱你” 作为输入喂给解码器。当模型正在预测第 2 个字(应该是“爱”)时,它只能看到第 1 个字“我”。如果没有 Mask,模型通过注意力机制会偷看到后面的“爱”和“你”。

在计算 softmax(QKTdk)softmax(\frac{QK^T}{\sqrt{d_k}}) 之前,我们强行把当前位置之后的分数全部变成负无穷大(-\infty)。

自动驾驶中的应用

空间上的 Mask:Deformable Attention (变形注意力)

隐式 Mask): 这里的 Mask 不是简单的“遮住”,而是**“只看想看的地方”**。

**传统 Attention: **我(Query)要和全图所有的点(Key)算相似度。

**Deformable Attention(变种 Mask): **我(Query)只和离我最近的、或者我感兴趣的 4 个点算相似度。其他的点,默认 Mask 掉(权重为 0),根本不参与计算。

时间上的mask

轨迹预测 (Motion Prediction) —— 为了“不穿越”
当模型在预测 t=2t=2 的位置时,我们必须把 t=3,4,5,6t=3, 4, 5, 6 的真实轨迹 Mask 掉。这使用标准的因果掩码(Causal Mask / Triangular Mask)。

训练策略上的 Mask:MAE (Masked Autoencoders) —— 为了“脑补”

随机遮挡: 把摄像头拍到的画面,或者 BEV 网格,随机抠掉 40% 的块(Mask 掉,设为 0)。

让模型猜: 强迫模型利用剩下的 60% 信息,去还原那被遮住的 40%。

为什么这么做? 这能逼迫模型理解环境的连续性。 比如:Mask 遮住了车道线的中间一段。模型必须学会:“上面有线,下面也有线,那中间这个黑洞(Mask)里肯定也是线。” 这种 Mask 不是为了生成,而是为了训练模型对环境的深度理解能力。

(⊙﹏⊙)

随后的ADD & NORM不再赘述

又是一个Multi-Head Attention(交互注意力 / Cross Attention)

输入来源:

Query (Q) 来自哪里? 来自Decoder(下方,也就是刚刚经过 Masked Attention 处理过的信息)。
Key (K) 和 Value (V) 来自哪里? 来自Encoder(左边,也就是对源句子的完整理解)。

Cross Attention 的输出,本质上是“被注入了新信息的 Query”。

如端到端自动驾驶中为
输出 = “抓取到了物体特征的 Query”
不过还不是坐标框 (x, y, w, h)。它只是一串包含了物体信息的数学特征。

右侧的前馈神经网络

根据attention去生成包含规划、决策信息的高维向量。大概这样粗糙理解吧

最后的输出

端到端自动驾驶与图中的翻译模型不同

翻译模型:

Linear 的作用:拉伸(Mapping)

  • Decoder 输出来的向量只有 512 维。但是我们词表里有 30,000 个单词。
    所以这个 Linear 层的作用是:把 512 维的特征,强行拉伸成 30,000 维 的超长向量。每一维对应一个单词的打分(Logits)。

Softmax 的作用:归一化(Probability)

  • Linear 输出的分数可能是 [10.5, -3.2, 55.0, …],这没法看。Softmax 把它们变成概率(加起来等于 1):[0.1, 0.0, 0.9, …]。意思就是:有 90% 的概率是单词 C,有 10% 的概率是单词 A。

自动驾驶

要预测的是轨迹坐标 (x,y)(x, y),这是一个回归任务(Regression),而不是分类任务。

结构: 通常是 MLP(即 Linear -> ReLU -> Linear)。

为什么用 MLP? 因为轨迹是很复杂的曲线,一层 Linear 往往拟合得不够准,多加一层 ReLU 能让它画出更顺滑的弯道。

没有softmax

本文作者:战斗包子
本文链接:https://paipai121.github.io/2025/11/23/工作/草履虫的transformer初步理解/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可