

关于分析师

在此对 YouMing Zhang 对本文所作的贡献表示诚挚感谢,他毕业于东北大学信息与计算科学专业,专注机器学习、深度学习算法领域。擅长Python、Matlab仿真、神经网络、数据分析。曾担任多家科技公司算法工程师,参与过图像识别与自然语言处理等多个AI项目的研发与落地,对Transformer系列模型有丰富的应用与优化经验。
本文系统讲解了Transformer模型的核心组件——缩放点积注意力与多头自注意力,并使用PyTorch从零实现了Transformer编码器。我们将这一架构应用于两个实际任务:序列反转与集合异常检测。文中重点回答:(1)自注意力机制如何通过查询-键-值实现动态加权?(2)多头注意力为何能提升特征表达?(3)Transformer编码器为何需要残差连接与层归一化?(4)位置编码的数学原理与可视化;(5)学习率预热对训练稳定性的影响。通过完整的代码示例和结果分析,读者可快速掌握Transformer的精髓,并将其迁移至自己的研究课题。
关键词:Transformer;多头注意力;自注意力;位置编码;学习率预热;序列反转;集合异常检测;PyTorch
This paper thoroughly dissects the core components of the Transformer model—scaled dot-product attention and multi-head self-attention—and implements a Transformer encoder from scratch using PyTorch. We apply the architecture to two practical tasks: sequence reversal and set anomaly detection. Key questions addressed include: (1) How does self-attention compute dynamic weights via query-key-value? (2) Why does multi-head attention enhance feature representation? (3) Why are residual connections and layer normalization vital in the Transformer encoder? (4) The mathematical design and visualization of positional encoding; (5) How does learning rate warmup stabilize training? Complete code and experimental results are provided, enabling readers to quickly grasp the Transformer and adapt it to their own research.
Keywords: Transformer; multi-head attention; self-attention; positional encoding; learning rate warmup; sequence reversal; set anomaly detection; PyTorch
近年来,Transformer架构席卷了深度学习各大领域,从自然语言处理到计算机视觉,无不展现出强大的序列建模能力。我经常被学生和企业伙伴问及:如何真正理解并手写一个Transformer?如何用它解决非NLP领域的实际问题?
本文将带你从零构建一个Transformer编码器,包括缩放点积注意力、多头注意力、位置编码、学习率预热等全套组件,并通过序列反转任务验证其对长程依赖的捕捉能力,再通过图像集合异常检测展示其无序集合上的强大泛化性。无论你是准备毕业论文的学子,还是正在做模型选型的技术负责人,都能从中获得可直接复现的代码和可迁移的设计思路。
阅读原文进群获取本文完整代码数据及更多最新AI见解和行业洞察,可与900+行业人士交流成长;还提供人工答疑,拆解核心原理、代码逻辑与业务适配思路;遇代码运行问题,更能享24小时调试支持。
全文脉络流程图:
Transformer核心组件
│
├─ 缩放点积注意力 ──► 查询·键·值
│
├─ 多头注意力 ──► 多子空间交互
│
├─ 编码器块 ──► 残差+层归一化+前馈
│
├─ 位置编码 ──► 正弦/余弦注入顺序
│
├─ 学习率预热 ──► Adam稳定训练
│
└─ 应用任务
├─ 序列反转 (准确率100%)
└─ 图像异常检测 (准确率94%)
运行前需要安装若干依赖包。以下代码会静默安装指定版本的PyTorch Lightning、matplotlib、torchvision等。
执行后可能提示pip版本更新,忽略即可。接着导入必要的模块,并固定随机种子、配置计算设备。
输出显示“使用设备: cuda:0”,表示GPU可用。
阅读原文进群获取完整内容及更多AI见解、行业洞察,与900+行业人士交流成长。
注意力可以类比为在图书馆检索资料:你心中有一个“查询”(想了解的主题),每本书有“键”(目录关键词)和“值”(详细内容)。你比较查询与每本书的键,得出相似度分数,再根据分数聚合各书的值,最终获得综合信息。这正是**查询(Q)、键(K)、值(V)**的由来。
自注意力则是序列中的每个元素都同时充当查询、键和值,让元素间两两交互,动态决定“谁应该更关注谁”。
对于一组查询Q、键K、值V(形状为 seq_len × d_k 等),计算流程为:
Attention(Q,K,V) = softmax( QK^T / √d_k ) V
除以 √d_k 的缩放因子至关重要:当 d_k 较大时,点积结果的方差会变为 d_k 倍,导致softmax饱和到极端分布,梯度消失。缩放后方差回归1,梯度流动正常。以下为自定义实现,函数更名为 compute_scaled_dot_attn:
def computttn(query, key, value, mask=None):
dim_k = query.size()[-1]
# 计算注意力分数矩阵
scores = torch.matmul(query, key.transpose(-2, -1))
scores = scores / mt.sqrt(dim_k)
if mask is not None:
scores = scores.masked_fill(mask == 0, -9e15)
attn_weights = F.softmax(scores, dim=-1)
output = torch.matmul(attn_weights, value)
return output, attn_weights
单一注意力头可能只捕捉一种关联模式。多头注意力通过并行执行h个独立的注意力,每个头有自己的W_Q, W_K, W_V投影,最后拼接结果并再次线性投影,让模型同时关注不同表示子空间。
导师答辩高频提问:为什么要用多头而非增大单头维度? 标准答案:多个头可并行关注不同位置、不同语义特征,实验表明多头显著提升模型表达能力,且计算量可控。
以下实现 MultiHeadAttention 类(关键部分,省略了参数初始化细节):
这就像公司开会,每位员工对某个议题有不同角度的看法(多头),他们各自基于自己的关注点(查询)听取其他人的发言(键、值),最后综合各方观点得出结论。多头机制避免了“一言堂”,保留了丰富的交互信息。
一个编码器块 = 多头自注意力 + 残差连接 + 层归一化 + 前馈网络(MLP) + 再次残差连接与层归一化。残差连接保证了深层网络梯度传播,层归一化加速训练并平滑特征尺度。
由于自注意力是对称的,无法感知顺序。因此将正弦和余弦生成的位置编码直接加到输入向量上:
PE(pos,2i) = sin(pos / 10000^(2i/d_model))
PE(pos,2i+1) = cos(pos / 10000^(2i/d_model))
不同频率的波形让模型可学习相对位置关系。以下实现并可视化。
可视化编码矩阵:

