题目:Attention Is All You Need
RNN的不足:
循环模型通常是沿着输入与输出序列的符号位置进行因子计算。在计算时将位置与步骤对齐,它们会生成一个隐藏状态ht序列,由先前隐藏状态ht-1和位置输入t组成的一个函数(现在的状态依赖于前面的状态)。这种固有的序列性质在训练中无法进行并行化,这在较长的序列中是至关重要的。尽管最近的研究通过因子分解技巧和条件计算已经在计算效率方面得到了显著进步,同时也提高了后者的模型性能,但是序列计算的限制依然存在。
注意力机制:
注意力机制已经成为各种任务中的序列建模和转换模型的重要部分,它允许对依赖项进行建模,而不需要关注它们在输入或输出序列中的距离。然而,除了少部分情况外,注意力机制都在和循环网络结合使用。
我们的工作:
我们提出了Transformer,这是一种避免重复的模型架构,完全依赖注意力机制来描述输入和输出之间的全局依赖性。Transformer允许更多的并行化,并且在8个P100 GPU上训练12小时之后,可以达到翻译质量的新水平。
减少序列计算的目标也是扩展神经GPU
、ByteNet
、和ConvS2S
形成的依据,这些网络都是使用卷积神经网络作为基础构建块,并行计算所有输入和输出位置的隐藏表示。在这些模型中,将来自两个任意输入和输出位置的信号关联起来所需的操作数量随着位置之间的距离而增加。这就使得了解远距离位置之间的依赖关系变得更加困难。在Transformer中,会将操作数量减少的恒定大小。尽管由于平均位置注意力加权会降低有效的分辨率,但我们使用多头注意力抵消了这种影响。
自注意力机制是将单个序列的不同位置关联起来,以计算序列的表示。自注意力机制已经成功应用在各种任务中,包括阅读理解、抽象总结等与学习任务无关的句子表示。
端到端记忆网络基于重复注意力机制,而不是顺序一致的重复,并且已经在简单的语言问答和语言建模任务中表现良好。
然而,据我们所知,Transformer是第一个完全依靠自注意力机制来计算其输入和输出表示的转换模型,而不使用序列一致RNN或卷积。
大多数竞争性神经序列转换模型都有编码器-解码器结构。编码器将输入序列(x1,x2,……xn)映射到连续表示序列z=(z1,z2,……,zn)。
给定z,解码器一次生成一个符号的输出序列(y1,y2,y3,……,ym)。
每一步中的模型都是自回归的,在生成下一步时,需要使用先前的生成符号作为额外输入。
下面是Transformer的总体结构,Transformer使用的编码器-解码器结构是将自注意力和pointwise,全连接层堆叠在一起的。
左边:编码器;右边:解码器
这是基础块结构,Nx表示多个这样的基础块。
encoder由N=6个相同的层组成。每个层又有两个子层。
第一个子层是多头自注意力机制,第二个是位置全连接前馈网络。两个子层均采用残差连接,之后再进行Layer normalization。
每个子层公式表示为:
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))
为了方便残差连接,所有的子层和内部嵌入层的输出维度都是dmodel=512。
decoder由N=6个相同的层组成。每个层又有三个子层。
与encoder相似,每个子层周围使用残差连接,之后进行Layer normalization。
我们还修改了解码器中的自注意力子层,防止位置信息关注序列后面的位置。(注意力机制是可以看到完整输出的)这种结合了偏移一个位置的输出嵌入的遮掩层,可以确保位置i的预测只能依赖与小于位置i的输出。
attention 函数是将一个query和一组key-value对映射到输出,这里的query、key和value都是向量。
输出是由值的加权和计算的,每一个值的权重由query和相应key的兼容函数计算。
我们将这个特殊的注意力机制称为“Scaled Dot-Product Attention”。
A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V) = softmax(frac{QK^T}{sqrt{d_k}})V Attention(Q,K,V)=softmax(dk QKT)V
在实践中,我们会在一组query上同时计算注意力函数,这样可以将多个query组成一个矩阵,key和value类似。
最常用的注意力函数:additive attention和dot-product attention。
我们采用的是修改的dot-product attention,我们的是进行了除以 d k sqrt{d_k} dk 。
为什么除以 d k sqrt{d_k} dk ?
当dk较小时,除与不除没有太大区别,dk很大时,会导致点乘后的项值很大或很小,每一项之间的差距也会相对变大,在后面作softmax时,很大的值会靠近1,很小的值会靠近0。这种情况计算梯度值很小,模型收敛很慢。
Mask的作用?
我们希望计算Kt时,只使用t之前的序列,但是我们把K矩阵输入进去后,注意力机制是可以看到所有的K1-Km。Mask的作用就是将Kt-Km的值变得非常大,这样经过softmax后这些值会非常接近于0,起到屏蔽的作用。
我们发现用不同的线性投影将query、key和value分别线性投影到dk、dk和dv维是有益的。在query、key和value的每一个投影上,我们并行执行注意力函数,生成dv维的输出值。最后将这些值进行连接,再次投影得到最终值。
多头注意力机制允许模型共同关注来自不同位置的不同表征子空间的信息。只有一个注意力头时,平均值会抑制这种情况。
M u l t i H e a d ( Q , K , V ) = C o n c a t ( h e a d 1 , h e a d 2 , … , h e a d h ) W O w h e r e h e a d i = A t t e n t i o n ( Q W i Q , K W i K , V W i V ) MultiHead(Q,K,V) = Concat(head_1,head_2,…,head_h)W^O\ where head_i = Attention(QW_i^Q,KW_i^K,VW_i^V) MultiHead(Q,K,V)=Concat(head1,head2,…,headh)WOwhere headi=Attention(QWiQ,KWiK,VWiV)
WiQ ∈ Rdmodel×dk,WiK ∈ Rdmodel×dk,WiV ∈ Rdmodel×dv,WiV ∈ Rhdv×dmodel,dmodel表示原来的维度,W都是可学习的参数。
h表示注意力层的数量,也就是投影到h个子空间中或h个head。
dk=dv=dmodel/h
基本结构中,multi-head attention的三种应用:
在encoder-decoder中的每一层都包含一个全连接前馈神经网络,该网络会分别地相同地作用于每一个位置(序列位置)。网络包含两个线性层和一个ReLU激活层。
F F N ( x ) = m a x ( 0 , x W 1 + b 1 ) W 2 + b 2 FFN(x) = max(0,xW_1+b_1)W_2+b_2 FFN(x)=max(0,xW1+b1)W2+b2
两个线性层的作用:
① W1:将x映射的更高的维度;
② W2:将高纬度数据恢复为原来的维度大小。
我们使用学到的Embedding层将输入token和输出token转换为维度dmodel的向量。
我们还使用学到的线性变换和softmax函数将解码器的输出转换为预测的下一个token的概率。
在模型中,两个embeding和softmax前的线性层的权值共享。
在嵌入层中,我们将这些权重乘以 d m o d e l sqrt{d_{model}} dmodel 。
理解什么是Embedding层及利用nn.Embedding创建时的参数含义
了解了什么是one-hot编码后,发现了该编码方式的优点和缺点非常的突出,为了更高效的使用内存,更加合理的进行文本的编码,常常使用Embedding层进行文本的数字张量表示。文本只是一个符号,简单的理解文本的作用,即表示实体和实体之间的逻辑性的符号,但是实体与实体之间是存在联系的。**如果我们把Embedding层理解成文本数据扩充维度的表现,是否可以更好的理解这部分内容呢。**即如果有3句话,每句话有10个字,通过张量表示,则该张量的形状一定是(3, 10),可是如果我们把每个文字用60个数字来抽象的表示,那该文本的张量形状是不是变成了(3, 10, 60)其中60就是所谓的词嵌入维度。所以从字面上理解,只要给定词库的数字,以及要转化的词嵌入维度,我们就能够得到Embedding层的输出。即nn.Embedding(max_len, d_model),这样一个简单的Embedding层创建完毕。其中我们的max_len也可以写成vocab表示词表的大小。
由于我们的模型不包括循环和卷积,为了使模型能够利用序列的顺序,我们必须在序列中注入一些关于token的相对或绝对位置的信息。
位置编码和embedding具有相同的维度,因此两者可以作加法。位置编码包括:可学习的、固定的。
每个序列中的第pos个token的第i个嵌入的PE为:
P E ( p o s , 2 i ) = s i n ( p o s 1000 0 2 i / d m o d e l ) P E ( p o s , 2 i + 1 ) = s i n ( p o s 1000 0 2 i / d m o d e l ) PE(pos,2i) = sin(frac{pos}{10000^{2i/d_{model}}})\ PE(pos,2i+1) = sin(frac{pos}{10000^{2i/d_{model}}}) PE(pos,2i)=sin(100002i/dmodelpos)PE(pos,2i+1)=sin(100002i/dmodelpos)
本文发布于:2024-01-28 21:37:41,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170644906610452.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |