导航:首页 > 源码编译 > transformer理论源码细节详解

transformer理论源码细节详解

发布时间:2023-03-16 17:15:21

1. 图解什么是 Transformer

Transformer 是 Google 团队在 17 年 6 月提出的 NLP 经典之作,
由 Ashish Vaswani 等人在 2017 年发表的论文 Attention Is All You Need 中提出。

Transformer 在机器翻译任务上的表现超过了 RNN,CNN,只用 encoder-decoder 和 attention 机制就能达到很好的效果,最大的优点是可以高效地并行化。

Transformer 是一种基于 encoder-decoder 结构的模型,

在 Encoder 中,

在 Decoder 中,

下面我们具体看一下其中这几个概念,这里主要参考 Jay Alammar,他在 The Illustrated Transformer 中给出了很形象的讲解。

例如我们要进行机器翻译任务,输入一种语言,经过 Transformer,会输出另一种语言。

Transformer 的 encoder 由 6 个编码器叠加组成,
decoder 也由 6 个解码器组成,
在结构上都是相同的,但它们不共享权重。

每一个 encoder 都分为两个子层:

每一个 decoder 也具有这两个层,但还有一个注意力或差层,用来帮助解码器关注输入句子的相关部分

首先使用嵌入算法将输入的 word 转换为 vector,
最下面的 encoder ,它的输入就是 embedding 向量,
在每个 encoder 内部,
输入向量经过 self-attention,再经过 feed-forward 层,
每个 encoder 的输出向量是它正上方 encoder 的输入,
向量的大小是一个超参数,通常设置为训练集中最长句子的长度。

在这里,我们开始看到 Transformer 的一个关键性质,
即每个位置的单词在 encoder 中都有自己的路径,
self-attention 层中的这些路径之间存在依赖关系,
然而在 feed-forward 层不具有那些依赖关系,
这样各种路径在流过 feed-forward 层时可以并行执行。

Positional Encoding 是一种考虑输入序列中单词顺序的方法。

encoder 为每个输入 embedding 添加了一个向量,这些向量符合一种特定模式,可以确定每个单词的位置,或者序列中不同单词之间的距离。

例如,input embedding 的维度为4,那么实际的positional encodings如下所示:

在下图中,是20个单词的 positional encoding,每行代表一个单词的位置编码,即第一行是加在输入序列中第一个词嵌入的,每行包含 512 个值, 每个值介于 -1 和 1 之间,用颜色表示出来。

可以看到在中心位置分成了两半,因为左半部分的值由一个正弦函数生成,右半部分由余弦函数生成,然后将它们连接起来形成了每个位置的编码向量局团扒。

当然这并不是位置编码的唯一方法,只是这个方法能够扩展到看不见的序列长度处,例如当我们要翻译一个句子,这个句子的长度比我们训练集中的任何一个句子都长时。

例如我们要翻译:”The animal didn't cross the street because it was too tired” 这句话
这句话中的“it”是指什么?它指的是 street 还是 animal?
这对人类来说是一个简单的问题,但对算桐昌法来说并不简单。

而 Self-Attention 让算法知道这里的 it 指的是 animal

当模型在处理每个单词时,self-attention 可以帮助模型查看 input 序列中的其他位置,寻找相关的线索,来达到更好的编码效果。它的作用就是将对其他相关单词的“understanding”融入我们当前正在处理的单词中。

例如上图中,在第5层时,我们就知道 it 大概指的是 animal 了。

第一步,为编码器的每个输入单词创建三个向量,
即 Query vector, Key vector, Value vector
这些向量通过 embedding 和三个矩阵相乘得到,
请注意,这些新向量的尺寸小于嵌入向量。它们的维数为64,而嵌入和编码器输入/输出向量的维数为512.它们不一定要小,这是一种架构选择,可以使多头注意力计算(大多数)不变。
将x1乘以WQ得到Query向量 q1,同理得到Key 向量 和, Value 向量
这三个向量对 attention 的计算有很重要的作用

第二步,是计算一个得分
假设我们要计算一个例子中第一个单词 “Thinking” 的 self-attention,就需要根据这个单词,对输入句子的每个单词进行评分,这个分数决定了对其他单词放置多少关注度。
分数的计算方法是,
例如我们正在考虑 Thinking 这个词,就用它的 q1 去乘以每个位置的 ki

第三步和第四步,是将得分加以处理再传递给 softmax
将得分除以 8(因为论文中使用的 key 向量的维数是 64,8 是它的平方根)
这样可以有更稳定的梯度,
然后传递给 softmax,Softmax 就将分数标准化,这样加起来保证为 1。
这个 softmax 分数决定了每个单词在该位置bbei表达的程度。
很明显,这个位置上的单词将具有最高的softmax分数,但有时候注意与当前单词相关的另一个单词是有用的。

第五步,用这个得分乘以每个 value 向量
目的让我们想要关注单词的值保持不变,并通过乘以 0.001 这样小的数字,来淹没不相关的单词

第六步,加权求和这些 value 向量

这就是第一个单词的 self-attention 的输出
得到的向量接下来要输入到前馈神经网络,在实际实现中用矩阵乘法的形式完成

论文中还增加一种称为 multi-headed 注意力机制,可以提升注意力层的性能

它使得模型可以关注不同位置

虽然在上面的例子中,z1 包含了一点其他位置的编码,但当前位置的单词还是占主要作用, 当我们想知道“The animal didn’t cross the street because it was too tired” 中 it 的含义时,这时就需要关注到其他位置

这个机制为注意层提供了多个“表示子空间”。下面我们将具体介绍,

1. 经过 multi-headed , 我们会得到和 heads 数目一样多的 Query / Key / Value 权重矩阵组
论文中用了8个,那么每个encoder/decoder我们都会得到 8 个集合。
这些集合都是随机初始化的,经过训练之后,每个集合会将input embeddings 投影到不同的表示子空间中。

2. 简单来说,就是定义 8 组权重矩阵,每个单词会做 8 次上面的 self-attention 的计算
这样每个单词会得到 8 个不同的加权求和 z

3. 但在 feed-forward 处只能接收一个矩阵,所以需要将这八个压缩成一个矩阵
方法就是先将8个z矩阵连接起来,然后乘一个额外的权重矩阵WO

下图显示了在例句中,it 的不同的注意力 heads 所关注的位置,一个注意力的焦点主要集中在“animal”上,而另一个注意力集中在“tired”,换句话说,it 是 “animal”和“tired”的一种表现形式。
当然如果选了8个层,将所有注意力 heads 都添加到图片中,就有点难以解释了。

这里有一个细节,

即在每个 encoders 和 decoders 里面的 self-attention, ffnn,encoders-decoders attention 层,都有 resial 连接,还有一步 layer-normalization

下面我们看一下 Decoder 部分

1. 输入序列经过编码器部分,然后将最上面的 encoder 的输出变换成一组 attention 向量 K和V
这些向量会用于每个 decoder 的 encoder-decoder attention 层,有助于解码器聚焦在输入序列中的合适位置

重复上面的过程,直到 decoder 完成了输出,每个时间步的输出都在下一个时间步时喂入给最底部的 decoder,同样,在这些 decoder 的输入中也加入了位置编码,来表示每个字的位置。

2. 解码器中的 self attention 层与编码器中的略有不同
在解码器中,在 self attention 的 softmax 步骤之前,将未来的位置设置为 -inf 来屏蔽这些位置,这样做是为了 self attention 层只能关注输出序列中靠前的一些位置。

Encoder-Decoder Attention 层的工作方式与 multiheaded self-attention 类似,只是它用下面的层创建其 Queries 矩阵,从编码器栈的输出中获取 Keys 和 Values 矩阵。

3. 解码器最后输出的是一个向量,如何把它变成一个单词,这就要靠它后面的线性层和 softmax 层
线性层就是一个很简单的全连接神经网络,将解码器输出的向量映射成一个更长的向量。
例如我们有 10,000 个无重复的单词,那么最后输出的向量就有一万维。
每个位置上的值代表了相应单词的分数。

