【论文笔记】Transformer

news2025/3/26 5:29:02

Transformer

2017 年,谷歌团队提出 Transformer 结构,Transformer 首先应用在自然语言处理领域中的机器翻译任务上,Transformer 结构完全构建于注意力机制,完全丢弃递归和卷积的结构,这使得 Transformer 结构效率更高。迄今为止,Transformer 广泛应用于深度学习的各个领域。

模型架构

Transformer 结构如下图所示,Transformer 遵循编码器-解码器(Encoder-Decoder)的结构,每个 Transformer Block 的结构基本上相同,其编码器和解码器可以视为两个独立的模型,例如:ViT 仅使用了 Transformer 编码器,而 GPT 仅使用了 Transformer 解码器。

Transformer Architecture

编码器

编码器包含 N = 6 N=6 N=6 个相同的层,每个层包含两个子层,分别是多头自注意力层(Multi Head Self-Attention)和前馈神经网络层(Feed Forward Network),每个子层都包含残差连接(Residual Connection)和层归一化(Layer Normalization),使模型更容易学习。FFN 层是一个两层的多层感知机(Multi Layer Perceptron)。

解码器

解码器也包含 N = 6 N=6 N=6 个相同的层,包含三个子层,分别是掩码多头自注意力层(Masked Multi-Head Attention)、编码器-解码器多头注意力层(Cross Attention)和前馈神经网络层。

其中,掩码多头自注意力层用于将输出的 token 进行编码,在应用注意力机制时存在一个注意力掩码,以保持自回归(Auto Regressive)特性,即先生成的 token 不能注意到后生成的 token,编码后作为 Cross Attention 层的 Query,而 Cross Attention 层的 Key 和 Value 来自于编码器的输出,最后通过 FFN 层产生解码器块的输出。

位置编码

递归神经网络(Recurrent Neural Networks)以串行的方式处理序列信息不同,注意力机制本身不包含位置关系,因此 Transformer 需要为序列中的每个 token 添加位置信息,因此需要位置编码。Transformer 中使用了正弦位置编码(Sinusoidal Position Embedding),位置编码由以下数学表达式给出:

P E p o s , 2 i = sin ⁡ ( p o s 1000 0 2 i / d model ) P E p o s , 2 i + 1 = cos ⁡ ( p o s 1000 0 2 i / d model ) \begin{aligned} &PE_{pos,2i} = \sin \left( \frac{pos}{10000^{2i/d_{\text{model}}}} \right)\\ &PE_{pos,2i+1} = \cos \left( \frac{pos}{10000^{2i/d_{\text{model}}}} \right) \end{aligned} PEpos,2i=sin(100002i/dmodelpos)PEpos,2i+1=cos(100002i/dmodelpos)

其中,pos 为 token 所在的序列位置,i 则是对应的特征维度。作者采用正弦位置编码是基于正弦位置编码可以使模型更容易学习到相对位置关系的假设。

下面是正弦位置编码的 PyTorch 实现代码,仅供参考。

class PositionEmbedding(nn.Module):
    """Sinusoidal Positional Encoding."""

    def __init__(self, d_model: int, max_len: int) -> None:
        super(PositionEmbedding, self).__init__()
        self.pe = torch.zeros(max_len, d_model, requires_grad=False)
        factor = 10000 ** (torch.arange(0, d_model, step=2) / d_model)
        pos = torch.arange(0, max_len).float().unsqueeze(1)
        self.pe[:, 0::2] = torch.sin(pos / factor)
        self.pe[:, 1::2] = torch.cos(pos / factor)

    def forward(self, x: Tensor) -> Tensor:
        seq_len = x.size()[1]
        pos_emb = self.pos_encoding[:seq_len, :].unsqueeze(0).to(x.device)
        return pos_emb

注意力机制

注意力机制出现在 Transformer 之前,包括两种类型:加性注意力和乘性注意力。Transformer 使用的是乘性注意力,这也是最常见的注意力机制,首先计算一个点积相似度,然后通过 Softmax 后得到注意力权重,根据注意力权重对 Values 进行加权求和,具体的过程可以表示为以下数学公式:

Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q,K,V)=\text{softmax}(\frac{QK^T}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dk QKT)V

Attention

