Transformer解读

Transformer解读

最近开始研究Transformer系列的东西,读了Transformer那篇论文Attention is All You Need,也查了一些资料,算是终于大体摸清了是个啥意思,打算之后再跟着哈佛的一个帖子复现一下,这里先记录一下模型整个流程以防之后忘记了。

模型结构总览

图1 Transformer模型结构

图1是Transformer模型的结构示意图(我是直接从论文里截的图,可能会糊,不过无伤大雅就不自己画矢量图啦!),从宏观的结构说,Transformer还是使用了Encoder-Decoder结构(图1左边矮的是Encoder,右边高的是Decoder)。

如果你不知道什么是Encoder-Decoder结构:

Encoder-Decoder结构是机器翻译任务的模型非常喜欢使用的一种结构(机器翻译:就是实现不同语言之间的翻译,Google Translate、有道翻译这些),它大概干了什么事情呢,就是说我们把需要翻译的语句输入进Encoder(编码器),然后这个Encoder就通过一系列操作算出了一个特征向量,然后再把这个特征向量输入进Decoder(解码器),Decoder通过一系列操作算出最终的翻译结果,这个就是Encoder-Decoder结构。(用更白的话来讲,输入和输出的语句“意思”是要一样的,Encoder就是从输入中提取这个“意思”,Decoder就是通过“意思”把话给组织出来。)

Encoder

Encoder有六个独立的layer,每个layer包含两个sub-layer。第一个sub-layer是Multi-head attention mechanism,顾名思义就是用来计算attention的。第二个sub-layer是一个全连接网络。每个sub-layer都使用了残差的思想,即每个sub-layer的输出都是: 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))(残差+Normalization),因此模型里所有的sub-layer以及embedding layer的输出的维数都是512( d m o d e l = 512 d_{model}=512 dmodel=512)。

如果你不知道什么是残差:

我讲一下我理解的残差。在人们刚刚开始研究深度学习的时候,发现模型的性能并不如人们所想的层数叠得越多就越好,反而层数太多了性能就会下降。这就很诡异了,按理来讲你20层能做到的东西,50层必定能做得一样好:让后面30层不工作不就好了吗?于是就有人提出,那这样好了,每层的输入是上一层的计算结果,我想要让后30层不工作,那我让每层计算的东西直接跟上一层的计算结果叠加,这样我后30层只要无脑全部输出0+上一层的结果,就一定能让50层模型至少拥有20层模型的性能,这就是残差的由来。而且残差收敛起来也快,可以粗暴理解为残差的取值范围一定比原始值取值范围小,所以在用梯度下降更新的时候具有优势。

总结一下,layer如果使用残差,假设它的输入为 x x x,那么它的输出为 x + l a y e r ( x ) x+layer(x) x+layer(x) l a y e r layer layer函数为这个layer计算的结果。由于输入和输出要相加,所以它俩必须要可加,因此这个layer的输入维数和输出维数一定是相等的(所以Transfomer里各层维数都是512)。使用残差的好处在于模型可以更深层以及模型更好训练了。

我是在学ResNet的时候看到的残差是什么。(ResNet是一个CNN模型,知不知道ResNet什么样不影响理解残差,放心。)当时ResNet就是利用残差降低了模型“学成”的难度,从而使得整个模型可以叠超级多层。如果你觉得我在胡扯八道或者没看懂的话,可以参考这个讲ResNet的文章或者自己再找找相关资料。

Decoder

Decoder由六个独立layer组成。每个layer有三个sub-layer:

  • Masked multi-head attention,作用其实跟Encoder的multi-head attention相同,都是用来计算attention的。为啥会多个mask,是因为Decoder毕竟是在生成过程,它肯定不会有当前时刻后面的时刻的信息,因此需要把这些没有的mask掉。
  • Multi-head attention,用来计算Encoder给Decoder输入的特征的attention。
  • 全连接网络,跟Encoder一样了。

什么是当前时刻?

相信有这个疑问的大多对RNN(循环神经网络)不是很熟悉【当然也可能是因为我没讲清楚。我们用最直白的理解方式来讲这个事情。各种语句都可以认为是单词或者字符的序列,而我们在让模型处理语句的时候,不是一股脑地把一整句话都塞进去,而是按顺序一个单词一个单词或者一个字符一个字符处理的,最后推测也是一个单词一个单词一个字符一个字符这样推测的。每个时刻模型都只在处理一个单词或者一个模型。比方说输入是I love China. 那第1个时刻就在处理I,第2个时刻就在处理love,第3个时刻在处理China。可以理解这种感觉了吗?

所以为什么说Decoder的第一个sub-layer需要mask,就是因为它计算的是推测结果的attention,而只要Decoder还在运转,就代表结果还没被推测完,后面还有单词或者字符没推测呢,那你不可能拿不存在的东西去计算吧?而Encoder不一样,Encoder的语句我们是完整知道的,所以它不需要mask,Decoder的第二个sub-layer计算的是Encoder计算的结果,也是已知的,所以它也不需要mask。

下面会对几个sub-layer涉及到的方法进行具体的介绍。

Multi-head Attention

这个方法在Transformer里是核心方法,我们可以把这个方法按照名字拆开:Multi-head和Attention

Attention

Attention是啥???为了节省时间,我举个例子解释一下attention是做什么的(看不懂可以直接跳到公式表达那部分,然后去查其他资料理解attention的作用):

比如说我要把I love China.翻译成中文,我们当然知道这个中文是我爱中国,我们按照人类的思维逻辑想想,你是不是对着I翻译我,对着love翻译爱然后对着China翻译中国?在翻译我这个字的时候除了I以外其他的都不重要,即翻译I的时候我们只需要关注I。把这种思路延申进机器学习里,推测每个单词的时候,如果能“注意”到跟这个单词最相关的输入单词就好了。attention机制就是做的这个。

把知乎上讲Transformer的一篇文章里写的Attention机制公式化的表达给放到这里:

有两个序列Source和Target,我想要计算Source在Target的某个元素的Attention权重下的特征向量是什么,我们可以从Target的这个元素生成一个叫Query(Q)的向量,从Source序列生成一系列的<Key, Value>键值对 { K i , V i ∣ i = 1 , 2 , . . . , m } \left\{K_i,V_i|i=1,2,...,m\right\} {Ki,Vii=1,2,...,m},然后进行三步:

  1. 计算Q和K的相似度,这里用f来表示

    f ( Q , K i ) , i = 1 , 2 , . . . , m f(Q,K_i),i=1,2,...,m f(Q,Ki),i=1,2,...,m

  2. 将得到的相似度进行Softmax操作,归一得到权重

    α i = e f ( Q , K i ) s u m j = 1 m f ( Q , K j ) , i = 1 , 2 , . . . , m \alpha_i=\frac{e^{f(Q,K_i)}}{sum_{j=1}^mf(Q,K_j)},i=1,2,...,m αi=sumj=1mf(Q,Kj)ef(Q,Ki),i=1,2,...,m

  3. 使用计算出来的权重 α i \alpha_i αi与Value进行加权求和,得到Attention向量。

    ∑ i = 1 m α i V i \sum_{i=1}^m\alpha_iV_i i=1mαiVi

有朋友可能会说了,那这QKV都咋算出来的啊,我看见的是拿个矩阵跟Target和Source的向量相乘算出来的,至于这个矩阵具体是多少数值是由模型在训练过程中自己算出来的。

那self-attention是什么?一句话:Target和Source相等就是self-attention。self-attention有什么用呢?举个例子,有一个句子:“我吃的面,我朋友吃的饭,我觉得我那碗很难吃。”问究竟难吃的是什么东西,使用self-attention就能计算出难吃跟这句话里其他字的相关程度,发现面的相关程度高,就推测出难吃的是面。当然这是非常直观且不严谨的解释,只是想说明self-attention是有用的!

前面说了这么多,终于可以进入到最细节的Transformer里的attention是什么样的了

我们在将模型结构概览的时候提到过,所有的layer的输入的维数都是 d m o d e l = 256 d_{model}=256 dmodel=256,首先要通过输入把QKV三个矩阵算出来,其中 Q ∈ R m × d k Q\in R^{m \times d_k} QRm×dk K ∈ R m × d k K\in R^{m \times d_k} KRm×dk V ∈ R m × d v V\in R^{m \times d_v} VRm×dv d k d_k dk d v d_v dv是两个给定的数值,它的具体数值和设定原因我们放到Multi-head里讲,这里只需要知道是两个数就可以了。这个 m m m论文中没有仔细说明,论文只是说在实际实现的时候它们不是一个单词一个单词计算attention的,而是一个序列一起进行计算,所以我感觉 m m m可以粗暴理解成输入的序列长度?

(原文)In practice, we compute the attention function on a set of queries simultaneously, packed together into a matrix Q.

还记得前面说的,attention机制的第一步是计算Q和K的相似度吗?在Transformer里,这个相似度是使用这样的一个计算公式计算的:

f ( Q , K i ) = Q T K i d k f(Q,K_i)=\frac{Q^TK_i}{\sqrt{d_k}} f(Q,Ki)=dk QTKi

然后再进行Softmax操作归一化得到权重:

α i = e Q T K i d k s u m j = 1 m Q T K j d k , i = 1 , 2 , . . . , m \alpha_i=\frac{e^{\frac{Q^TK_i}{\sqrt{d_k}}}}{sum_{j=1}^m\frac{Q^TK_j}{\sqrt{d_k}}},i=1,2,...,m αi=sumj=1mdk QTKjedk QTKi,i=1,2,...,m

将query、Keys和Values分别整合为矩阵Q,K,V,计算输出矩阵为(Softmax函数就不展开啦):

A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q T K d k ) V Attention(Q,K,V)=softmax(\frac{Q^TK}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dk QTK)V

Multi-head

Multi-head比Attention好理解多了。常规而言,我们算Attention就只用一组线性变换把输入映射成一组Q, K, V。但是Transformer里使用多组线性变换把输入映射成多组QKV,计算出不同的attention output,然后把不同组attention的值拼在一起输出。这就是所谓的Multi-head

Positional Encoding

Positional Encoding的作用比较好理解。机器翻译这些任务之所以一直使用RNN一类的模型,就是因为RNN类的模型拥有处理序列化数据的能力,不仅仅是指它能够输入输出序列化的数据,更多的是因为它能够学到序列数据排序的一些规律。但是我们可以看到Attention机制里它学到的更多是不同元素之间的关系,这种关系是某种相关程度。相关程度跟顺序是有着微妙的不同的。因此为了使得以Attention机制为核心的Transformer拥有类似于RNN理解顺序的能力,需要额外地增加某种表达使得模型能够表示顺序,这个表达就是Positional Encoding。在Transformer里采用的是使用sine和cosine来表示:

P E ( p o s , 2 i ) = s i n ( p o s / 1000 0 2 i / d m o d e l ) PE_{(pos,2i)}=sin(pos/10000^{2i/d_{model}}) PE(pos,2i)=sin(pos/100002i/dmodel)

P E ( p o s , 2 i + 1 ) = c o s ( p o s / 1000 0 2 i / d m o d e l ) PE_{(pos,2i+1)}=cos(pos/10000^{2i/d_{model}}) PE(pos,2i+1)=cos(pos/100002i/dmodel)

参考文献

https://blog.csdn.net/weixin_44538273/article/details/86501056

https://zhuanlan.zhihu.com/p/46990010

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Transformer 是一种用于自然语言处理和其他序列转换任务的深度学习模型架构。它在2017年由 Vaswani 等人提出,通过引入自注意力机制和多头注意力机制,取得了显著的成果。 Transformer 的核心思想是完全基于注意力机制的模型,它不依赖于循环神经网络 (RNN) 或卷积神经网络 (CNN) 进行序列建模。该模型的输入和输出都是由嵌入向量组成的序列,例如单词或字符。Transformer 由编码器和解码器组成,每个部分都是堆叠的自注意力和前馈神经网络层。 编码器将输入序列转换为上下文感知的编码表示,解码器则根据编码器的输出和之前生成的部分目标序列来生成最终的输出序列。自注意力机制使得模型能够在输入序列中建立全局的依赖关系,每个位置对整个序列进行关注。多头注意力机制则允许模型同时关注不同表示子空间中的不同信息。这些机制共同提供了强大的建模能力,使得 Transformer 在翻译、摘要、对话生成等任务中表现出色。 除了自注意力和前馈神经网络层,Transformer 还引入了残差连接和层归一化等技术,用于缓解训练过程中的梯度消失和表达能力不足的问题。此外,Transformer 还使用了位置编码来保留输入序列中的顺序信息。 总结来说,Transformer 是一种基于注意力机制的深度学习模型,通过自注意力和多头注意力机制实现了对序列数据的建模。它在自然语言处理任务中取得了显著的突破,并成为了当前最先进的模型之一。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值