[论文解读]Attention is all you need

本文深入解析了Google在2017年提出的自我注意(self-attention)机制,详细介绍了其在机器翻译任务中的应用,以及如何通过摒弃RNN单元实现并行训练。文章还讨论了自我注意与传统注意力机制的区别,提供了模型结构和技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述


最早提出self-attention思想的就是google17年这篇著名的论文了。
  • 动机

传统的rnn难于并行,而最近流行的attention往往会利用rnn。总之为了解决无法并行训练问题,google提出了self-attention,完全摒弃了rnn单元,从而做到并行训练。
在这篇论文之前,facebook AI lab就提出了一种解决这个问题的方法,就是用cnn代替rnn单元来实现并行,具体发表在论文《Convolutional Sequence to Sequence Learning》。google提出用self-attention代替rnn,也是对facebook的一种回应吧。


  • 背景

self-attention被google利用在了机器翻译上,目前比较流行的是attention-based机器翻译模型,基本已经取代encoder-decoder模型。但大多数仍是以rnn为基本单元。google的self-attention就是对传统的机器翻译模型进行改进,摒弃了rnn单元。要想深刻理解self-attention,我们首先先了解一下传统的机器翻译模型。

传统attention-based机器翻译模型代表论文《Neural machine translation by jointly learning to align and translate》,基本网络框图如下:

这里写图片描述
---------------------------------------------------图1-----------------------------------------------

图1就是传统的attention-based MT。它的一些基本公式有:
这里写图片描述
这里写图片描述
这里写图片描述
这种结构google在论文中也有提到过,并被划分成一类attention。


  • 思考

以传统attention-based MT为背景,现在想要把rnn单元去掉,也换成attention。我们来看看google是怎么做的,首先我们需要先了解attention的概念:

  • attention的概念和分类
    google是最先形式化地提出attention地概念的。它把attention的三个重要组件分别称为key,value和query
    直接解释这三个名词可能会很抽象难懂。我们从传统的attention-based MT模型入手。在图1中,query就是解码层的s,key和value都是编码层的输出o。字面意思上来说,query是查询,即:我与你们的相似度是多少?key是键,即query要比较的值,value是值,一个key对应一个value,即query与我的key相似度为a,则我这个值对query的贡献度就为a。那么每个位置解码的时候,query(s)会分别计算与编码层各个位置key的相似度,把相似度做为对应value的权重,最后此位置的attention的输出即为所有位置value的加权输出。即用公式表示为:
    这里写图片描述


    论文也对attention进行了分类,query来自于解码层,key和value来自于编码层时叫vanilla attention(论文中并没有这么说),即最基本的attention。query,key和value都来自编码层的叫self attention

于是,很自然的,把rnn换成self-attention。

  1. 在编码层,输入的word-embedding就是key,value和query,然后做self-attention得到编码层的输出。这一步就模拟了图1中的编码层,输出就可以看成图1中的h。
  2. 然后模拟图1中的解码层,解码层的关键是如何得到s,即用来和编码层做attention的query,我们发现,s与上个位置的真实label y,上个位置的s,和当前位置的attention输出c有关,换句话说,位置i的s利用了所有它之前的真实label y信息,和所有它之前位置的attention的输出c信息。label y信息我们全都是已知的,而之前位置的c信息虽然也可以利用,但是我们不能用,因为那样就又不能并行了(因为当前位置的c信息必须等它之前的c信息都计算出来)。于是我们只能用真实label y来模拟解码层的rnn。前面说过,当前位置s使用了它之前的所有真实label y信息。于是我们可以做一个masked attention,即对真实label y像编码层的x一样做self-attention,但每个位置的y只与它之前的y有关(mask),这样,self-attention之后每个位置的输出综合了当前位置和它之前位置的所有y信息,即可做为s(query)。
  3. 得到编码层的key和value以及解码层的query后,下面就是模仿vanilla attention,利用key和value以及query再做最后一个attention。得到每个位置的输出。

