从Transformer到ViT:多模态编码器算法原理解析与实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Transformer到ViT:多模态编码器算法原理解析与实现相关的知识,希望对你有一定的参考价值。
从Transformer到ViT:多模态编码器算法原理解析与实现
- 模型架构与算法原理
- Image Token Embedding
- Multi-head Self-attention流程
- 线性变换
- MatMul
- Scale和softmax
- MatMul
- 前向层模块
- ADD NORM模块
- 思考
- 多模态模型应用的感想
- Paddle实现vit模型
Transformer架构是一种使用自注意力机制的神经网络,最初是由谷歌提出的,被广泛应用于自然语言处理和图像处理任务中。它是一种基于注意力机制的深度学习模型,适用于序列到序列的学习任务,例如机器翻译、语音识别、文本摘要等。
多模态Transformer前部分encoder算法是近年来在计算机视觉领域备受瞩目的研究方向之一。它的出现极大地推动了多模态信息的融合与处理,被广泛应用于图像、文本等多种数据类型的处理。
其中,Vision Transformer(ViT)是一种以Transformer为基础的视觉编码器,已经在各种视觉任务中取得了极佳的效果。本篇博客将介绍多模态Transformer前部分encoder算法的原理,重点讲解其在ViT中的实现,同时附带完整的ViT代码实现。如果您对多模态Transformer前部分encoder算法感兴趣,或是对ViT的实现方式想要深入了解,本文或许能为您提供帮助。
下面是vit模型核心架构图,下文是对模型架构各部分做了详细的介绍。
模型架构与算法原理
Image Token Embedding
模型输入一个将一张28x28x3的图片,模型先将图片切成一个16块,每一块为7x7。还是3通道的。
再将7x7,3通道的数据,并成一行,[1,7x7x3]=[1,147],
有16块那就是[16,147]。
接着将图片转为特征向量Embedding:
*=
其中就是要训练的参数,也就是下图中的Patch Embedding,
Multi-head Self-attention流程
依据模型输入的图片转换为的Image token Embedding,我们假设这个图像块集合为,每个图像块的维度为,接着将这个embedding输入到transformer中。
在transformer首先进入到Multi-head Self-attention进行以下四个步骤:线性变换、多头机制、scale和softmax、多头机制。下面我们将逐步说明这些步骤的算法流程。
线性变换
我们首先将每个图像块映射到一个10维的向量。
这个映射是通过对做一个线性变换得到的,具体而言,我们将乘以一个的权重矩阵得到一个10维的向量:
其中向量包含有,模型训练需要算出参数有三个变换矩阵
MatMul
我们计算每个图像块与其他所有图像块的注意力分数。具体而言,我们计算每对图像块的注意力分数,并将其用于加权求和所有图像块的向量表示。
为了计算注意力分数,我们需要先计算每对图像块之间的“相似度”
这个相似度是通过将与做点积得到的。其中,和分别是图像块和图像块通过线性变换得到的向量。这个点积的结果可以看作是两个向量的余弦相似度,用于衡量它们之间的相似程度,
Scale和softmax
然而,直接计算点积可能会因为向量维度较大而导致计算上的不稳定性,因此我们在计算前先将和除以一个缩放因子,就是特征的维度10,从而保证点积的值较小,不容易出现计算上的不稳定性,然后在进行softmax函数计算。
具体公式如下:
其中,表示向量点积运算。注意力分数的分母
是一个缩放因子,用于确保点积的结果不会过大或过小。
MatMul
最后结合向量计算出的注意力特征向量:
具体流程可以看下图
上面这种是对于自注意力的,还有一种多注意力
多注意力实现其实就是多个自注意力这样的结构结合起来,如下图所示
上面的,就是组合起来,以第一个自注意力来看,
其实就是自注意力里的
多头只是从计算上来说,每一个自注意的q不仅要与自己的k和v计算,还要结合其他的自注意的k和v计算。
最简单的例子来理解注意力,举例一个生活的例子来说
当我们将自注意力算法类比为一个学生学习一门学科的过程时,可以将看作是学生的注意力,看作是这门学科的大纲,则代表着这个学科的教材的内容。通过计算与的相似度,可以得到学生消耗注意力与大纲中不同知识点之间的分配权重,从而确定学生应该集中注意力去学习哪些知识点。最后,通过将这些权重乘以,可以得到学生学习到的知识内容。
多头注意力算法可以被类比为一个学生在学习多门学科的情况。在这种情况下,不同的学科可能具有不同的难度、内容和格式。因此,学生的注意力在不同的学科中可能有所不同。通过多头注意力算法,我们可以将学生的注意力与不同学科大纲中的知识点以及学科的教材内容相乘,从而得到不同学科下的学习成果。这样做的好处是,可以更好地利用不同学科中的优势,进一步提高学生的学习效果。
前向层模块
前向层模块由两个全连接层和一个残差连接组成。残差连接将输入直接添加到模块的输出上。全连接层包括一个线性变换和一个激活函数,其中线性变换将输入 x 乘以一个权重矩阵 W1,并加上偏置 b1,然后将结果输入激活函数进行非线性转换。激活函数通常为 ReLU。
前向层模块的计算公式如下:
其中 表示输入,和是第一个全连接层的权重矩阵和偏置向量,和
ADD NORM模块
ADD NORM 模块由一个残差连接和一个 Layer Normalization 组成。残差连接将输入直接添加到模块的输出上。Layer Normalization 用于归一化每个样本在不同维度上的特征。
ADD NORM 模块的计算公式如下:
其中 表示输入,Sublayer 表示 Transformer 模型中的一个子层(如自注意力模块或前向层模块)。
表示输入加上子层的输出。LayerNorm 对
思考
搞懂了算法各结构的原理,如下是我个人的几个思考
为什么这种transformer结构,将原始特征向量通过与上下文(或者上下图像)的相似度计算,得出的新的特征向量能够更准确的代表这个数据的特征向量呢?
Transformer 结构在自然语言处理和计算机视觉等领域广泛应用,主要原因是它具有以下优点:
- 上下文信息丰富。相比于传统的基于手工设计特征的方法,Transformer能够利用上下文信息对特征向量进行更加准确的表示。在自然语言处理中,上下文可以是当前单词所处的句子或段落,而在计算机视觉中,上下文可以是当前像素所处的图像区域。
- 处理长序列能力强。由于使用了自注意力机制,Transformer 能够对长序列进行有效的处理。在自然语言处理中,这使得Transformer 能够处理长文本,而在计算机视觉中,这使得 Transformer 能够对高分辨率的图像进行处理。
- 端到端的学习。Transformer结构能够直接从原始数据中学习特征表示,而无需手工设计特征。这使得模型能够从原始数据中学习到更加准确的特征表示,从而提高了模型的性能。
为什么多头注意力,比自注意力效果更好呢
多头注意力是一种在 Transformer 模型中使用的注意力机制,相比于单独使用自注意力机制,它能够提高模型的表现。这主要是由于以下几个原因:
- 多头注意力能够并行处理不同信息。在多头注意力中,模型使用多个注意力头同时学习不同的信息。这意味着模型能够并行处理多个不同的信息,从而加速模型的训练和推断过程。
- 多头注意力能够学习更加复杂的特征表示。由于多头注意力能够并行处理多个信息,模型能够学习更加复杂的特征表示。这能够帮助模型捕捉更加丰富和多样化的特征,从而提高模型的表现。
- 多头注意力能够提高模型的泛化能力。在多头注意力中,每个注意力头都能够学习不同的特征表示,这使得模型更加鲁棒并能够更好地泛化到新的数据。
总的来说,多头注意力能够并行处理多个信息,学习更加复杂的特征表示,并提高模型的泛化能力,这使得它比单独使用自注意力机制效果更好。
在transformer中encoder叠加了多个,它的作用是什么呢,是不断更精细化的求出图像与图像相似度之间的关系吗
在 Transformer 模型中,encoder 叠加了多个层,每个层都包含了多头注意力和前馈神经网络。encoder 叠加多层的作用是逐渐提取和组合输入序列中的信息,并生成更加准确的特征表示。这些特征表示最终被用于后续的任务,如机器翻译、语言模型、文本分类等。
具体来说,encoder 中的每一层都能够进一步优化模型的特征表示。通过多层叠加,模型能够逐渐捕捉输入序列中的更多信息,从而生成更加准确的特征表示。这些特征表示能够反映输入序列中的重要信息,并能够被用于后续的任务。
因此,encoder 叠加多层的作用并不是仅仅更精细地求出图像与图像之间的相似度,而是逐渐提取和组合输入序列中的信息,生成更加准确的特征表示,从而提高模型的性能。在计算机视觉任务中,输入序列可能是图像的像素值序列或者是图像的特征表示序列,而不仅仅是图像与图像之间的相似度。
多模态模型应用的感想
掌握了transformer就是前半部分,就算是知道了,我们现在有的数据图像、语音、文本是如何转为模型的特征向量了,
能获取到这些特征向量,应该说就可以输出任何标签类的任务,从实现原理熵也就是在transformer结构下游,增加全连接层实现输出。(这也是在大模型中使用预训练模型微调的一种方法)。
Paddle实现vit模型
# ViT Online Class
# Author: Dr. Zhu
# Project: PaddleViT (https://github.com/BR-IDL/PaddleViT)
# 2021.11
import paddle
import paddle.nn as nn
import numpy as np
from PIL import Image
paddle.set_device(cpu)
class Identity(nn.Layer):
def __init__(self):
super().__init__()
def forward(self, x):
return x
class Mlp(nn.Layer):
def __init__(self, embed_dim, mlp_ratio=4.0, dropout=0.):
super().__init__()
self.fc1 = nn.Linear(embed_dim, int(embed_dim * mlp_ratio))
self.fc2 = nn.Linear(int(embed_dim * mlp_ratio), embed_dim)
self.act = nn.GELU()
self.dropout = nn.Dropout(dropout)
def forward(self, x):
x = self.fc1(x)
x = self.act(x)
x = self.dropout(x)
x = self.fc2(x)
return x
class PatchEmbedding(nn.Layer):
def __init__(self, image_size, patch_size, in_channels, embed_dim, dropout=0.):
super().__init__()
self.patch_embedding = nn.Conv2D(in_channels, embed_dim, patch_size, patch_size)
self.dropout = nn.Dropout(dropout)
def forward(self, x):
# [n, c, h, w]
x = self.patch_embedding(x) # [n, c, h, w]
x = x.flatten(2) # [n, c, h*w]
x = x.transpose([0, 2, 1]) # [n, h*w, c]
x = self.dropout(x)
return x
class Attention(nn.Layer):
# TODO: 补全时,删除pass
def __init__(self, embed_dim, num_heads, qkv_bias=False, qk_scale=None, dropout=0., attention_dropout=0.):
super().__init__()
self.num_heads = num_heads
self.attn_head_size = int(embed_dim / self.num_heads)
self.all_head_size = self.attn_head_size * self.num_heads
self.qkv = nn.Linear(embed_dim, self.all_head_size*3)
if qk_scale == None:
self.scales = self.attn_head_size ** -0.5
else:
self.scales = qk_scale
self.proj = nn.Linear(self.all_head_size, embed_dim)
self.attn_dropout = nn.Dropout(attention_dropout)
self.proj_dropout = nn.Dropout(dropout)
self.softmax = nn.Softmax(axis=-1)
def transpose_multihead(self, x):
new_shape = x.shape[:-1] + [self.num_heads, self.attn_head_size]
x = x.reshape(new_shape)
x = x.transpose([0, 2, 1, 3])
return x
def forward(self, x):
qkv = self.qkv(x).chunk(3, axis=-1)
q, k, v = map(self.transpose_multihead, qkv)
attn = paddle.matmul(q, k, transpose_y=True)
attn = attn * self.scales
attn = self.softmax(attn)
attn_weights = attn
attn = self.attn_dropout(attn)
z = paddle.matmul(attn, v)
z = z.transpose([0, 2, 1, 3])
new_shape = z.shape[:-2] + [self.all_head_size]
z = z.reshape(new_shape)
z = self.proj(z)
z = self.proj_dropout(z)
return z, attn_weights
class EncoderLayer(nn.Layer):
def __init__(self, embed_dim):
super().__init__()
self.attn_norm = nn.LayerNorm(embed_dim)
self.attn = Attention()
self.mlp_norm = nn.LayerNorm(embed_dim)
self.mlp = Mlp(embed_dim)
def forward(self, x):
h = x
x = self.attn_norm(x)
x = self.attn(x)
x = x + h
h = x
x = self.mlp_norm(x)
x = self.mlp(x)
x = x + h
return x
class ViT(nn.Layer):
def __init__(self):
super().__init__()
self.patch_embed = PatchEmbedding(224, 7, 3, 16)
layer_list = [EncoderLayer(16) for i in range(5)]
self.encoders = nn.LayerList(layer_list)
self.head = nn.Linear(16, 10)
self.avgpool = nn.AdaptiveAvgPool1D(1)
self.norm = nn.LayerNorm(16)
def forward(self, x):
x = self.patch_embed(x) # [n, h*w, c]: 4, 1024, 16
for encoder in self.encoders:
x = encoder(x)
# avg
x = self.norm(x)
x = x.transpose([0, 2, 1])
x = self.avgpool(x)
x = x.flatten(1)
x = self.head(x)
return x
def main():
t = paddle.randn([4, 16, 96])
print(input shape = , t.shape)
model = Attention(embed_dim=96, num_heads=8,
qkv_bias=False, qk_scale=None, dropout=0., attention_dropout=0.)
print(model)
out, attn_weights = model(t)
print(out.shape)
print(attn_weights.shape)
if __name__ == "__main__":
main()
一文梳理视觉Transformer:与CNN相比,ViT赢在哪儿?
点击 机器学习算法与Python学习 ,选择加星标
精彩内容不迷路
机器之心报道
Transformer 近年来已成为视觉领域的新晋霸主,这个来自 NLP 领域的模型架构在 CV 领域有哪些具体应用?。
Transformer 作为一种基于注意力的编码器 - 解码器架构,不仅彻底改变了自然语言处理(NLP)领域,还在计算机视觉(CV)领域做出了一些开创性的工作。与卷积神经网络(CNN)相比,视觉 Transformer(ViT)依靠出色的建模能力,在 ImageNet、COCO 和 ADE20k 等多个基准上取得了非常优异的性能。
近日,一位名为 Nikolas Adaloglou 的博主撰写了一篇博客长文,综述了 ViT 领域的进展以及 ViT 与其他学科的交叉应用。
以下是博客原文:
ViT 的灵感来源于自然语言处理中的自注意力机制,其中将词嵌入替换成了 patch 嵌入。
以合理的规模训练 ViT
知识蒸馏
在 Kaggle 等深度学习竞赛中,集成(ensemble)是非常流行的一种方法。集成大体上是指平均多个已训练模型的输出以进行预测。这种简单的方法非常适合提高测试时的性能,然而它在推理过程中会慢 N 倍(其中 N 表示模型数量)。当在嵌入式设备中部署此类神经网络时,这就成了一个棘手的问题。解决这个问题常用的一种方法是知识蒸馏。
在知识蒸馏中,小模型(学生模型)通常是由一个大模型(教师模型)监督,算法的关键是如何将教师模型的知识迁移给学生模型。
尽管没有足够的基础理论支持,但知识蒸馏已被证明是一种非常有效的技巧。关于为什么集成的输出分布能提供与集成相当的测试性能,还有待发现。而使用集成的输出(略有偏差的平滑标签)相对于真实标签存在性能增益,这更加神秘。
DeiT 模型通过注意力训练数据高效的图像 Transformer 和蒸馏,这表明在没有外部数据的情况下,仅在 ImageNet 上训练 ViT 是可以的。该研究使用来自 Resnet 的已训练好的 CNN 模型作为单一教师模型。直观地讲,强大的数据假设(归纳偏置)让 CNN 比 ViT 更适合做教师网络。
自蒸馏
令人惊讶的是,有研究发现类似方法也可以通过对同一架构的单个模型(教师网络)进行知识蒸馏来实现。这个过程被称为自蒸馏,来自于 Zhang et al.2019 年的论文《Be Your Own Teacher: Improve the Performance of Convolutional Neural Networks via Self Distillation》。自蒸馏就是一种 N=1 的知识蒸馏,自蒸馏(使用具有相同架构的单个训练模型)也可以提高测试准确率。
ViT 的 Hard-label 蒸馏:DeiT 训练策略
在这种方法中,一个额外的可学习全局 token(即蒸馏 token),与 ViT 的 patch 嵌入相连。最关键的是,蒸馏 token 来自训练有素的教师 CNN 主干网络。通过将 CNN 特征融合到 Transformer 的自注意力层中,研究者们在 Imagenet 的 1M 数据上训练 DeiT。
DeiT 模型概览。
DeiT 使用如下损失函数进行训练:
其中 CE 是交叉熵损失函数,σ 是 softmax 函数。Z_cls 和 Z_distill 分别是来自类 token 和蒸馏 token 的学生模型的输出,ytrue 和 yteacher 分别是 ground truth 和教师模型的输出。
这种蒸馏技术使模型用更少的数据获得超强的数据增强,这可能会导致 ground truth 标签不精确。在这种情况下,教师网络似乎会产生更合适的标签。由此产生的模型系列,即数据高效图像 Transformer(DeiTs),在准确率 / 步长时间上与 EfficientNet 相当,但在准确率 / 参数效率上仍然落后。
除了蒸馏,还有一些研究大量使用图像增强来弥补缺乏可用的额外数据。此外,DeiT 依赖于随机深度等数据正则化技术。最终,强大的增强和正则化限制了 ViT 在小数据机制中的过拟合趋势。
Pyramid 视觉 Transformer
Pyramid 视觉 Transformer(PVT)的总体架构。
为了克服注意力机制的二次复杂度,Pyramid 视觉 Transformer(PVT)采用一种称为空间减少注意力 (SRA) 的自注意力变体。其特征是键和值的空间减少,类似于 NLP 领域的 Linformer 注意力。
通过应用 SRA,整个模型的特征空间维度缓慢减少,并通过在所有 transformer block 中应用位置嵌入来增强顺序的概念。PVT 已被用作目标检测和语义分割的主干网络,以处理高分辨率图像。
后来,该研究团队推出改进版 PVT-v2,主要改进如下:
重叠 patch 嵌入;
卷积前馈网络;
线性复杂度自注意力层。
重叠 patch 是改进 ViT 的一个简单而通用的想法,尤其是对于密集任务(例如语义分割)。通过利用重叠区域 /patch,PVT-v2 可以获得图像表征的更多局部连续性。
全连接层(FC)之间的卷积消除了每一层中对固定大小位置编码的需要。具有零填充(zero padding,p=1)的 3x3 深度卷积 (p=1) 旨在补偿模型中位置编码的移除(它们仍然存在,但只存在于输入中)。此过程可以更灵活地处理多种图像分辨率。
最后,使用键和值池化(p=7),自注意力层就减小到了与 CNN 类似的复杂度。
Swin Transformer:
使用移位窗口的分层视觉 Transformer
Swin Transformer 旨在从标准 NLP transformer 中建立局部性的思想,即局部或窗口注意力:
在 Swin Transformer 中,局部自注意力被用于非重叠窗口。下一层的窗口到窗口通信通过逐步合并窗口来产生分层表征。
如上图所示,左侧是第一层的常规窗口分区方案,其中在每个窗口内计算自注意力。右侧第二层中的窗口分区被移动了 2 个图像 patch,导致跨越了先前窗口的边界。
局部自注意力随图像大小线性缩放 O (M*N) 而不是 O (N^2),在用于序列长度 N 和 M 窗口大小。
通过合并添加许多局部层,有一个全局表示。此外,特征图的空间维度已显着降低。作者声称在 ImageNet-1K 和 ImageNet-21K 上都取得了有希望的结果。
视觉 Transformer 的自监督训练:DINO
Facebook AI 的研究提出了一个强大的框架用于训练大规模视觉数据。提议的自监督系统创建了如此强大的表征,你甚至不需要在上面微调线性层。这是通过在数据集的冻结训练特征上应用 K - 最近邻 (NN) 来观察到的。作者发现,训练有素的 ViT 可以在没有标签的情况下在 ImageNet 上达到 78.3% 的 top-1 准确率。
该自监督框架如下图所示:
与其他自监督模型相比,他们使用了交叉熵损失,就像在典型的自蒸馏场景中所做的那样。尽管如此,这里的教师模型是随机初始化的,其参数是根据学生参数的指数移动平均值更新的。为了让它 work,研究者将带温度参数的 softmax 应用于具有不同温度的教师和学生模型。具体来说,教师模型得到的温度参数更小,这意味着更敏锐的预测。最重要的是,他们使用了从 SWAV 中获得的多重裁剪方法,效果更佳,在这种情况下教师只能看到全局视图,而学生可以访问转换后的输入图像的全局和局部视图。
对于 CNN 架构来说,该框架并不像对视觉 Transformer 那样有益。那又该如何从图像中提取什么样的特征?
作者将经过训练的 VIT 的自注意力头输出可视化。这些注意力图说明模型自动学习特定于类的特征,导致无监督的对象分割,例如前景与背景。
此属性也出现在自监督预训练的卷积神经网络中,但需要一种特殊的方法来可视化特征。更重要的是,自注意力头学习补充信息并通过为每个头部使用不同的颜色来说明。默认情况下,这根本不是通过自注意力获得的。
DINO 多注意力头可视化。
Scaling 视觉 Transformer
深度学习和规模是相关的。事实上,规模是很多 SOTA 实现的关键因素。在这项研究中,来自 Google Brain Research 的作者训练了一个稍微修改过的 ViT 模型,它有 20 亿个参数,并在 ImageNet 上达到了 90.45 % 的 top-1 准确率。这种过度参数化的一般化模型在少样本学习上进行了测试,每类只有 10 个示例情况下。在 ImageNet 上达到了 84.86% 的 top-1 准确率。
小样本学习是指在样本数量极其有限的情况下对模型进行微调。小样本学习的目标通过将获得的预训练知识稍微适应特定任务来激励泛化。如果成功地预训练了大型模型,那么在对下游任务非常有限的理解(仅由几个示例提供)的情况下表现良好是有意义的。
以下是本文的一些核心贡献和主要结果:
模型大小可能会限制表征质量,前提是有足够的数据来提供它;
大型模型受益于额外的监督数据,甚至超过 1B 图像。
上图描绘了从 300M 图像数据集 (JFT-300M) 切换到 30 亿图像 (JFT-3B) 而不进行任何进一步缩放的效果。中型 (B/32) 和大型 (L/16) 模型都受益于添加数据,大致是一个常数因子。结果是在整个训练过程中通过小样本(线性)评估获得的。
大模型的样本效率更高,以更少的可见图像达到相同的错误率水平。
为了节省内存,他们删除了类 token (cls)。相反,他们评估了全局平均池化和多头注意力池化,以聚合所有 patch token 的表征。
他们对头部和称为「主干」的其余层使用了不同的权重衰减。作者在下图中很好地证明了这一点。框值是小样本精度,而横轴和纵轴分别表示主干和头部的权重衰减。令人惊讶的是,头部的更强衰减会产生最好的结果。作者推测,头部的强烈权重衰减会导致表示具有更大的类之间的余量。
这或许是可以更广泛地应用于预训练 ViT 的最有趣的发现。
他们在训练开始时使用了热身阶段,在训练结束时使用了冷却阶段,其中学习率线性退火为零。此外,他们使用了 Adafactor 优化器,与传统的 Adam 相比,内存开销为 50%。
在同一个波长,你可以找到另一个大规模的研究:《如何训练你的 ViT?视觉 Transformer 中的数据、增强和正则化》(How to train your ViT? Data, Augmentation, and Regularization in Vision Transformers)
替代自注意力:独立 token + 通道混合方式
众所周知,自注意力可以作为一种具有快速权重的信息路由机制。到目前为止,有 3 篇论文讲述了同样的故事:用 2 个信息混合层替换自注意力;一种用于混合 token(投影 patch 向量),一种用于混合通道 / 特征信息。
MLP-Mixer
MLP-Mixer 包含两个 MLP 层:第一个独立应用于图像 patch(即「混合」每个位置的特征),另一个跨 patch(即「混合」空间信息)。
MLP-Mixer 架构。
XCiT:互协方差图像 Transformer
另一个是最近的架构 XCiT,旨在修改 ViT 的核心构建 block:应用于 token 维度的自注意力。
XCiT 架构。
XCA:对于信息混合,作者提出了一种交叉协方差注意力 (XCA) 函数,该函数根据 token 的特征维度而不是根据其本身进行操作。重要的是,此方法仅适用于 queries、keys、values 集的 L2 归一化。L2 范数用 K 和 Q 字母上方的 hat 表示。乘法的结果在 softmax 之前也归一化为 [-1,1] 。
局部 Patch 交互:为了实现 patch 之间的显式通信,研究者添加了两个 depth-wise 3×3 卷积层,中间有批归一化和 GELU 非线性。Depth-wise 卷积独立应用于每个通道(这里的 patch)。
ConvMixer(加链接:patch 成为了 ALL You Need?挑战 ViT、MLP-Mixer 的简单模型来了)
自注意力和 MLP 理论上是更通用的建模机制,因为它们允许更大的感受野和内容感知行为。尽管如此,卷积的归纳偏差在计算机视觉任务中具有不可否认的成果。
受此启发,研究者提出了另一种基于卷积网络的变体,称为 ConvMixer。主要思想是它直接对作为输入的 patch 进行操作,分离空间和通道维度的混合,并在整个网络中保持相同的大小和分辨率。
更具体地说,depthwise 卷积负责混合空间位置,而逐点卷积(1x1x 通道内核)用于混合通道位置,如下图所示:
通过选择较大的内核大小来创建较大的感受野,可以实现远距离空间位置的混合。
多尺度视觉 Transformer
CNN 主干架构受益于通道的逐渐增加,同时降低了特征图的空间维度。类似地,多尺度视觉 Transformer (MViT) 利用了将多尺度特征层次结构与视觉 Transformer 模型相结合的想法。在实践中,作者从 3 个通道的初始图像大小开始,逐渐扩展(分层)通道容量,同时降低空间分辨率。
因此,创建了一个多尺度的特征金字塔。直观地说,早期层将学习高空间与简单的低级视觉信息,而更深层负责复杂的高维特征。
视频分类:Timesformer
在图像任务成功后,视觉 Transformer 被应用于视频识别。这里介绍两种架构:
用于视频识别的基于 block 与基于架构 / 基于模块的时空注意力架构。
右图:缩小架构级别。所提出的方法将空间 Transformer 应用于投影图像 block,然后有另一个网络负责捕获时间相关性。这类似于基于视频处理的 CNN+LSTM 获胜策略。
左图:可以在自注意力级别实现的时空注意力,红框中是最佳组合。通过首先将图像帧视为 token 来在时域中顺序应用注意力。然后,在 MLP 投影之前应用两个空间维度的组合空间注意力。下面是该方法的 t-SNE 可视化:
使用 Timesformer t-SNE 进行特征可视化。
「每个视频都可视化为一个点。属于同一动作类别的视频具有相同的颜色。具有分割时空注意力的 TimeSformer 比具有仅空间注意力或 ViT 的 TimeSformer 在语义上学习更多可分离的特征。」
语义分割中的 ViT:SegFormer
英伟达提出了一种配置良好的设置,名为 SegFormer。SegFormer 的设计组件很有趣。首先,它由一个输出多尺度特征的分层 Transformer 编码器组成。其次,它不需要位置编码,因为当测试分辨率与训练不同时,这会降低性能。
SegFormer 使用一个超级简单的 MLP 解码器来聚合编码器的多尺度特征。与 ViT 不同的是,SegFormer 采用了小的图像 patch,例如 4 x 4 这种,众所周知,这有利于密集预测任务。所提出的 Transformer 编码器输出 1/4、1/8、1/16、1/32 多级特征的原始图像分辨率。这些多级特征提供给 MLP 解码器来预测分割掩码。
Mix-FFN:为了减轻位置编码的影响,研究者使用 零填充的 3 × 3 卷积层来泄漏位置信息。Mix-FFN 可以表述为:
高效的自注意力是 PVT 中提出的,它使用缩减比率来减少序列的长度。结果可以通过可视化有效感受野 (ERF) 来定性测量:
「SegFormer 的编码器自然地产生局部注意力,类似于较低阶段的卷积,同时能够输出高度非局部注意力,有效地捕捉第 4 阶段的上下文。如放大补丁所示,MLP 头部(蓝色框)的 ERF 与 Stage-4(红色框)不同,除了非局部注意力之外,局部注意力明显更强。」
医学成像中的视觉 Transformer:Unet + ViT = UNETR
尽管在医学成像方面还有其他尝试,但 UNETR 提供了最有说服力的结果。在这种方法中,ViT 适用于 3D 医学图像分割。研究表明,简单的适应足以改善几个 3D 分割任务的基线。
本质上,UNETR 使用 Transformer 作为编码器来学习输入音频的序列表示。与 Unet 模型类似,它旨在有效捕获全局多尺度信息,这些信息可以通过长残差连接传递给解码器,以不同的分辨率形成残差连接以计算最终的语义分割输出。
UNETR 架构。
以下是论文的一些分割结果:
原文链接:
https://theaisummer.com/transformers-computer-vision/?hss_channel=tw-1259466268505243649&continueFlag=8cde49e773efaa2b87399c8f547da8fe
觉得不错,请点个在看呀
以上是关于从Transformer到ViT:多模态编码器算法原理解析与实现的主要内容,如果未能解决你的问题,请参考以下文章
从ViT到Swin,10篇顶会论文看Transformer在CV领域的发展历程
一文梳理视觉Transformer:与CNN相比,ViT赢在哪儿?
2021深度学习的研究方向推荐!TransformerSelf-SupervisedZero-Shot和多模态
Transformer专题Vision Transformer(ViT)原理 + 代码