softmax 层将这个分数转换为了概率。

我们选择概率最大的所对应的单词,就是当前时间步的输出。

学习资源:
https://arxiv.org/pdf/1706.03762.pdf
https://jalammar.github.io/illustrated-transformer/
https://ai.googleblog.com/2017/08/transformer-novel-neural-network.html

2. Transformer详解,输入部分(词嵌入、位置编码)

由图可知:

inputs和带标签的输入分别进encoder和decoder

Positional Encoding

线性层

softmax层

由N个念渣编码器堆叠而成

每个编码器有两个子层相连接

第一个子层橘好->多头 自注意力机制 和规范化层以及一个残差连接

第二个子层->全连接层和规范化层以及一个残差连接

由N个解码器堆叠而成

每个编码器有三个子层相连接

第一个子层->一个多头 自注意力机制 层和规范化层以及一个残差连接

第二个子层->多头 注意力机制 和规范化层以及仔伍悄一个残差连接

第三个子层->全连接层和规范化层以及一个残差连接

目的是为了将目标文本的 数字表示 ->向量表示,为了在高维空间捕捉词汇间的关系

效果如下

在Transformer编码器中没有针对词汇位置信息的处理,故需要在embedding层后加入位置编码器,将 词汇位置不同可能会产生不同语义的信息 加入到嵌入张量中(embedding),用来弥补位置信息的缺失。

3. 为何Transformer论文作者声称“Attention is all you need”

详解Transformer (论文Attention Is All You Need). 正如论文的题目所说的,Transformer中抛弃了传统的CNN和RNN,睁返整个网络悉基饥结构完全是由Attention机制组成。. 更准确地讲,Transformer由且锋悔

4. Swin Transformer

目前transformer从语言到视觉任务的挑战主要是由于这两个领域间的差异:

为了解决以上两点,我们提出了层级Transformer,通过滑动窗口提取特征的方式将使得 self.attention 的计算量降低为和图像尺寸的线性相关。

我们观察到将语言领域迁移到视觉领域的主要问模缺指题可以被总结为两种:

在源扮耐码实现中两个模块合二为一,称为 PatchEmbedding 。输入图片尺寸为 的RGB图片,将 4x4x3 视为一个patch,用一个linear embedding 层将patch转换为任意dimension(通道)的feature。源码中使用4x4的stride=4的conv实现。->

这是这篇论文的核心模块。

window partition 分为 regular window partition 和 shift window partition ,对应于 W-MSA 和 SW-MSA 。通过窗口划分,将输入的 feature map 转换为 num_windows*B, window_size, window_size, C ,其中 num_windows = H*W / window_size / window_size 。然后resize 到 num_windows*B, window_size*window_size, C 进行attention。源码如下:

由 regular window partition 模块 和 mutil-head self attention 模块组成。
W-MSA相比于直接使用MSA主要是为了降低计算量。传统的transformer都是基于全局来计算注意力,因此计算复杂度非常高。但是swin transformer通过对每个窗口施加注意力,从而减少了计算量。attention的主要计算过程如下:

假设每一个 window 的区块大旦配小为 ,输入的尺寸为 ,以下为原始的 和 的计算复杂度:

虽然 降低了计算量,但是由于将attention限制在 window 内,因此不重合的 window 缺乏联系,限制了模型的性能。因此提出了 模块。在 MSA 前面加上一个 cycle shift window partition

swin transformer中没有使用 pooling 进行下采样,而是使用了和yolov5中的 focus 层进行 feature map 的下采样。 -> ,在使用一个全连接层-> ,在一个stage中将feature map的高宽减半,通道数翻倍。

基准模型结构命名为 Swin-B ,模型大小和计算复杂度和 ViT-B / DeiT-B 相近。同时我们也提出了 Swin-T , Swin-S 和 Swin-L ,分别对应 0.25× , 0.5× 和 2× 倍的模型尺寸和计算复杂度。 Swin-T 和 Swin-S 的计算复杂度分别和 ResNet-50 、 ResNet-101 相近。 默认设置为7。 代表第一层隐藏层的数量。

