【论文阅读笔记】Attention Is All You Need

news2025/1/10 17:04:41

1.论文介绍

Attention Is All You Need
2017年 NIPS
transformer 开山之作 回顾一下经典,学不明白了
Paper Code

2. 摘要

显性序列转导模型基于包括编码器和解码器的复杂递归或卷积神经网络。性能最好的模型还通过注意力机制连接编码器和解码器。我们提出了一个新的简单的网络架构,Transformer,完全基于注意力机制,完全免除了递归和卷积。在两个机器翻译任务上的实验表明,这些模型在质量上是上级的,同时具有更好的并行性,并且需要更少的训练时间。我们的模型在WMT 2014英语到德语翻译任务中达到了28.4 BLEU,比现有的最佳结果(包括集成)提高了2 BLEU以上。在WMT 2014英语到法语的翻译任务中,我们的模型在8个GPU上训练了3.5天后,建立了一个新的单模型最先进的BLEU得分为41.0,这是文献中最佳模型训练成本的一小部分。

Keywords:transformer,纯注意力机制

3.Introduction

递归模型通常沿输入和输出序列的符号位置沿着因子计算。将位置与计算时间中的步骤对齐,它们生成隐藏状态ht的序列,作为前一个隐藏状态ht-1和位置t的输入的函数。这种固有的顺序性质排除了训练示例中的并行化,这在较长的序列长度下变得至关重要,因为内存约束限制了示例之间的并行化。最近的工作通过因式分解技巧和条件计算实现了计算效率的显着提高,同时还提高了后者的模型性能。然而,顺序计算的基本约束仍然存在。注意力机制已经成为各种任务中引人注目的序列建模和转导模型的组成部分,允许在不考虑它们在输入或输出序列中的距离的情况下对依赖关系进行建模。然而,除了少数情况外,在所有情况下,这种注意力机制都与循环网络结合使用。在这项工作中,我们提出了Transformer,一个模型架构避免复发,而是完全依赖于注意力机制,以绘制输入和输出之间的全局依赖关系。Transformer支持更高的并行化,在8个P100 GPU上训练12小时后,翻译质量就能达到最新水平。

减少顺序计算的目标也构成了扩展神经GPU,ByteNet 和ConvS 2S 的基础,所有这些都使用卷积神经网络作为基本构建块,并行计算所有输入和输出位置的隐藏表示。在这些模型中,将来自两个任意输入或输出位置的信号关联起来所需的操作数量随着位置之间的距离而增长,对于ConvS 2S是线性的,而对于ByteNet是线性的。这使得学习远距离位置之间的依赖关系变得更加困难。在Transformer中,这被减少到恒定数量的操作,尽管由于平均注意力加权位置而降低了有效分辨率。自我注意力(英语:Self-attention),有时也被称为内部注意力(intra-attention),是一种将单个序列的不同位置联系起来以计算该序列的表示的注意力机制。自我注意已成功用于各种任务,包括阅读理解,抽象概括,文本蕴涵和学习任务独立的句子表征。端到端记忆网络基于循环注意机制而不是序列对齐的循环,并且已被证明在简单语言问题回答和语言建模任务中表现良好。然而,据我们所知,Transformer是第一个完全依靠自我注意力来计算其输入和输出的表示而不使用序列对齐的RNN或卷积的转换模型。

传统的递归模型通常沿着输入和输出序列的符号位置进行计算,这意味着它们需要依次处理每个符号的位置,这在处理长序列时会导致效率低下。
最近的一些研究工作尝试通过不同的技术来改善计算效率,但是仍然受到顺序计算的基本限制。注意力机制是一种常见的用于处理序列数据的方法,它允许模型在不考虑符号在输入或输出序列中的距离的情况下对它们之间的依赖关系进行建模。然而,传统的注意力机制通常与循环神经网络(RNN)结合使用,而且仍然受到顺序计算的限制。
为了克服这些限制,作者提出了一种名为Transformer的新型模型架构,它完全依赖于自我注意力机制来处理序列数据,而不使用循环神经网络或卷积。这使得Transformer能够更有效地处理长序列,并且支持更高的并行计算,因此能够更快地训练模型并获得更好的性能。Transformer已经在机器翻译等任务中取得了很好的表现。

4. 网络结构详解

大多数竞争性神经序列转导模型具有编码器-解码器结构。这里,编码器将符号表示的输入序列(x1,,xn)转换为连续表示序列z =(z1,…,Zn)。给定z,解码器然后生成输出序列(y1,…,ym)中的每一个。在每一步,模型都是自回归的,在生成下一个符号时,模型会使用先前生成的符号作为额外的输入。Transformer遵循这种整体架构,编码器和解码器均使用堆叠的自注意和逐点全连接层,结构如下图所示。
在这里插入图片描述
编码器和解码器堆栈
编码器:编码器由N = 6个相同层的堆栈组成。每层有两个子层。第一个是多头自注意机制,第二个是一个简单的,位置明智的全连接前馈网络。两个子层的每一个周围使用残差连接,然后进行层归一化。也就是说,每个子层的输出是 L a y e r N o r m ( x + S u b l a y e r ( x ) ) LayerNorm(x + Sublayer(x)) LayerNorm(x+Sublayer(x)),其中Sublayer(x)是子层本身实现的函数。为了促进这些残差连接,模型中的所有子层以及嵌入层产生维度dmodel = 512的输出。

解码器:解码器也是由一个堆栈的N = 6相同的层。除了每个编码器层中的两个子层之外,解码器还插入第三子层,该第三子层对编码器堆栈的输出执行多头注意。与编码器类似,我们在每个子层周围使用残差连接,然后进行层归一化。我们还修改了解码器堆栈中的自关注子层,以防止关注后续位置。这种掩蔽,结合输出嵌入偏移一个位置的事实,确保了位置i的预测只能依赖于小于i的位置处的已知输出。

注意力
注意力函数可以被描述为将查询和一组键值对映射到输出,其中查询、键、值和输出都是向量。输出被计算为值的加权和,其中分配给每个值的权重由查询与对应键的兼容性函数计算。

标度点积注意力:如下图所示,输入包含查询、键(维度dk)以及维度dv的值组成。计算查询与所有键的点积,将每个键除以 √ d k √dk dk,并应用softmax函数来获得值的权重。这些查询被打包到一个矩阵Q中。键和值也被打包到矩阵K和V中。我们计算输出矩阵为:
在这里插入图片描述
两种最常用的注意力函数是加法注意力和点积(乘法)注意力。点积注意力(计算相似度)与我们的算法相同,除了比例因子为 1 d k \frac{1}{\sqrt{d_k}} dk 1。加法注意力使用具有单个隐藏层的前馈网络计算兼容性函数。虽然两者在理论复杂度上相似,但点积注意力在实践中要快得多,空间效率更高,因为它可以使用高度优化的矩阵乘法代码来实现。虽然对于较小的dk值,这两种机制的表现相似,但在dk值较大的情况下,加法注意力优于点积注意力。我们怀疑,对于较大的dk值,点积的大小会变大,从而将softmax函数推到梯度非常小的区域。为了抵消这种影响,我们将点积缩放 1 d k \frac{1}{\sqrt{d_k}} dk 1
在这里插入图片描述
多头注意:我们发现,与使用 d m o d e l d_{model} dmodel维的键、值和查询来执行单个注意力函数。不同的是,使用不同的学习线性投影将查询、键和值分别线性投影h次到dk、dk和dv维是有益的。在这些查询、键和值的每个投影版本上,并行执行注意力函数,产生dv-dimensional输出值。这些数据被连接起来并再次投影,从而得到最终值,如下图所示。多头注意允许模型在不同的位置联合注意来自不同表示子空间的信息。对于一个单一的注意力头,平均化抑制了这一点。
在这里插入图片描述
其中投影是参数矩阵 W i Q ∈ R d m o d e l × d k W^Q_i ∈ R^{d_{model}×d_k} WiQRdmodel×dk W i K ∈ R d m o d e l × d k W^K_i ∈ R^{d_{model}×d_k} WiKRdmodel×dk W i V ∈ R d m o d e l × d v W^V_i ∈ R^{d_{model}×d_v} WiVRdmodel×dv W O ∈ R d v × d m o d e l W^O ∈ R^{dv ×dmodel} WORdv×dmodel。在这项工作中,采用h = 8平行注意层,或头。对于每一个,我们使用dk = dv = dmodel/h = 64。由于每个头的维数降低,总的计算成本是类似的单头注意与全维。
在这里插入图片描述
在“编码器-解码器注意”层中,查询Q来自先前的解码器层,并且存储器键K和值V来自编码器的输出。这使得解码器中的每个位置都可以覆盖输入序列中的所有位置。这模仿了序列到序列模型中典型的编码器-解码器注意力机制。编码器包含自注意层。在自关注层中,所有的键、值和查询都来自同一个地方,在这种情况下,是编码器中前一层的输出。编码器中的每个位置可以涉及编码器的前一层中的所有位置。类似地,解码器中的自关注层允许解码器中的每个位置关注解码器中的所有位置,直到并包括该位置。我们需要防止解码器中的冗余信息流,以保持自回归特性。我们通过屏蔽(设置为−∞)softmax输入中对应于非法连接的所有值来实现这一点。

位置前馈网络:除了注意力子层之外,编码器和解码器中的每一层都包含一个完全连接的前馈网络,该网络单独且相同地应用于每个位置。这包括两个线性变换,中间有一个ReLU激活。

虽然线性变换在不同位置是相同的,但它们在层与层之间使用不同的参数。另一种描述这种情况的方式是两个卷积,内核大小为1。输入和输出的维度为dmodel = 512,内层的维度为dff = 2048。

嵌入式和Softmax:与其他序列转换模型类似,使用学习的嵌入将输入令牌和输出令牌转换为维度dmodel的向量。还使用常用的学习线性变换和softmax函数将解码器输出转换为预测的下一个令牌概率。在我们的模型中,我们在两个嵌入层和pre-softmax线性变换之间共享相同的权重矩阵。在嵌入层中,我们将这些权重乘以嵌入模型。

位置编码
由于transformer不包含递归和卷积,为了让模型利用序列的顺序,必须注入一些关于序列中token的相对或绝对位置的信息。为此,在编码器和解码器堆栈的底部向输入嵌入添加“位置编码”。位置编码与嵌入具有相同的维度dmodel,因此两者可以相加。有许多位置编码的选择,学习和固定。在这项工作中,我们使用不同频率的正弦和余弦函数,
在这里插入图片描述
其中pos是位置,i是尺寸。即,位置编码的每个维度对应于正弦曲线。波长形成从2π到10000 · 2π的几何级数。之所以选择这个函数,是因为我们假设它可以让模型很容易地学会通过相对位置来参与,因为对于任何固定的偏移量k,PEpos+k都可以表示为PEpos的线性函数。我们还尝试使用学习的位置嵌入,发现两个版本产生了几乎相同的结果。我们选择正弦版本,因为它可以允许模型外推到比训练期间遇到的更长的序列长度。

为什么用自注意力
一个是每层的总计算复杂度。另一个是可以并行化的计算量,这是通过所需的最小顺序操作数来衡量的。第三个是网络中长距离依赖之间的路径长度。学习长程依赖性是许多序列转导任务中的关键挑战。影响学习这种依赖关系的能力的一个关键因素是前向和后向信号必须在网络中穿过的路径的长度。输入和输出序列中任意位置组合之间的路径越短,就越容易学习长程依赖性。

5.总结

它没有用递归和卷积,只用注意力机制。包含一个编码器一个解码器,每个都有N层,在最开始有位置编码实现序列结构信息。编码器的每层包含一个多头自注意力和一个前馈神经网络层。
解码器包含一个多头自注意力、一个前馈神经网络外加一层对输出进行多头自注意力。

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

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

相关文章

Redis部署方式(三)主从模式

在前面单机版的基础上,41为主,30为从。 一、主从搭建 1、主Redis安装 41机器redis主要配置 requirepass redis#!_41 bind 0.0.0.0 port 6379 daemonize yes 2、从redis安装 30机器redis主要配置 requirepass redis#!_30 bind 0.0.0.0 port 6380 da…

Oracle 部署及基础使用

1. Oracle 简介 Oracle Database,又名 Oracle RDBMS,简称 Oracle Oracle系统,即是以Oracle关系数据库为数据存储和管理作为构架基础,构建出的数据库管理系统。是目前最流行的客户/服务器(client/server)或…

关于Transfomer的思考

为何诞生 在说transformer是什么,有什么优势之类的之前,先谈一谈它因何而诞生。transformer诞生最重要的原因是早先的语言模型,比如RNN,由于其本身的训练机制导致其并行度不高,特别是遇到一些长句子的情况下。其次&…

面试题手撕篇

参考博客 开始之前,理解递归 手写 浅拷贝 function shallow(target){if(target instanceof Array){return [...resObj]}else{return Object.assign({},target);} }手写深拷贝 const _sampleDeepClone target > {// 补全代码return JSON.parse(JSON.stringify…

深度学习神经网络训练环境配置以及演示

🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:高性能(HPC)开发基础教程 🎀CSDN主页 发狂的小花 🌄人生秘诀:学习的本质就是极致重复! 目录 1 NVIDIA Dr…

Flink源码解析(1)TM启动

首先在看之前,回顾一下akka模型: Flink通讯模型—Akka与Actor模型-CSDN博客 注:ActorRef就是actor的引用,封装好了actor 下面是jm和tm在通讯上的概念图: RpcGateway 用于定义RPC协议,是客户端和服务端沟通的桥梁。服务端实现了RPC协议,即实现了接口中定义的方法,做具…

云原生(二)、Docker基础

Docker Docker 是一种开源的容器化平台,用于开发、部署和运行应用程序。它允许开发者将应用程序及其所有依赖项打包到一个可移植的容器中,这个容器可以在任何支持 Docker 的环境中运行,无论是开发人员的个人笔记本电脑、测试环境、生产服务器…

逆序对的数量 刷题笔记

思路 使用归并排序 在每次返回时 更新增加答案数 因为归并排序的两个特点 第一 使用双指针算法 第二 层层返回 从局部有序合并到整体有序 例如 {4 ,1 ,2 ,3} 划分到底层是四个数组 {4},{1},{3}, {…

Java项目:54 springboot工资信息管理系统453

作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本系统的使用角色可以被分为用户和管理员, 用户具有注册、查看信息、留言信息等功能, 管理员具有修改用户信息,发…

k8s部署hadoop

(作者:陈玓玏) 配置和模板参考helm仓库:https://artifacthub.io/packages/helm/apache-hadoop-helm/hadoop 先通过以下命令生成yaml文件: helm template hadoop pfisterer-hadoop/hadoop > hadoop.yaml用kube…

《操作系统实践-基于Linux应用与内核编程》第10章-Linux综合应用

前言: 内容参考《操作系统实践-基于Linux应用与内核编程》一书的示例代码和教材内容,所做的读书笔记。本文记录再这里按照书中示例做一遍代码编程实践加深对操作系统的理解。 引用: 《操作系统实践-基于Linux应用与内核编程》 作者:房胜、李旭健、黄…

vue3+ts动态表单渲染,antd的useForm改造

let fieldList: any getFormFields(fieldInfo.coreNavigationList[0].list[0].list,fieldInfo.positionCodeRespVO,isCanBeUpdateProcess.value,isDetail.value 1); fieldInfo数据格式: {"name": "默认模板","status": "ENA…

微信小程序-webview分享

项目背景 最近有个讨论区项目需要补充分享功能,希望可以支持在微信小程序进行分享,讨论区是基于react的h5项目,在小程序中是使用we-view进行承载的 可行性 目标是在打开web-view的页面进行分享,那就需要涉及h5和小程序的通讯问…

K8S CNI

OCI概念 OCI,Open Container Initiative,开放容器标准,是一个轻量级,开放的治理结构(项目),在 Linux 基金会的支持下成立,致力于围绕容器格式和运行时创建开放的行业标准。 OCI 项目…

虚拟机开机字体变大,进入系统后字体模糊

问题 虚拟机开机字体变大,进入系统后字体模糊。 原因 虚拟机配置问题。 解决办法 修改配置为如下:

【兆易创新GD32H759I-EVAL开发板】图像处理加速器(IPA)的应用

GD32H7系列的IPA(Image Pixel Accelerator)是一个高效的图像处理硬件加速器,专门设计用于加速图像处理操作,如像素格式转换、图像旋转、缩放等。它的优势在于能够利用硬件加速来实现这些操作,相比于软件实现&#xff0…

Ubuntu软件开发环境搭建

Ubuntu软件开发环境搭建 安装VMware Tools网络桥接更新软件源常用功能配置时间同步共享文件夹双向复制粘贴终端初始大小和字体设置安装必要的工具 常用指令 安装VMware Tools 点击虚拟机->安装VMware Tools… 打开终端,cd到/media/用户名/VMware Tools/下&#…

JS 事件捕获、事件冒泡、事件委托

js事件机制在开发中可以说时刻使用,例如dom绑定事件、监听其自身事件等。js事件机制有事件捕获、事件冒泡俩种机制,我们分别说下这俩种机制的使用场景。 一、概念 事件捕获顺序如下: window > document > body > div 事件冒泡顺序…

【一】【单片机】有关LED的实验

点亮一个LED灯 根据LED模块原理图,我们可以知道,通过控制P20、P21...P27这八个位置的高低电平,可以实现D1~D8八个LED灯的亮灭。VCC接的是高电平,如果P20接的是低电平,那么D1就可以亮。如果P20接的是高电平,…

14.矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]示例 2: 输入&…