横轴为序列位置,纵轴为隐藏维度,颜色代表编码值。可明显看出正弦、余弦波的不同波长。
点击标题查阅往期内容
关于 Transformer 模型,我为你整理了其核心原理、演进脉络和关键应用的深度解析。以下内容综合了公众号内的技术文章和行业报告,希望能帮助你快速建立系统性的认知。
Transformer模型在2017年由Vaswani等人提出,其革命性在于完全摒弃了传统的循环(RNN)和卷积(CNN)结构,仅依赖自注意力机制(Self-Attention) 来构建模型,从而解决了长序列依赖和训练并行化两大核心难题[1]。
你可以将Transformer想象成一个高效的“多语言翻译团队”。这个团队的核心架构是编码器-解码器(Encoder-Decoder) 结构:
Transformer的强大能力,很大程度上源于其核心的自注意力机制,特别是其“多头(Multi-Head)”设计。
自诞生以来,基于Transformer的模型家族飞速演进,但也面临一些挑战。
针对上述挑战,研究者们提出了许多创新性的解决方案,并在实践中取得了显著效果。
面对众多的Transformer变体,你可以参考以下建议:
如果你想深入了解某个特定方向,以下是一些深度报告的链接:
再单独观察某几个维度的编码曲线:

隐藏维度1和2只是初始相位不同,而维度3、4的波长增大。这种设计使得任何两个位置间的相对偏移可通过线性函数近似,有利于模型学习相对距离。
相关文章

原文链接:https://tecdat.cn/?p=44060
深度Transformer在训练初期易出现梯度不稳定,采用学习率预热(warmup)可以有效缓解。结合余弦退火,学习率先线性增长至设定值,再按余弦曲线衰减。
绘制出的学习率曲线如下:

前100次迭代从0升至1,之后余弦下降。
导师高频提问:为什么不用固定学习率? 答案:因为Adam等自适应优化器在早期会因偏置校正产生高方差,导致参数更新过大,warmup可给予模型一段“缓冲期”来稳定梯度估计。
我们将前面所有组件封装成一个通用的 TransformerPredictor 类,包含输入投影、位置编码、编码器、输出分类头,并集成优化器和学习率调度。具体实现省略核心细节,只展示接口。
后面的训练、验证、测试步骤将在具体任务子类中重写。
构造一个简单的序列反转数据集:生成0~9的随机整数序列,标签为其倒序。序列长度固定为16。
创建训练、验证、测试数据加载器,其中训练集5万条。
在 TransformerPredictor 基础上,定义 ReversePredictor,重写损失计算。
训练函数(省略部分细节):
我们使用单头、单层编码器,模型维度32,学习率5e-4,预热50步。
模型轻松完美反转序列。
调用 get_attn_maps 获取单层单头的注意力权重,并绘制热力图。

图中横轴为序列输入,纵轴为输出位置(均为原始标签)。每个单元格的颜色深度表示第i个输出对第j个输入的关注度。可以看到,模型成功学会了将对角线翻转的注意力模式:输出位置i几乎完全关注输入位置 (seq_len-1-i),从而实现了完美反转。
此任务中,模型需在一组图像(9张同类 + 1张异类)中找出“格格不入”的那一张。为减少计算量,我们先利用在ImageNet上预训练的ResNet34提取图像的高层语义特征(512维)。。
以下函数提取所有图像特征并保存到磁盘,避免重复计算。
特征形状:训练集 [50000,512],测试集 [10000,512]。
我们定义 AnomalySetDataset,每次返回一组图像特征,其中最后一个元素为异常。训练时随机抽取,测试时固定集合以保证可比性。
然后划分训练/验证集,按类别均衡采样10%作为验证。
加载器构建:
由于集合中元素无序,我们不添加位置编码,保持模型排列等变性。输出一个标量logit,经softmax得到每个图像为异常的概率,并与真实标签计算交叉熵。
训练配置:4层编码器,256维,4头,dropout 0.1,学习率5e-4,预热100步。训练后输出:
训练准确率: 96.38%
验证准确率: 96.20%
测试准确率: 94.41%
模型成功发现绝大多数异常,并且通过置换测试验证了严格的排列等变性:输入顺序变化时,输出概率仅按相同排列重排,数值几乎不变。
下面展示几个测试集样例。第一组:9张树+1张火山。

预测结果准确指向最后一张。进一步画出各层的注意力图:


可以看到,第二层头1、头3和第三层头1明显关注异常图像;而第四层所有头则降低了对异常的注意,表明高层已整合信息并做出决断。
我们也查看了错误案例:一张棕榈树被误判为建筑。


错误原因可能是拍摄角度和颜色分布与同类差异较大,导致模型混淆。
下表引自Vaswani et al. (2017),对比了自注意力、循环网络、卷积网络在计算复杂度、并行度和最长路径长度上的差异。
层类型 | 每层复杂度 | 顺序操作数 | 最大路径长度 |
|---|---|---|---|
自注意力 | O(n²·d) | O(1) | O(1) |
循环 | O(n·d²) | O(n) | O(n) |
卷积 | O(k·n·d²) | O(1) | O(logₖn) |
其中 n 为序列长度,d 为表示维度,k 为卷积核大小。自注意力在短序列上既快又具备最短梯度传播路径,非常有利于捕获长距离依赖。
导师答辩常见追问:Transformer的复杂度是O(n²),长序列怎么办? 标准答案:可通过稀疏注意力(如Longformer)、低秩近似(如Linformer)或分块注意(Reformer)来降低复杂度,目前已有大量高效Transformer变体。
本文从理论推导、代码实现到实际应用,完整呈现了Transformer编码器的核心组件。通过两个典型任务,我们验证了其强大的序列建模能力和对无序集合的适应性。主要结论如下: