Transformer超详细解读

论文:Attention Is All You Need
作者:Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser, Illia Polosukhin
机构:Google Brain
链接:https://arxiv.org/abs/1706.03762
代码:https://github.com/tensorflow/tensor2tensor



1、算法概述

这篇论文是transformer的开山之作,最早transformer是用于机器翻译的,也就是NLP领域,但是随着2020年DETR和ViT的出现,它在视觉领域的应用也大火了起来,为了后续解读transformer在视觉领域的其他应用算法,有必要解读一下transformer的理论基础。

作者在论文摘要中指出,之前的处理序列信号的任务例如机器翻译都是基于复杂的循环神经网络(RNN)、长短时记忆(LSTM)或者卷积神经网络(CNN)组成的编码器和解码器,为了使其表现好点,在编码的时候还可以结合注意力机制。这篇论文,作者完全摒弃了RNN和CNN结构,只基于注意力机制,相比于RNN和LSTM的串行处理结构,作者提出的transformer结构可以实现并行处理,大大减小了处理序列的时间。如下图是传统用RNN及CNN处理序列的示意图(图片来自台湾国立大学李宏毅老师的transformer课件ppt,侵删)
在这里插入图片描述

由上图可见,RNN和LSTM这类循环神经网络是串行处理,输出一串序列,耗时长,CNN虽然可以并行处理,但它关联到序列之间的关系范围有限,需要通过不断加深网络层数来扩大范围,使其能处理更长的序列。
而自注意力是一种将单个序列的不同位置联系起来以计算该序列的表示的注意机制。在处理序列问题上,它可以完全替代RNN及CNN的角色,如下图:
在这里插入图片描述


2、Transformer细节

在这里插入图片描述
Transformer整体架构如上图所示,它使用堆叠的自注意力层和point-wise层,由编码器和解码器两部分组成。论文中编码器和解码器中的N均设置为6。

编码器中一个block由两部分组成,第一个是多头自注意机制,第二个是一个简单的、位置明智(point-wise)的全连接前馈网络。其中的Add & Norm操作为LayerNorm(x + Sublayer(x)),这里的Sublayer(x)及代表Multi-Head Attention或Feed Forward模块。

解码器中一个block则由三部分组成,除了编码器中的Multi-Head Attention和Feed Forward模块,它还包含了Masked Multi-Head Attention模块,它负责对编码器堆栈的输出执行多头注意。为了确保位置i的预测只能依赖于位置小于i的已知输出。作者修改了解码器堆栈中的自注意子层,以防止关注后续位置。

可以看出本文的创新点在于Multi-Head Attention部分,下面详细阐述这个模块的计算方式。


2.1 Attention

注意函数可以描述为将查询(query)和一组键值对(key-value pairs)映射到输出,其中查询、键、值和输出都是向量。输出以值(value)的加权和形式计算得到,其中分配给每个值(value)的权重由查询与相应键的匹配度函数计算得到。

  • Scaled Dot-Product Attention
    如下图是Q,K,V的操作示意图
    在这里插入图片描述
    用公式可表示如下:
    在这里插入图片描述
    下面以李宏毅老师的ppt来展示对于序列 (x1,x2,x3,x4) 如何一步一步计算self-attention的。
    首先xi经过矩阵W变换得到ai,通过ai得到对应的qi、ki及vi。如下图:
    在这里插入图片描述
    在这里插入图片描述
    对于q1,它和每一个ki进行点积(dot product)计算并做scale操作得到a1,i,如下图:
    在这里插入图片描述
    对a1,i做softmax操作,得到a^1,i,这里就得到计算第一个输出值的b1所需要的各个vi的权重了,如下图:
    在这里插入图片描述
    第一个输出值b1可由权重a^1,i与vi加权求和得到,如下图:
    在这里插入图片描述
    同理,第二个节点b2也可以计算得到:
    在这里插入图片描述
    主要是b1,b2,b3,b4可以利用GPU进行并行计算,如下图:
    在这里插入图片描述
    在这里插入图片描述

  • Multi-Head Attention
    多头注意允许模型在不同位置共同注意来自不同表示子空间的信息。对于单一注意力头,平均会抑制这一点,如下图所示:
    在这里插入图片描述
    用公式可以表示为:
    在这里插入图片描述
    论文中h取8,dk=dv=dmodel/h=64。
    下面还是以李宏毅老师的ppt图片来展示两个注意力头的计算方式,非常直观。
    在这里插入图片描述
    图中两个注意力头,红色椭圆框住的是第一个头,绿色椭圆框住的是第二个头,对于第一个头输出的bi,1只需对第一个头的q,k,v进行相关计算即可。第二个头的输出结果同理,如下图:
    在这里插入图片描述
    两个头最终的输出结果bi由各个头的输出结果进行concat然后通过矩阵Wo相乘得到。如下图:
    在这里插入图片描述
    多个注意力头对语句关注点可视化如下,可见每个注意力头关注点都不一样。
    在这里插入图片描述

2.2 Position-wise Feed-Forward Networks

除了注意子层之外,编码器和解码器中的每一层都包含一个全连接的前馈网络,该网络分别相同地应用于每个位置。它包括两个线性连接,中间有一个ReLU激活。用公式表示为:
在这里插入图片描述

2.3 Positional Encoding

由于作者设计的模型不包含递归和卷积,为了使模型有效利用序列的顺序,需向模型引入一些关于序列中标记的相对或绝对位置的信息。为此,作者在编码器和解码器底部的输入嵌入向量(embedding)中添加了“位置编码”。位置编码与嵌入向量具有相同的维数,因此可以对两者进行求和。

位置编码有很多选择,有通过学习获得也有直接设置的,本论文作者选择了后者,采用的位置编码公式为:
在这里插入图片描述
由于公式的三角函数特性,对于固定偏移位置k,PEpos+k都可以被PEpos线性表示出来:
s i n ⁡ ( a + b ) = s i n ⁡ a c o s ⁡ b + c o s ⁡ a s i n ⁡ b sin⁡(a+b)=sin⁡a cos⁡b+cos⁡a sin⁡b sin(a+b)=sinacosb+cosasinb
c o s ⁡ ( a + b ) = c o s ⁡ a c o s ⁡ b − s i n ⁡ a s i n ⁡ b cos⁡(a+b)=cos⁡a cos⁡b-sin⁡a sin⁡b cos(a+b)=cosacosbsinasinb
而李宏毅老师的ppt中位置编码是通过学习获得的,我们可以直观感受到位置编码如何与单词embedding相加得到的,如下图,李宏毅老师中定义每个单词位置pi为one-hot编码,然后通过矩阵变换Wp得到位置编码ei,这里ei的维度和单词的embedding向量ai维度需保持一致,最后相加得到最终的单词嵌入向量进入后续的自注意力模块。
在这里插入图片描述

2.4 Seq2seq with Attention

接下来看看对于seq2seq任务中,如何应用transformer中的自注意力机制的,把Encoder-Decoder中的RNN用self-attention取代掉,如下图:
在这里插入图片描述


3、训练

训练采用WMT 2014 英语-德语数据集,它由450万个句子对,具有大约37000个标记的源-目标词汇表。而且,作者还采用了WMT 2014英语-法语数据集,它的数据量更大,包含3600百万个句子对,包含大约32000个单词,25000个源-目标词汇对应表标记。

作者用了8个NVIDIA P100 GPUs训练模型,对于base model,训练了10万个steps用了12小时,对于big model,训练了30万个steps用了3.5天。作者采用Adam优化器,warmup设置了4000个step并且采用线性变化到初始学习率,然后按步长平方根的倒数成比例递减。
在这里插入图片描述
对于模型正则化,作者采用了三种方式:Residual Dropout,每个sub-layer的输出应用dropout,还有在编码器和解码器中的单词embedding和位置编码之和处应用dropout,在base model中,drop概率设置为0.1;还有就是label smoothing,概率设置为0.1。


4、实验

机器翻译的实验结果如下:
在这里插入图片描述

参考:
[1] Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A.N., Kaiser, L., Polosukhin, I.: Attention is all you need. In: NeurIPS (2017)
[2]https://www.bilibili.com/video/av71295187/?spm_id_from=333.788.videocard.8&vd_source=dde073a03801571dd0b077e3e88ccfb7
[3] https://zhuanlan.zhihu.com/p/340149804
[4] https://zhuanlan.zhihu.com/p/308301901
[5] pytorch实现:https://github.com/jadore801120/attention-is-all-you-need-pytorch

要使用Transformer进行测试单句话的代码,你需要先进行一些必要的准备工作: 1. 导入所需的库和模块,如torch和torch.nn。 2. 定义相关的参数,如词汇表大小和嵌入维度。 3. 创建Transformer模型实例,可以通过调用torch.nn.Transformer类来实现。 4. 加载训练好的模型参数,以便进行推理。 5. 定义输入数据,将句子转换为对应的索引序列,并进行填充和遮蔽操作。 6. 使用模型进行推理,通过调用模型的forward方法传入输入数据。 7. 对输出进行后处理,如取最大值等操作,以得到最终的预测结果。 下面是一段示例代码,展示了如何使用Transformer进行测试单句话: ```python import torch import torch.nn as nn # 定义参数 vocab_size = 10000 embedding_dim = 256 hidden_dim = 512 num_layers = 6 # 创建Transformer模型实例 model = nn.Transformer( d_model=embedding_dim, nhead=8, num_encoder_layers=num_layers, num_decoder_layers=num_layers, dim_feedforward=hidden_dim, dropout=0.1 ) # 加载模型参数 model.load_state_dict(torch.load('transformer_model.pth')) # 定义输入数据 sentence = "Hello, how are you?" input_ids = [token2id[token for token in sentence.split()] input_tensor = torch.tensor(input_ids).unsqueeze(0) # 添加batch维度 src_key_padding_mask = torch.zeros((1, len(input_ids))).bool() # 用于遮蔽填充部分 # 使用模型进行推理 output = model(input_tensor, src_key_padding_mask=src_key_padding_mask) # 对输出进行后处理,获取最终的预测结果 pred_ids = output.argmax(dim=-1).squeeze().tolist() pred_sentence = ' '.join([id2token[id for id in pred_ids]) print(pred_sentence) ``` 请注意,以上代码只是一个示例,实际上还需根据具体的应用场景进行适当的修改和调整。具体来说,你可能需要根据你的数据集和任务来调整模型的参数,以及根据你的词汇表设置相关的token2id和id2token映射关系。同时,如果你使用的是预训练的Transformer模型,还需要根据具体的预训练模型进行相应的调整和加载预训练参数。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Transformer 代码详解(Pytorch版)](https://blog.csdn.net/BXD1314/article/details/126187598)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【Transformer系列(5)】Transformer代码详细解读(Pytorch)](https://blog.csdn.net/weixin_43334693/article/details/130313746)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值