总结起来就是,x做self-attention得到key和value,y做masked self-attention得到query,然后key,value,query做vanilla-attention得到最终输出。


基本框图:
这里写图片描述

  • 相似度的计算
    attention中最重要的一步就是query和key相似度的计算,目前主要的相似度计算方法有以下4种。
    这里写图片描述
    其中Q为query,K为key,V为value。《Neural machine translation by jointly learning to align and translate》这篇论文就使用了perceptron attention。而这篇论文使用的是dot attention,后面会有详细的介绍。


  • 细节

上面已经说了这篇论文的主要思想,当然论文中还是用到了很多其他技术的,在模型上也有细节上的改进。我们从输入到输出来一步步说明。


  • position embedding
    论文采用self-attention的一个缺点就是无法使用word的位置信息。rnn可以使用位置信息,因为当位置变化时(比如互换两个word的位置)rnn的输出就会改变。而self-attention各个位置可以说是相互独立的,输出只是各个位置的信息加权输出,并没有考虑各个位置的位置信息。cnn也有类似位置无关的特点。以往的pe往往采用类似word_embedding式的可以随网络训练的位置参数,google提出了一种固定的pe算法:
    这里写图片描述
    即在偶数位置,此word的pe是sin函数,在奇数位置,word的pe是cos函数。论文说明了此pe和传统的训练得到的pe效果接近。并且因为 sin(α+β)=sinα cosβ+cosα sinβ 以及 cos(α+β)=cosα cosβ−sinα sinβ,位置 p+k 的向量可以用位置 p 的向量的线性变换表示,这也说明此pe不仅可以表示绝对位置,也能表示相对位置。
    最后的embedding为word_embedding+position_embedding。而facebook的论文是拼接两个embedding。


  • multi-head attention
    有了embedding,接下来就是attention了,论文采用了多个attention。首先embedding做h次linear projection,每个linear projection的参数不一样,然后做h次attention,最后把h次attention的结果拼接做为最后的输出。作者表明,多个attention便于模型学习不同子空间位置的特征表示,然后最终组合起来这些特征,而单头attention直接把这些特征平均,就减少了一些特征的表示可能。如图所示:
    这里写图片描述
    公式表示为:
    这里写图片描述


  • Scaled Dot-Product
    这篇论文计算query和key相似度使用了dot-product attention,即query和key进行点乘(内积)来计算相似度。论文中的公式如下:
    这里写图片描述
    示意图为:
    这里写图片描述
    之所以用内积除以维度的开方,论文给出的解释是:假设Q和K都是独立的随机变量,满足均值为0,方差为1,则点乘后结果均值为0,方差为dk。也即方差会随维度dk的增大而增大,而大的方差导致极小的梯度(我认为大方差导致有的输出单元a(a是softmax的一个输出)很小,softmax反向传播梯度就很小(梯度和a有关))。为了避免这种大方差带来的训练问题,论文中用内积除以维度的开方,使之变为均值为0,方差为1。


  • 预测
    训练的时候我们知道全部真实label,但是预测时是不知道的。可以首先设置一个开始符s,然后把其他label的位置设为pad,然后对这个序列y做masked attention,因为其他位置设为了pad,所以attention只会用到第一个开始符s,然后用masked attention的第一个输出做为query和编码层的输出做普通attention,得到第一个预测的label y,然后把预测出的label加入到初始序列y中的相应位置,然后再做masked attention,这时第二个位置就不再是pad,那么attention层就会用到第二个位置的信息,依此循环,最后得到所有的预测label y。其实这样做也是为了模拟传统attention的解码层(当前位置只能用到前面位置的信息)。


  • other
    label Smoothing
    用softmax分类并使用交叉熵函数做为损失函数时,真实标签只有0或1,根据反向求导公式可知,这会难于泛化,并且上层导数容易为0.所以把真实标签smooth,使之为0-1之间的一个数,而不是两个极端。
    layer normlization
    为了加速训练,避免陷入局部最优。
    stack layers
    如Figure 1的网络结构,编码层和解码层都重复了N次,最后把结果拼接。
    restricted self-attention
    为了缓解需要两两计算相似性的计算代价,作者又提出了restricted版本的self-attention,即每个query只需和他临近的r个key计算相似性。类似于卷积中的窗口概念。


  • 网络结构

    如图:
    这里写图片描述

  • 总结

    self-attention层的好处是能够一步到位捕捉到全局的联系,解决了长距离依赖,因为它直接把序列两两比较(代价是计算量变为 O(n2),当然由于是纯矩阵运算,这个计算量相当也不是很严重),而且最重要的是可以进行并行计算。
    相比之下,RNN 需要一步步递推才能捕捉到,并且对于长距离依赖很难捕捉。而 CNN 则需要通过层叠来扩大感受野,这是 Attention 层的明显优势。
    self-attention其实和cnn,rnn一样,也是为了对输入进行编码,为了获得更多的信息。所以应把self-attention也看成网络中的一个层加进去。

  • 参考

  1. 一文读懂self-attention
  2. 自然语言处理中的自注意力机制(Self-attention Mechanism)
  3. attention model–Neural machine translation by jointly learning to align and translate论文解读
  4. Attention is all you need
### 解读 'Attention is All You Need' 论文 #### 关键思想 《Attention is All You Need》这篇论文提出了一个新的神经网络架构——Transformer,该架构完全依赖于自注意力机制来处理序列数据。传统上,在自然语言处理领域中使用的RNN及其变体(LSTM, GRU),由于其固有的顺序计算特性,难以并行化训练,并且对于长距离依赖关系的学习效果不佳。 为了克服这些问题,研究者引入了一种全新的方法论,即通过多头自注意力建模输入序列中的不同表示子空间[^1]。这种方法不仅能够有效捕捉到句子内部词语之间的关联性,而且极大地提高了模型的表达能力与泛化性能。 #### Transformer 架构 Transformer 的核心组件包括编码器(encoder) 和解码器(decoder),两者均由多个相同的层堆叠而成。每一层主要由两个子模块构成: - **Multi-head Self-Attention Layer**: 这一层允许模型在同一时间关注来自不同位置的不同表征特征,从而增强了对上下文的理解。 - **Feed Forward Neural Network (FFN)**: FFN是一个简单的全连接前馈网络,应用于每个位置上的独立操作,不涉及任何跨位置交互。 此外,还存在残差连接(residual connection)围绕着这两个子模块,并在其后接一个Layer Normalization 层以稳定梯度传播过程。 ```python class TransformerBlock(nn.Module): def __init__(self, d_model, num_heads, dropout=0.1): super().__init__() self.self_attn = MultiHeadedSelfAttention(d_model=d_model, h=num_heads) self.feed_forward = PositionwiseFeedForward(d_model=d_model) self.norm_1 = nn.LayerNorm(d_model) self.norm_2 = nn.LayerNorm(d_model) self.dropout_1 = nn.Dropout(dropout) self.dropout_2 = nn.Dropout(dropout) def forward(self, x): attn_output = self.self_attn(x) out = self.norm_1(x + self.dropout_1(attn_output)) ff_output = self.feed_forward(out) output = self.norm_2(out + self.dropout_2(ff_output)) return output ``` #### 引入自注意力机制的意义 自注意力机制使得模型能够在无需考虑固定长度窗口的情况下动态调整权重分配给不同的词或字符片段。相比于传统的循环结构,这种方式显著减少了计算复杂度,并促进了更高效的并行运算实现方式。更重要的是,它提供了一个灵活而强大的工具来建模复杂的句法和语义模式,这对于提高机器翻译、文本摘要等多种下游任务的表现至关重要。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值