5. Transformer为什么适合自动驾驶毫末智行CEO顾维灏亲自揭秘

作为在自然语言处理(NLP)领域应用广泛的深度学习模型,Transformer 近两年强势来袭,不仅横扫 NLP 领域,而且在 CV 上也锋芒毕露。江湖传言,Transformer 架构就像是绝世高手的武林秘籍,得秘籍者得天下!

毫末智行作为国内首先大规模使用 Vision Transformer 技术的公司,CEO顾维灏第一时间在内部推动了此项技术的落地,力求在智能驾驶的赛道上能抢占先机。

Transformer 的杀手锏

据顾维灏介绍,最初的 Transformer 来自于 NLP,它的出现将 NLP 领域向前推动了一大步。其中的关键要素就是Transformer 具备:超强的序列建模能力、全局信息感知能力。

得益于这两点优势,Transformer 几乎取代了基于 RNN 的算法在 NLP 中的地位,也被引入到 CV 领域。但值得深入思考的是,Transformer 如何利用优势在视觉领域发挥作用呢?

要知道 NLP 中处理的是语句,句子是天然的序列数据,所以很容易理解 Transformer 是如何处理它们的。可在视觉领域,“序列”的概念并不是显式的,因此可以从空间和时间两个维度去理解。

首先是空间维度,静态图像从空间上可以被划分成多个区域(block),一种典型的划分方式就是按照高和宽进行划分,例如,一幅图像的高和宽分别是 H 和 W,如果要求 block 的长宽均为 M,那么最终会得到 (H/M W/M) 个 block。

其实可以把 block 看成是 NLP 句子中的词,这里的只不过是“视觉词”(visual words)。这样一来,就可以将一幅图像转化成一个按照空间顺序排列的 block 集合,一方面这样的视角转换保证了不丢失视觉信息,另一方面让应用 Transformer 变得非常容易。

另一种则是通过时间维度去理解视觉中的序列,即视频。视频是由静态的图像帧组成,把每一帧看成是一个基本单元(同样可以类别成句子中的词),那么就可以很自然地按照时间序列把一个片段组织起来,从而应用 Transformer 进行后续的特征提取。

图引自论文《An Image is Worth 16x16 Words Transformer for Image Recognition at scale”》

除了强大的序列建模能力,Transformer 的主要模块 Multi-Head Self-Attention 可以同时感知到输入序列的全局信息,这是 Transformer 相比于 CNN 的巨大优势。在 CNN 中,信息只能从局部开始,随着层数的增加,能够被感知到的区域逐步增大。然而 Transformer 从输入开始,每一层结构都可以看到所有的信息,并且建立基本单元之间的关联,也意味着Transformer 能够处理更加复杂的问题。

Transformer 的优化升级

目前处于 Transformer 在视觉中应用的早期,大家使用 Transformer 的方式主要参考了其在 NLP 中的应用经验。但是,如果直接将 Transformer 应用到视觉上,也会存在一些难题。

其一,核心模块多头注意力机制(Multi-Head Self-Attention )的计算量与 block 的个数成正比,因此在视觉中 block 数量要远多于 NLP 中句子的词数,这就造成了计算量的陡增。

其二,Transformer 擅长全局关系的学习,对于局部细节信息关注有限,然而视觉中很多任务需要足够丰富的细节信息做判断,比如语义分割。

针对上述的问题, 毫末智行人工智能研发团队对核心模块多头注意力机制(Multi-Head Self-Attention)进行了优化,同时采用了金字塔的结构增强 Transformer 对于细节信息的感知。

图引自论文《LeViT a Vision Transformer in ConvNet Clothing for Faster Inference》

Transformer 的未来演化

尽管我们在上面提到了 Transformer 的一些不尽如意之处,但随着研究的深入,大家逐步发现在同一结构中结合 CNN 和 Transformer 各自的优势,即可做到相互的扬长避短。在未来,把CNN 和 Transformer 进行整合将成为 Transformer 的演化路径之一。

具体来说,主干网使用 CNN,Head 使用 Transformer 结构,可以有效提升网络的速度(相比纯使用 Transformer);相反,主干网使用 Transformer 结构,Head 使用 CNN 的结构,可以有效提升结果精度(相比于纯使用 CNN)。

其次,核心模块 Multi-Head Self-Attention 内部也可以通过降低子空间的维度、对输入 block 进行分组等手段降低其计算量且不至于损失过多精度。

最后,通过控制 block 的粒度,使 Transformer 能够感知到不同尺度的信息,从而达到局部和全局的信息融合。

毫末智行团队已经将上述的改进逐步添加到了毫末智行自己的模型中。未来,我们将不断在提升速度的同时保证出色的精度,让 Transformer 在实际的业务中生根发芽。

图引自论文《End to End Object Detection with Transformers》

基于 Transformer 的感知算法表现出了极强的泛化性和鲁棒性,也因此顾维灏坚定认为,Transformer 的优秀特性极有可能在智能驾驶的场景中发挥出传统 CNN 算法所不能企及的感知能力。

目前, 毫末智行的人工智能团队正在逐步将基于 Transformer 的感知算法应用到实际的道路感知问题,例如车道线检测、障碍物检测、可行驶区域分割、红绿灯检测&识别、道路交通标志检测、点云检测&分割等。 未来,相关 Transformer 感知算法更加和稳定成熟后,逐步替换基于 CNN 的感知算法。

Transformer 技术的进一步应用,不仅为毫末智行在各条智能驾驶产品线上的视觉算法落地带来成倍的效率提升,还能够让各项视觉性能指标快速达到业内领先水平。

6. Transformer模型解析记录

整个Transformer模型由Encoder和Decoder两部分组成。Encoder负责对输入数据的编码,而Decoder负责对编码后的数据进行解码。

Encoder由N个结构相同,参数不共享的模块组成,每个模块又由多头自注意力层和全连接层组成,其中多头自注意力层和全连接层都加上了残差连接和layer normalization。

Decoder与Encoder结构类似,相比于Encoder,Decoder部分多了一个 Multi-Head Attention ,第一个 Multi-Head Attention 采用Masked操作,第二个 Multi-Head Attention 的 K 和 V 使用Encoder的手轮备输出,而Q使用上一个Decoder block的输出。
Decoder的输出通过一个线性层和softmax输出下一个翻译单词的概率。

Encoder由N个结构相同,参数不共享的的Layer组成(论文中N=6),也即图1左侧的单元,最左边有个“Nx”。
每个Layer由 Multi-Head Attention 和 Feed-Forward 两个sub_layer组成。其中每个sub_layer都加了残差连接(Resial Connect)和归一化(Normalization)操作。则每个sub_layer的输出可表示为:

Muti-Head Attention从结构上来看就是通过h个不同的线性变换将输入 投影到h个不同的 组合,最后将h个不同的Attention结果拼接起来,最后经过一个Liner层得到Muti-Head Attention的输出。

其中, 、

Muti-Head Attention输出的维度是

关于Attention的详细介绍,可以参考之前文档:

Feed Forward也称Position-wise feed-forward networks,该层主要提供非线性变换。之所以是position-wise是因为过线性层时每个位置i的变换参数是一样的。

该层比较简单,是一个两层的全连接层,第一层的激活函数为 Relu,第二层不使用激活函数,对应公式为:

:Attention输出之后的结果会和 相乘来进行维度变换,那这里为什么又要增加一个2层的FFN网络呢?
:FFN网络的加入给模型增加了非线性(Relu激活函数),增加了模型的表现能力。当然去掉FFN层也是可以的,只不过效果上会差些。

Decoder是图1的右半部分,与左半部分的Encoder类似,但又存在一些区别。

Decoder比Encoder多了一个Multi-Head Attention,第一个Multi-Head Attention采用Masked操作,因为在生成任务中,前面的词语是看不到后面词语的信息的,因此需要加入Masked来避免信息泄露。第二个Multi-Head Attention输入的 是根据Encoder的输出编码矩阵映射而来,而 是根据上一个Decoder的输出映射而来。

最后有一个 Softmax 层计算下一个翻译单词的概率。

模型在解码的过程中需要毕毁注意的是训练和预测不一样。
在训练时,解码桐罩是一次全部decode出来,用上一步的ground truth来预测(mask矩阵也会改动,让解码时看不到未来的token);
而预测时,因为没有ground truth了,需要一个个预测。

上面简单介绍了 Encoder Decoder 模块,下面简单介绍一下Transformer的Position Embedding。

引入Position Embedding主要是为了弥补Transformer模型对位置信息的不足,将Position Embedding与token Embedding相加后,即可保留各个token的位置信息。

论文作者提出了两种添加位置信息的的方法:
一种方法是直接用不同频率的正余弦函数直接计算各个token的位置id,公式如下:

另一种方法是直接学习出一个Position Embedding。

通过实验发现,两种方法结果差不多,最后作者选择了第一种方法。

Transformer 与 RNN 不同,可以比较好地并行训练。

Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding,否则 Transformer 就是一个词袋模型了。

Transformer 的重点是 Self-Attention 结构,其中用到的 Q, K, V矩阵通过输出进行线性变换得到。

Transformer 中 Multi-Head Attention 中有多个 Self-Attention,可以捕获单词之间多种维度上的相关系数 attention score。

Transformer 模型详解 (推荐)
【NLP】Transformer模型原理详解
【经典精读】Transformer模型深度解读

7. Transformer解读(附pytorch代码)

Transformer早在2017年就出现了,直到BERT问世,Transformer开始在NLP大放光彩,目前比较好的推进就是Transformer-XL(后期附上)。这里主要针对论文和程序进行解读,如有不详实之处,欢迎指出交流,如需了解更多细节之处,推荐知乎上 川陀学者 写的。本文程序的git地址在 这里 。程序如果有不详实之处,欢迎指出交流~

2017年6月,Google发布了一篇论文《Attention is All You Need》,在这篇论文中,提出了 Transformer 的模型尺搭,其旨在全部利用Attention方式来替代掉RNN的循环机制,从而通过实现并行化计算提速。在Transformer出现之前,RNN系列网络以及seq2seq+attention架构基本上铸就了所有NLP任务的铁桶江山。由于Attention模型本身就可以看到全局的信息, Transformer实现了完全不依赖于RNN结构仅利用Attention机制,在其并行性和对全局信息的有效处理上获得了比之前更好的效果。

纵观图1整个Transformer的结构,其核心模块其实就是三个:Multi-Head attention、Feed Forward 以及 Add&Norm。这里关于Multi-Head attention部分只讲程序的实现,关于更多细节原理,请移至开头推荐的知乎链接。

Transformer中的attention采用的是多头的self-attention结构,并且在编码器中,由于不同的输入mask的部分不一样,因此在softmax之前采用了mask操作,并且解码时由于不能看到t时刻之后的数据,同样在解码器的第一个Multi-Head attention中采用了mask操作,但是二者是不同的。因为编码器被mask的部分是需要在输入到Transformer之前事先确定好,而解码器第一个Multi-Head attention被mask的部分其实就是从t=1时刻开始一直到t=seq_len结束,对应于图2。在图2中,横坐标表示解码器一个batch上的输入序列长度(也就是t),紫色部分为被mask的部分,黄色部分为未被mask的部分,可以看出,随着t的增加,被mask的部分逐一减少。而解码器第二个Multi-Head attention的mask操作和编码器中是一样的。

mask+softmax程序如下:

mask操作其实就是对于无效橡困返的输入,用一个负无穷的值代替这个输入,这样在softmax的时候其值就是0。而在attention中(attention操作见下式),softmax的操作出来的结果其实就是attention weights,当attention weights为0时,表示不需要attention该位置的信息。

对于Multi-Head attention的实现,其实梁饥并没有像论文原文写的那样,逐一实现多个attention,再将最后的结果concat,并且通过一个输出权重输出。下面通过程序和公式讲解一下实际的实现过程,这里假设 , , 的来源是一样的,都是 ,其维度为[batch_size, seq_len, input_size]。(需要注意的是在解码器中第二个Multi-Head的输入中 与 的来源不一样)