其中,注意力计算中包含了一个温度参数 d k \sqrt{d_k} dk ,一个直观的解释是避免点积的结果过大或过小,导致 softmax 后的结果梯度几乎为 0 的区域,降低模型的收敛速度。对于自回归生成任务而言,我们不希望前面生成的 token 关注后面生成 token,因此可能会采用一个下三角的 Attention Mask,掩盖掉 attention 矩阵的上三角部分,注意力机制可以重写为:

Attention ( Q , K , V ) = softmax ( Q K T d k + M ) V \text{Attention}(Q,K,V)=\text{softmax}(\frac{QK^T}{\sqrt{d_k}}+M)V Attention(Q,K,V)=softmax(dk QKT+M)V

具体实现中,需要 mask 掉的部分设置为负无穷即可,这会使得在 softmax 操作后得到的注意力权重为 0,避免注意到特定的 token。

有趣的是,注意力机制本身不包含可学习参数,因此,在 Transformer 中引入了多头注意力机制,同时希望多头注意力能够捕捉多种模式,类似于卷积。多头注意力机制可以表示为:

MultiHead ( Q , K , V ) = Concat ( head 1 , head 2 , … , head h ) W O where  head i = Attention ( Q W i Q , K W i K , V W i V ) \begin{aligned} \text{MultiHead}(Q,K,V)=\text{Concat}(\text{head}_1,\text{head}_2,\dots,\text{head}_h)W^O\\ \text{where }\text{head}_i=\text{Attention}(QW_i^Q,KW_i^K,VW_i^V) \end{aligned} MultiHead(Q,K,V)=Concat(head1,head2,,headh)WOwhere headi=Attention(QWiQ,KWiK,VWiV)

以下为多头注意力机制的 PyTorch 实现代码,仅供参考。

from torch import nn, Tensor
from functools import partial

class MultiHeadAttention(nn.Module):
    """Multi-Head Attention."""

    def __init__(self, d_model: int, n_heads: int) -> None:
        super(MultiHeadAttention, self).__init__()
        self.n_heads = n_heads
        self.proj_q = nn.Linear(d_model, d_model)
        self.proj_k = nn.Linear(d_model, d_model)
        self.proj_v = nn.Linear(d_model, d_model)
        self.proj_o = nn.Linear(d_model, d_model)
        self.attention = ScaledDotProductAttention()

    def forward(
        self, q: Tensor, k: Tensor, v: Tensor, mask: Tensor | None = None
    ) -> Tensor:
        # input tensor of shape (batch_size, seq_len, d_model)
        # 1. linear transformation
        q, k, v = self.proj_q(q), self.proj_k(k), self.proj_v(v)
        # 2. split tensor by the number of heads
        q, k, v = map(partial(_split, n_heads=self.n_heads), (q, k, v))
        # 3. scaled dot-product attention
        out = self.attention(q, k, v, mask)
        # 4. concatenate heads
        out = _concat(out)
        # 5. linear transformation
        return self.proj_o(out)


class ScaledDotProductAttention(nn.Module):
    """Scaled Dot-Product Attention."""

    def __init__(self) -> None:
        super(ScaledDotProductAttention, self).__init__()
        self.softmax = nn.Softmax(dim=-1)

    def forward(
        self, q: Tensor, k: Tensor, v: Tensor, mask: Tensor | None = None
    ) -> Tensor:
        # input tensor of shape (batch_size, n_heads, seq_len, d_head)
        d_k = k.size()[3]
        k_t = k.transpose(2, 3)
        # 1. compute attention score
        score: Tensor = (q @ k_t) * d_k**-0.5
        # 2. apply mask(optional)
        if mask is not None:
            score = score.masked_fill(mask == 0, float("-inf"))
        # 3. compute attention weights
        attn = self.softmax(score)
        # 4. compute attention output
        out = attn @ v
        return out


def _split(tensor: Tensor, n_heads: int) -> Tensor:
    """Split tensor by the number of heads."""
    batch_size, seq_len = tensor.size()[:2]
    d_model = tensor.size()[2]
    d_head = d_model // n_heads
    return tensor.view(batch_size, seq_len, n_heads, d_head).transpose(1, 2)


def _concat(tensor: Tensor) -> Tensor:
    """Concatenate tensor after splitting."""
    batch_size, n_heads, seq_len, d_head = tensor.size()
    d_model = n_heads * d_head

参考

[1] A. Vaswani et al., “Attention is All you Need,” in Advances in Neural Information Processing Systems, Curran Associates, Inc., 2017.

[2] A. Dosovitskiy et al., “An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale,” Jun. 03, 2021, arXiv: arXiv:2010.11929.

[3] K. He, X. Zhang, S. Ren, and J. Sun, “Deep Residual Learning for Image Recognition,” Dec. 10, 2015, arXiv: arXiv:1512.03385.

[4] A. Radford, K. Narasimhan, T. Salimans, and I. Sutskever, “Improving Language Understanding by Generative Pre-Training”.

[5] hyunwoongko. "Transformer: PyTorch Implementation of ‘Attention Is All You Need’ " Github 2019. [Online] Available: https://github.com/hyunwoongko/transformer

[6] 李沐. “Transformer论文逐段精读【论文精读】” Bilibili 2021. [Online] Available: https://www.bilibili.com/video/BV1pu411o7BE/?spm_id_from=333.337.search-card.all.click&vd_source=c8a32a5a667964d5f1068d38d6182813

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2320735.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用CSS3实现炫酷的3D翻转卡片效果

使用CSS3实现炫酷的3D翻转卡片效果 这里写目录标题 使用CSS3实现炫酷的3D翻转卡片效果项目介绍技术要点分析1. 3D空间设置2. 核心CSS属性3. 布局和定位 实现难点和解决方案1. 3D效果的流畅性2. 卡片内容布局3. 响应式设计 性能优化建议浏览器兼容性总结 项目介绍 在这个项目中…

SpringSecurity——基于角色权限控制和资源权限控制

目录 基于角色权限控制 1.1 自定义 UserDetailsService 1.2 加载用户角色 1.3. 给角色配置能访问的资源(使用切面拦截,使用注解) 总结 资源权限控制 2.2. 需要有一个用户;(从数据库查询用户) 2.2 基…

红宝书第十一讲:超易懂版「ES6类与继承」零基础教程:用现实例子+图解实现

红宝书第十一讲:超易懂版「ES6类与继承」零基础教程:用现实例子图解实现 资料取自《JavaScript高级程序设计(第5版)》。 查看总目录:红宝书学习大纲 一、ES6类的核心语法:把事物抽象成“模板” 想象你要设…

Python为Word文档添加书签并打包成exe

背景简述 由于一些工作场景,需要从多个Word文档中找到出现的关键词,并阅读关键词的上下文内容。文件可能几十个,手动操作太要命了。所以python尝试处理。 目录 背景简述思路第一步、功能实现结果验证 第二步、打包成exe2-1、基础准备2-2、打…

ROS导航工具包Navigation

一,安装 Navigation工具包包含在 navigation 元功能包中。你可以通过以下命令安装: sudo apt-get install ros-noetic-navigation 如果你使用的是其他ROS版本(如Melodic),将 noetic 替换为对应的版本名称&#xff08…

资金管理策略思路

详细描述了完整交易策略的实现细节,主要包括输入参数、变量定义、趋势判断、入场与出场条件、止损与止盈设置等多个方面。 输入参数(Input): EntryFrL (.6):多头入场的前一日波动范围的倍数。 EntryFrS (.3)&#xff1…

工业软件的破局与重构:从技术依赖到自主创新的未来路径

工业软件作为现代工业的“神经与大脑”,不仅是制造业数字化转型的核心工具,更是国家工业竞争力的战略制高点。近年来,中国工业软件市场在政策驱动与技术迭代中迅猛发展,但核心技术受制于人的困境仍待突破。如何实现从“跟跑”到“…

常见中间件漏洞攻略-Tomcat篇

一、 CVE-2017-12615-Tomcat put方法任意文件写入漏洞 第一步:开启靶场 第二步:在首页抓取数据包,并发送到重放器 第三步:先上传尝试一个1.txt进行测试 第四步:上传后门程序 第五步:使用哥斯拉连接 二、后…

【Dive Into Stable Diffusion v3.5】2:Stable Diffusion v3.5原理介绍

【Dive Into Stable Diffusion v3.5】系列博文: 第1篇:开源项目正式发布——深入探索SDv3.5模型全参/LoRA/RLHF训练第2篇:Stable Diffusion v3.5原理介绍 目录 1 前言1.1 扩散模型的原理1.2 损失函数1.3 加噪流程1.4 推理流程1.5 negative pr…

英伟达黄仁勋2025GTC演讲深度解析:液冷GPU、AI工厂、机器人AI…...

目录 一、技术产品与架构升级:从芯片到算力工厂1. 新一代GPU与计算架构2. AI工厂与算力操作系统 二、AI技术演进:从生成式到物理AI1. AI发展的三大阶段2. 推理算力需求爆炸式增长 三、生态合作与行业落地1. CUDA生态与开源工具2. 跨行业合作案例 四、未来…

嵌入式项目:利用心知天气获取天气数据实验方案

【实验目的】 1、利用心知天气服务器获取指定位置天气数据 2、将天气数据解析并可视化显示到OLED屏幕 【实验原理】 【实验步骤】 官网注册

Ubuntu下用QEMU模拟运行OpenBMC

1、前言 在调试过程中,安装了很多依赖库,具体没有记录。关于kvm,也没理清具体有什么作用。本文仅记录,用QEMU成功的将OpenBMC跑起来的过程,做备忘,也供大家参考。 2、环境信息 VMware Workstation 15 Pro…

专题|Python贝叶斯网络BN动态推理因果建模:MLE/Bayes、有向无环图DAG可视化分析呼吸疾病、汽车效能数据2实例合集

原文链接:https://tecdat.cn/?p41199 作为数据科学家,我们始终在探索能够有效处理复杂系统不确定性的建模工具。本专题合集系统性地解构了贝叶斯网络(BN)这一概率图模型在当代数据分析中的创新应用,通过开源工具bnlea…

Java单例模式中的饿汉模式和懒汉模式

Java单例模式中的饿汉模式和懒汉模式 一、单例模式的显著特点单一实例全局访问 二、饿汉模式:急切的实例创建者三、懒汉模式:延迟的实例构建者1. 不考虑线程安全的初始版本2. 引入同步机制解决线程安全问题3. 优化性能:避免重复进入同步块4. …

理解操作系统(一)冯诺依曼结构和什么是操作系统

认识冯诺依曼系统 操作系统概念与定位 深⼊理解进程概念,了解PCB 学习进程状态,学会创建进程,掌握僵⼫进程和孤⼉进程,及其形成原因和危害 1. 冯诺依曼体系结构 我们常⻅的计算机,如笔记本。我们不常⻅的计算机&am…

Git的认识安装及创建配置本地仓库

目录 Git的作用安装Git创建Git仓库配置本地仓库git config user.name/email(添加配置)以及git config --unset.name/email(删除配置)git config --global user.name/email以及git config --global --unset user.name/email(name和email适用于当前机器的所有Git仓库中) 感谢各位…

【el-upload】el-upload组件 - list-type=“picture“ 时,文件预览展示优化

目录 问题图el-upload预览组件 PicturePreview效果展示 问题图 el-upload <el-uploadref"upload"multipledragaction"#":auto-upload"false":file-list"fileList"name"files":accept".png,.jpg,.jpeg,.JGP,.JPEG,.…

Uthana,AI 3D角色动画生成平台

Uthana是什么 Uthana 是专注于3D角色动画生成的AI平台。平台基于简单的文字描述、参考视频或动作库搜索&#xff0c;快速为用户生成逼真的动画&#xff0c;支持适配任何骨骼结构的模型。Uthana 提供风格迁移、API集成和定制模型训练等功能&#xff0c;满足不同用户需求。平台提…

面试常问系列(二)-神经网络参数初始化之自注意力机制

目录 &#xff08;一&#xff09;、transformer中的自注意力机制为什么要除以根号d&#xff1f; 1. 点积的方差问题 2. 缩放的作用 3. 类比初始化方法 4. 实验验证 5.总结 &#xff08;一&#xff09;、transformer中的自注意力机制为什么要除以根号d&#xff1f; 在Tra…

Linux冯诺依曼体系与计算机系统架构认知(8)

文章目录 前言一、冯诺依曼体系冯•诺依曼体系结构推导内存提高冯•诺依曼体系结构效率的方法你用QQ和朋友聊天时数据的流动过程与冯•诺依曼体系结构相关的一些知识 二、计算机层次结构分析操作系统(Operator System)驱动层的作用与意义系统调用接口(system call)用户操作接口…