首先,对于输入 ,通过三个权重变量得到 , , ,此时三者维度相同,都是[batch, seq_len, d_model],然后对其进行维度变换:[batch, seq_len, h, d_model//h]==>[batch, h, seq_len, d]==>[batch×h, seq_len, d],其中d=d_model//h,因此直接将变换后的 , , 直接做DotProctAttention就可以实现Multi-Head attention,最后只需要将DotProctAttention输出的维度依次变换回去,然后乘以输出权重就可以了。关于程序中的参数valid_length已在程序中做了详细的解读,这里不再赘述,注意的是输入的valid_length是针对batch这个维度的,而实际操作中由于X的batch维度发生了改变(由batch变成了batch×h),因此需要对valid_length进行复制。

FFN的实现是很容易的,其实就是对输入进行第一个线性变换,其输出加上ReLU激活函数,然后在进行第二个线性变换就可以了。

Add&norm的实现就是利用残差网络进行连接,最后将连接的结果接上LN,值得注意的是,程序在Y的输出中加入了dropout正则化。同样的正则化技术还出现在masked softmax之后和positional encoding之后。

positional encoding的实现很简单,其实就是对输入序列给定一个唯一的位置,采用sin和cos的方式给了一个位置编码,其中sin处理的是偶数位置,cos处理的是奇数位置。但是,这一块的工作确实非常重要的,因为对于序列而言最主要的就是位置信息,显然BERT是没有去采用positional encoding(尽管在BERT的论文里有一个Position Embeddings的输入,但是显然描述的不是Transformer中要描述的位置信息),后续BERT在这一方面的改进工作体现在了XLNet中(其采用了Transformer-XL的结构),后续的中再介绍该部分的内容。

无论是编码器还是解码器,其实都是用上面说的三个基本模块堆叠而成,具体的实现细节大家可以看开头的git地址,这里需要强调的是以下几点:

中出现的程序都在开头的git中了,直接执行main.ipynb就可以运行程序,如有不详实之处,还请指出~~~

8. swin transformer理解要点

这是跑通的分类以及分割源码介绍,大家有需要可以参考一下:
1、 Swin-Transformer分类源码(已跑通)
2、侍辩滚 Swin-Transformer分割源码(已跑通)
3、 Swin-Unet(分割改编)

我们假设图片的大小是224×224的,窗口大小是固定的,7×7。这里每个方框都是一个窗口,每个窗口是固定有7×7个patch,但是patch的大小是不固定的,它会随着patch merging的操作而发生变化。比如我们看这儿,patch大小是4×4的,那怎么变成8×8呢?我们把周边4个窗口的patch拼在一起,相当于patch扩大了2×2倍,从而得到8×8大小的patch。

我们发现经过这一系列的操作之后,patch的数目在变少,最后整张图只有一个窗口,7个patch。所以我们可以认为降采样是指让patch的数量减少,但是patch的大小在变大。

这便是对ViT的一个改进,ViT从头至尾都是对全局做self-attention,而swin-transformer是一个窗口在放大的过程,然后self-attention的计算是以窗口为单位去计算的,这样相当于引入了局部聚合的信息,和CNN的卷积过灶瞎程很相似,就像是CNN的步长和卷积核大小一样,这样就做到了窗口的不重合,区别在于CNN在每个窗口做的是卷积的计算,每个窗口最后得到一个值,这个值代表着这个窗口的特征。而swin transformer在每个窗口做的是self-attention的计算,得到的是一个更新过的窗口,然后通过patch merging的操作,把窗口做了个合并,再继续对这个合并后的窗口做self-attention的计算。

其实这边困扰了我一小下,因为我们印象中降采样都是像CNN一样,会变小,但是swin transformer没有给我们变小的感觉。其实这就是感受野没理解到位的问题,CNN到最后,设计适当,最后一个特征图的感受野是可以放大到整张图的,swin transformer最后一个stage也是一个窗口涵盖了整张图。

Swin-transformer是怎么把复杂度降低的呢? Swin Transformer Block这个模块和普通的transformer的区别就在于W-MSA,而它就是降低复杂度计算的大功臣。
关于复杂度的计算,我简单的给大家介绍一下,首先是transformer本身基于全局的复杂度计算,这一块儿讲起来有点复杂,感兴趣的同学我们可以会后一起探讨推导过程。在这里,我们假设已知MSA的复杂度是图像大小的平方,根据MSA的复杂度,我们可以得出A的复杂度是(3×3)²,最后复杂度是81。Swin transformer是在每个local windows(红色部分)计算self-attention,根据MSA的复杂度我们可以得出每个红色窗口的复杂度是1×1的平方,也就是1的四次方。然后9个窗口,这些窗口的复杂度加和,最后B的复杂度为9。

W-MSA虽然降低了计算复杂度,但是不重合的window之间缺乏信息交流,所以想要窗口之间的信息有所交流,那么就可以把左图演化成右图这样,但是这就产生了一个问题,如此操作,会产生更多的windows,并且其中一部分window小于普通的window,比如4个window -> 9个window,windows数量增加了一倍多。这计算量又上来了。因此我们有两个目的,Windows数量不能多老余,window之间信息得有交流。

我们看到,原来的图被划分了9个窗口,中间的区域A就是信息交流的证明。我们先把左上部分(蓝色以外的窗口)移动到右下,然后再用切分四块的方法去切这个图片,这时候区域A就被隔出来了,达到了我们想要的效果。

transformer的出现并不是为了替代CNN。因为transformer有着CNN没有的功能性,它不仅可以提取特征,还可以做很多CNN做不到的事情,比如多模态融合。而swin transformer就是一个趋势,将CNN与transformer各自的优势有效的结合了起来。这是暂时对它的一些细节补充。最近听说MLP出来了,还没有细看,时代进展未免也太快了,手里针对ViT改进的文章还没投出去,就已经开始要立不住脚了。

希望可以帮助到大家,如果你觉得这篇文章对你有一定的帮助,那就点个赞支持一下吧!如果有什么问题的话也可以在文章下面评论,我们一起交流解决问题!

以下是我所有文章的目录,大家如果感兴趣,也可以前往查看
👉戳右边: 打开它,也许会看到很多对你有帮助的文章

9. 为什么说Transformer的注意力机制是相对廉价的注意力机制相对更对于RNN系列及CNN系列算法有何优势

QA形式对自然语言处理中注意力机制(Attention)进行总结,并对Transformer进行深入解析。


二、Transformer(Attention Is All You Need)详解
1、Transformer的整体架构是怎样的?由哪些部分组成?
2、Transformer Encoder 与 Transformer Decoder 有哪些不同?
3、Encoder-Decoder attention 与self-attention mechanism有哪些不同?
4、multi-head self-attention mechanism具体的计算过程是怎样的?
5、Transformer在GPT和Bert等词向量预训练模型中具体是怎么应用的?有什么变化?

一、Attention机制剖析

1、为什么要引入Attention机制?

根据通用近似定理,前馈网络和循环网络都有很强的能力。但为什么还要引入注意力机制呢?

阅读全文

与transformer理论源码细节详解相关的资料

热点内容
橙app如何开启聊天 浏览:899
访问服务器公网地址 浏览:666
pdf打印底色去掉 浏览:463
java快递接口 浏览:397
哪个app可以教新爸爸 浏览:210
如何查看服务器系统版本信息 浏览:524
成都市土地出让金算法 浏览:702
钢筋加密标记 浏览:576
ps中扩展功能在文件夹的什么位置 浏览:904
双极压缩机为什么要先高压 浏览:527
苹果手机服务器填什么 浏览:832
android移动动画效果 浏览:691
电子和服务器是什么意思 浏览:691
phpurl中文乱码问题 浏览:893
程序员那么可爱大结局陆漓产子 浏览:538
java如何从云服务器读取本地文件 浏览:924
压缩空气软管制作方法 浏览:912
天河三号算法 浏览:925
php队列教程 浏览:634
洪水命令 浏览:531