Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >可视化VIT中的注意力

可视化VIT中的注意力

作者头像
数据派THU
发布于 2023-04-18 04:10:06
发布于 2023-04-18 04:10:06
1.1K00
代码可运行
举报
文章被收录于专栏:数据派THU数据派THU
运行总次数:0
代码可运行

来源:DeepHub IMBA

本文约4000字,建议阅读8分钟

本文为你介绍ViT模型。

2022年, Vision Transformer (ViT)成为卷积神经网络(cnn)的有力竞争对手,卷积神经网络目前是计算机视觉领域的最先进技术,广泛应用于许多图像识别应用。在计算效率和精度方面,ViT模型超过了目前最先进的(CNN)几乎四倍。

ViT是如何工作的?

ViT模型的性能取决于优化器、网络深度和特定于数据集的超参数等, 标准 ViT stem 采用 16 *16 卷积和 16 步长。

CNN 将原始像素转换为特征图。然后,tokenizer 将特征图转换为一系列令牌,这些令牌随后被送入transformer。然后transformer使用注意力方法生成一系列输出令牌。

projector 最终将输出令牌标记重新连接到特征图。

vision transformer模型的整体架构如下:

  • 将图像拆分为补丁(固定大小)
  • 展平图像块
  • 从这些展平的图像块中创建低维线性嵌入
  • 包括位置嵌入
  • 将序列作为输入发送到transformer编码器
  • 使用图像标签预训练 ViT 模型,然后在广泛的数据集上进行训练
  • 在图像分类的下游数据集进行微调

可视化注意力

ViT中最主要的就是注意力机制,所以可视化注意力就成为了解ViT的重要步骤,所以我们这里介绍如何可视化ViT中的注意力。

导入库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 import os import torch import numpy as np import math from functools import partial import torch import torch.nn as nn
 import ipywidgets as widgets import io from PIL import Image from torchvision import transforms import matplotlib.pyplot as plt import numpy as np from torch import nn
 import warnings warnings.filterwarnings("ignore")

创建一个VIT

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 def trunc_normal_(tensor, mean=0., std=1., a=-2., b=2.):     # type: (Tensor, float, float, float, float) -> Tensor     return _no_grad_trunc_normal_(tensor, mean, std, a, b)

 def _no_grad_trunc_normal_(tensor, mean, std, a, b):     # Cut & paste from PyTorch official master until it's in a few official releases - RW     # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf     def norm_cdf(x):         # Computes standard normal cumulative distribution function         return (1. + math.erf(x / math.sqrt(2.))) / 2.

 def drop_path(x, drop_prob: float = 0., training: bool = False):     if drop_prob == 0. or not training:         return x     keep_prob = 1 - drop_prob     # work with diff dim tensors, not just 2D ConvNets     shape = (x.shape[0],) + (1,) * (x.ndim - 1)     random_tensor = keep_prob + \         torch.rand(shape, dtype=x.dtype, device=x.device)     random_tensor.floor_()  # binarize     output = x.div(keep_prob) * random_tensor     return output

 class DropPath(nn.Module):     """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).    """
     def __init__(self, drop_prob=None):         super(DropPath, self).__init__()         self.drop_prob = drop_prob
     def forward(self, x):         return drop_path(x, self.drop_prob, self.training)

 class Mlp(nn.Module):     def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):         super().__init__()         out_features = out_features or in_features         hidden_features = hidden_features or in_features         self.fc1 = nn.Linear(in_features, hidden_features)         self.act = act_layer()         self.fc2 = nn.Linear(hidden_features, out_features)         self.drop = nn.Dropout(drop)
     def forward(self, x):         x = self.fc1(x)         x = self.act(x)         x = self.drop(x)         x = self.fc2(x)         x = self.drop(x)         return x

 class Attention(nn.Module):     def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):         super().__init__()         self.num_heads = num_heads         head_dim = dim // num_heads         self.scale = qk_scale or head_dim ** -0.5
         self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)         self.attn_drop = nn.Dropout(attn_drop)         self.proj = nn.Linear(dim, dim)         self.proj_drop = nn.Dropout(proj_drop)
     def forward(self, x):         B, N, C = x.shape         qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C //                                   self.num_heads).permute(2, 0, 3, 1, 4)         q, k, v = qkv[0], qkv[1], qkv[2]
         attn = (q @ k.transpose(-2, -1)) * self.scale         attn = attn.softmax(dim=-1)         attn = self.attn_drop(attn)
         x = (attn @ v).transpose(1, 2).reshape(B, N, C)         x = self.proj(x)         x = self.proj_drop(x)         return x, attn

 class Block(nn.Module):     def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,                  drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm):         super().__init__()         self.norm1 = norm_layer(dim)         self.attn = Attention(             dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)         self.drop_path = DropPath(             drop_path) if drop_path > 0. else nn.Identity()         self.norm2 = norm_layer(dim)         mlp_hidden_dim = int(dim * mlp_ratio)         self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim,                        act_layer=act_layer, drop=drop)
     def forward(self, x, return_attention=False):         y, attn = self.attn(self.norm1(x))         if return_attention:             return attn         x = x + self.drop_path(y)         x = x + self.drop_path(self.mlp(self.norm2(x)))         return x

 class PatchEmbed(nn.Module):     """ Image to Patch Embedding    """
     def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768):         super().__init__()         num_patches = (img_size // patch_size) * (img_size // patch_size)         self.img_size = img_size         self.patch_size = patch_size         self.num_patches = num_patches
         self.proj = nn.Conv2d(in_chans, embed_dim,                               kernel_size=patch_size, stride=patch_size)
     def forward(self, x):         B, C, H, W = x.shape         x = self.proj(x).flatten(2).transpose(1, 2)         return x

 class VisionTransformer(nn.Module):     """ Vision Transformer """
     def __init__(self, img_size=[224], patch_size=16, in_chans=3, num_classes=0, embed_dim=768, depth=12,                  num_heads=12, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop_rate=0., attn_drop_rate=0.,                  drop_path_rate=0., norm_layer=nn.LayerNorm, **kwargs):         super().__init__()         self.num_features = self.embed_dim = embed_dim
         self.patch_embed = PatchEmbed(             img_size=img_size[0], patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)         num_patches = self.patch_embed.num_patches
         self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))         self.pos_embed = nn.Parameter(             torch.zeros(1, num_patches + 1, embed_dim))         self.pos_drop = nn.Dropout(p=drop_rate)
         # stochastic depth decay rule         dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]         self.blocks = nn.ModuleList([             Block(                 dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,                 drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer)             for i in range(depth)])         self.norm = norm_layer(embed_dim)
         # Classifier head         self.head = nn.Linear(             embed_dim, num_classes) if num_classes > 0 else nn.Identity()
         trunc_normal_(self.pos_embed, std=.02)         trunc_normal_(self.cls_token, std=.02)         self.apply(self._init_weights)
     def _init_weights(self, m):         if isinstance(m, nn.Linear):             trunc_normal_(m.weight, std=.02)             if isinstance(m, nn.Linear) and m.bias is not None:                 nn.init.constant_(m.bias, 0)         elif isinstance(m, nn.LayerNorm):             nn.init.constant_(m.bias, 0)             nn.init.constant_(m.weight, 1.0)
     def interpolate_pos_encoding(self, x, w, h):         npatch = x.shape[1] - 1         N = self.pos_embed.shape[1] - 1         if npatch == N and w == h:             return self.pos_embed         class_pos_embed = self.pos_embed[:, 0]         patch_pos_embed = self.pos_embed[:, 1:]         dim = x.shape[-1]         w0 = w // self.patch_embed.patch_size         h0 = h // self.patch_embed.patch_size         # we add a small number to avoid floating point error in the interpolation         # see discussion at https://github.com/facebookresearch/dino/issues/8         w0, h0 = w0 + 0.1, h0 + 0.1         patch_pos_embed = nn.functional.interpolate(             patch_pos_embed.reshape(1, int(math.sqrt(N)), int(                 math.sqrt(N)), dim).permute(0, 3, 1, 2),             scale_factor=(w0 / math.sqrt(N), h0 / math.sqrt(N)),             mode='bicubic',        )         assert int(             w0) == patch_pos_embed.shape[-2] and int(h0) == patch_pos_embed.shape[-1]         patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim)         return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1)
     def prepare_tokens(self, x):         B, nc, w, h = x.shape         x = self.patch_embed(x)  # patch linear embedding
         # add the [CLS] token to the embed patch tokens         cls_tokens = self.cls_token.expand(B, -1, -1)         x = torch.cat((cls_tokens, x), dim=1)
         # add positional encoding to each token         x = x + self.interpolate_pos_encoding(x, w, h)
         return self.pos_drop(x)
     def forward(self, x):         x = self.prepare_tokens(x)         for blk in self.blocks:             x = blk(x)         x = self.norm(x)         return x[:, 0]
     def get_last_selfattention(self, x):         x = self.prepare_tokens(x)         for i, blk in enumerate(self.blocks):             if i < len(self.blocks) - 1:                 x = blk(x)             else:                 # return attention of the last block                 return blk(x, return_attention=True)
     def get_intermediate_layers(self, x, n=1):         x = self.prepare_tokens(x)         # we return the output tokens from the `n` last blocks         output = []         for i, blk in enumerate(self.blocks):             x = blk(x)             if len(self.blocks) - i <= n:                 output.append(self.norm(x))         return output

 class VitGenerator(object):     def __init__(self, name_model, patch_size, device, evaluate=True, random=False, verbose=False):         self.name_model = name_model         self.patch_size = patch_size         self.evaluate = evaluate         self.device = device         self.verbose = verbose         self.model = self._getModel()         self._initializeModel()         if not random:             self._loadPretrainedWeights()
     def _getModel(self):         if self.verbose:             print(                 f"[INFO] Initializing {self.name_model} with patch size of {self.patch_size}")         if self.name_model == 'vit_tiny':             model = VisionTransformer(patch_size=self.patch_size, embed_dim=192, depth=12, num_heads=3, mlp_ratio=4,                                       qkv_bias=True, norm_layer=partial(nn.LayerNorm, eps=1e-6))
         elif self.name_model == 'vit_small':             model = VisionTransformer(patch_size=self.patch_size, embed_dim=384, depth=12, num_heads=6, mlp_ratio=4,                                       qkv_bias=True, norm_layer=partial(nn.LayerNorm, eps=1e-6))
         elif self.name_model == 'vit_base':             model = VisionTransformer(patch_size=self.patch_size, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4,                                       qkv_bias=True, norm_layer=partial(nn.LayerNorm, eps=1e-6))         else:             raise f"No model found with {self.name_model}"
         return model
     def _initializeModel(self):         if self.evaluate:             for p in self.model.parameters():                 p.requires_grad = False
             self.model.eval()
         self.model.to(self.device)
     def _loadPretrainedWeights(self):         if self.verbose:             print("[INFO] Loading weights")         url = None         if self.name_model == 'vit_small' and self.patch_size == 16:             url = "dino_deitsmall16_pretrain/dino_deitsmall16_pretrain.pth"
         elif self.name_model == 'vit_small' and self.patch_size == 8:             url = "dino_deitsmall8_300ep_pretrain/dino_deitsmall8_300ep_pretrain.pth"
         elif self.name_model == 'vit_base' and self.patch_size == 16:             url = "dino_vitbase16_pretrain/dino_vitbase16_pretrain.pth"
         elif self.name_model == 'vit_base' and self.patch_size == 8:             url = "dino_vitbase8_pretrain/dino_vitbase8_pretrain.pth"
         if url is None:             print(                 f"Since no pretrained weights have been found with name {self.name_model} and patch size {self.patch_size}, random weights will be used")
         else:             state_dict = torch.hub.load_state_dict_from_url(                 url="https://dl.fbaipublicfiles.com/dino/" + url)             self.model.load_state_dict(state_dict, strict=True)
     def get_last_selfattention(self, img):         return self.model.get_last_selfattention(img.to(self.device))
     def __call__(self, x):         return self.model(x)

创建可视化函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 def transform(img, img_size):     img = transforms.Resize(img_size)(img)     img = transforms.ToTensor()(img)     return img

 def visualize_predict(model, img, img_size, patch_size, device):     img_pre = transform(img, img_size)     attention = visualize_attention(model, img_pre, patch_size, device)     plot_attention(img, attention)

 def visualize_attention(model, img, patch_size, device):     # make the image divisible by the patch size     w, h = img.shape[1] - img.shape[1] % patch_size, img.shape[2] - \         img.shape[2] % patch_size     img = img[:, :w, :h].unsqueeze(0)
     w_featmap = img.shape[-2] // patch_size     h_featmap = img.shape[-1] // patch_size
     attentions = model.get_last_selfattention(img.to(device))
     nh = attentions.shape[1]  # number of head
     # keep only the output patch attention     attentions = attentions[0, :, 0, 1:].reshape(nh, -1)
     attentions = attentions.reshape(nh, w_featmap, h_featmap)     attentions = nn.functional.interpolate(attentions.unsqueeze(         0), scale_factor=patch_size, mode="nearest")[0].cpu().numpy()
     return attentions

 def plot_attention(img, attention):     n_heads = attention.shape[0]
     plt.figure(figsize=(10, 10))     text = ["Original Image", "Head Mean"]     for i, fig in enumerate([img, np.mean(attention, 0)]):         plt.subplot(1, 2, i+1)         plt.imshow(fig, cmap='inferno')         plt.title(text[i])     plt.show()
     plt.figure(figsize=(10, 10))     for i in range(n_heads):         plt.subplot(n_heads//3, 3, i+1)         plt.imshow(attention[i], cmap='inferno')         plt.title(f"Head n: {i+1}")     plt.tight_layout()     plt.show()


 class Loader(object):     def __init__(self):         self.uploader = widgets.FileUpload(accept='image/*', multiple=False)         self._start()
     def _start(self):         display(self.uploader)
     def getLastImage(self):         try:             for uploaded_filename in self.uploader.value:                 uploaded_filename = uploaded_filename             img = Image.open(io.BytesIO(                 bytes(self.uploader.value[uploaded_filename]['content'])))
             return img         except:             return None
     def saveImage(self, path):         with open(path, 'wb') as output_file:             for uploaded_filename in self.uploader.value:                 content = self.uploader.value[uploaded_filename]['content']                 output_file.write(content)

对一个图像的注意力进行可视化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu") if device.type == "cuda":    torch.cuda.set_device(1)
 name_model = 'vit_small' patch_size = 8
 model = VitGenerator(name_model, patch_size,                      device, evaluate=True, random=False, verbose=True)

 # Visualizing Dog Image path = '/content/corgi_image.jpg' img = Image.open(path) factor_reduce = 2 img_size = tuple(np.array(img.size[::-1]) // factor_reduce) visualize_predict(model, img, img_size, patch_size, device)

本文代码

https://colab.research.google.com/drive/1tRRuT21W3VUvORCFRazrVaFLSWYbYoqL?usp=sharing

编辑:于腾凯

校对:林亦霖

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据派THU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【图像分类】Vision Transformer理论解读+实践测试
Vision Transformer是2021年谷歌在ICLR上提出的算法,算法原理并不复杂,但是其价值是开创性的。它首次将NLP领域火热的Transformer模型架构移植到了CV领域,打破了这两个领域壁垒,并取得不错的成效。
zstar
2022/09/20
3K0
【图像分类】Vision Transformer理论解读+实践测试
带掩码的自编码器MAE详解和Pytorch代码实现
监督学习是训练机器学习模型的传统方法,它在训练时每一个观察到的数据都需要有标注好的标签。如果我们有一种训练机器学习模型的方法不需要收集标签,会怎么样?如果我们从收集的相同数据中提取标签呢?这种类型的学
deephub
2021/12/15
3.8K0
带掩码的自编码器MAE详解和Pytorch代码实现
preprint版本 | 何凯明大神新作MAE | CVPR2022最佳论文候选
本文证明了蒙面自动编码器(MAE)是一种可扩展的计算机视觉自监督学习器。我们的MAE方法很简单:我们屏蔽输入图像的随机补丁并重建丢失的像素。
机器学习炼丹术
2021/12/06
1.3K0
preprint版本 | 何凯明大神新作MAE | CVPR2022最佳论文候选
一文了解视觉Transformer解析 !!
自2017年“注意力就是一切”的理念问世以来,Transformer模型便迅速再自然语言处理(NLP)领域展露头角,确立了其领先地位。到了2021年,“一张图片等于16x16个单词”的理念成功将Transformer模型引入计算机视觉任务中。自此以后,众多基于Transformer的架构纷纷涌现,应用于计算机视觉领域。
JOYCE_Leo16
2025/02/02
4361
一文了解视觉Transformer解析 !!
解析 Token to Token Vision Transformer
Vision Transformer!的提出让我们看到了Transformer模型在图像方向的潜力,但其有一些缺点,如需要超大型数据集(JFT)预训练,才能达到现在CNN的精度。本文分析了ViT的一些不合理之处:
BBuf
2021/03/11
7.7K0
【固本强基】Vision Transformers的注意力层概念解释和代码实现
“强基固本,行稳致远”,科学研究离不开理论基础,人工智能学科更是需要数学、物理和神经科学等基础学科提供有力支撑,为了紧扣时代脉搏,我们推出“强基固本”专栏,讲解AI领域的基础知识,为你的科研学习提供助力,夯实理论基础,提升原始创新能力,敬请关注。
马上科普尚尚
2024/03/11
4910
【固本强基】Vision Transformers的注意力层概念解释和代码实现
【YOLOv8】YOLOv8改进系列(8)----替换主干网络之Swin Transformer
论文介绍了一种新的视觉Transformer模型——Swin Transformer,它旨在成为计算机视觉领域的通用骨干网络。Swin Transformer通过其独特的层次化结构和移位窗口(Shifted Windows)机制,解决了传统Transformer在视觉任务中的计算复杂度问题,并在图像分类、目标检测和语义分割等多个任务中取得了优异的性能。
HABuo
2025/03/19
3210
【YOLOv8】YOLOv8改进系列(8)----替换主干网络之Swin Transformer
VIT Vision Transformer | 先从PyTorch代码了解
【前言】:看代码的时候,也许会不理解VIT中各种组件的含义,但是这个文章的目的是了解其实现。在之后看论文的时候,可以做到心中有数,而不是一片茫然。
机器学习炼丹术
2021/03/04
2.3K0
图像恢复SwinIR: Image Restoration Using Swin Transformer
在图像超分辨率、图像去噪、压缩等图像修复(Image restoration)任务中,卷积神经网络目前仍然是主流。但是卷积神经网络有以下两个缺点:
JOYCE_Leo16
2024/03/19
1.4K0
图像恢复SwinIR: Image Restoration Using Swin Transformer
CvT: 如何将卷积的优势融入Transformer
与之前BoTNet不同,CvT虽然题目中有卷积的字样,但是实际总体来说依然是以Transformer Block为主的,在Token的处理方面引入了卷积,从而为模型带来的局部性。最终CvT最高拿下了87.7%的Top1准确率。
BBuf
2022/01/27
9570
CvT: 如何将卷积的优势融入Transformer
MoA-Transformer | Swin-Transformer应该如何更好地引入全局信息?
基于Transformer的体系结构在自然语言处理(NLP)领域取得了巨大的成功。受Transformer在语言领域的巨大成功的启发,Vision Transformer被提出,并在ImageNet数据集上取得了优秀的性能。Vision Transformer就像NLP中的word token一样,将图像分割成patches并输入Transformer之中,并通过Transformer的几个multi-head self-attention层来建立远程依赖关系。
集智书童公众号
2022/02/11
9830
MoA-Transformer | Swin-Transformer应该如何更好地引入全局信息?
图解swin transformer
针对上述两个问题,我们提出了一种包含滑窗操作,具有层级设计的Swin Transformer。
BBuf
2021/04/30
5.5K1
Vision Transformer(ViT)
Transformer[1]是Google在2017年提出的一种Seq2Seq结构的语言模型,在Transformer中首次使用Self-Atttention机制完全代替了基于RNN的模型结构,使得模型可以并行化训练,同时解决了在基于RNN模型中出现了长距离依赖问题,因为在Self-Attention中能够对全局的信息建模。
felixzhao
2023/02/26
1.4K0
金字塔ViT | 华为提出使用金字塔结构改进Transformer,涨点明显(Pytorch逐行解读)
新的“PyramidTNT”通过建立层次表示,显著地改进了原来的TNT。PyramidTNT相较于之前最先进的Vision Transformer具有更好的性能,如Swin-Transformer。
集智书童公众号
2022/02/10
1K0
金字塔ViT | 华为提出使用金字塔结构改进Transformer,涨点明显(Pytorch逐行解读)
CNN、Transformer、MLP架构的经验性分析
ViT的兴起挑战了CNN的地位,随之而来的是MLP系列方法。三种架构各有特点,为了公平地比较几种架构,本文提出了统一化的框架SPACH来对比,得到了具有一定insight的结论。论文来自微软的A Battle of Network Structures: An Empirical Study of CNN, Transformer, and MLP
BBuf
2021/12/27
1.1K0
CNN、Transformer、MLP架构的经验性分析
LLM入门5 | SAM代码从入门到出门 | MetaAI
非常好加载,基本上pytorch和torchvision版本不太落后就可以加载。里面的model_type需要和模型参数对应上,"vit_h"或者"vit_l"或者"vit_b",即便加载最大的2.4G的vit_h模型,也只需要占用8G的显卡。算是非常小的模型了。这里SAM测试的效果,很多情况下效果并不太好,是一个foundation model,我觉得主要原因是模型参数比较少。导致他不能很好的解决所有的问题。正确用法是对小领域最微调。
机器学习炼丹术
2023/09/02
1.3K0
LLM入门5 | SAM代码从入门到出门 | MetaAI
使用Pytorch手写ViT — VisionTransformer
《The Attention is all you need》的论文彻底改变了自然语言处理的世界,基于Transformer的架构成为自然语言处理任务的的标准。
deephub
2022/11/11
8220
使用Pytorch手写ViT — VisionTransformer
Swin-T图像论文复现
在计算机视觉领域,卷积神经网络(CNN)一直是构建模型的主流选择。自从AlexNet在ImageNet竞赛中取得了突破性的成绩后,CNN的结构不断演进,变得更庞大、更深入、更多样化。与此同时,自然语言处理领域的网络架构发展则呈现不同的轨迹,目前最流行的是Transformer模型。这种模型专为处理序列数据和转换任务而设计,以其能够捕捉数据中的长距离依赖关系而著称。Transformer在语言处理方面的显著成就激发了研究者探索其在计算机视觉领域的应用潜力,近期的研究表明,它在图像分类、目标检测、图像分割等任务上已经取得了令人鼓舞的成果。 实验得到该模型在图像分类、图像检测、目标检测有很好的效果。
Srlua
2024/11/30
1750
Swin-T图像论文复现
FAST-VQA(论文复现)
现实世界视频分辨率的提高对于深度视频质量评估(VQA)在效率与准确性之间提出了一个难题。一方面,保持原始分辨率将导致不可接受的计算成本。另一方面,现有的实践方法,如图像缩放和裁剪,会因为细节和内容的丢失而改变原始视频的质量,因此对质量评估是有害的。通过对人类视觉系统中的时空冗余以及视觉编码理论的研究,我们观察到,一个邻域周围的质量信息通常是相似的,这促使我们研究一种有效的、对质量敏感的邻域表征方案用于VQA。在这项工作中,我们提出了一种统一的方案,即时空网格小立方体采样(St-GMS),以获得一种新型样本,我们称之为片段。首先将全分辨率视频按照预设的时空网格划分为小型立方体,然后对齐时间上的质量代表进行采样,以组成用于VQA的片段。此外,我们设计了一个专门为片段量身定制的网络架构,即片段注意力网络(FANet)。利用片段和FANet,所提出的效率端到端的FAST-VQA和FasterVQA在所有VQA基准测试上的性能显著优于现有方法,同时仅需要1/1612的FLOPs,相较于当前最先进技术大幅降低。
Srlua
2024/11/30
1850
FAST-VQA(论文复现)
金字塔Transformer,更适合稠密预测任务的Transformer骨干架构
以CNN为骨干的方案在计算机视觉的各个领域均取得极大的成功,本文研究了一种简单的无卷积骨干网络用于诸多稠密预测任务(包含检测、分割等)。近来提出的Transformer(ViT)主要是针对图像分类任务而设计,我们提出稠密预测任务提出了一种PVT方案(Pyramid Vision Transformer),它克服了将ViT向稠密预测任务迁移的困难。(1) 不同于ViT的低分辨率输出、高计算复杂度与内存消耗,PVT不仅可以得到更高分辨率的输出(这对于稠密预测任务尤为重要),同时按照金字塔形式渐进式收缩特征分辨率;(2) PVT继承了CNN与Transformer的优势,通过简单的替换CNN骨干使其成为不同视觉任务的统一骨干结构;(3) 通过充分的实验验证了PVT的优越性,在目标检测、语义分割、实例分割等任务上PVT均取得了优异性能。比如RetinaNet+PVT在COCO数据集上取得了40.4AP指标,超越了RetinaNet+ResNet50的36.3AP。
AIWalker
2021/03/04
1.1K0
金字塔Transformer,更适合稠密预测任务的Transformer骨干架构
推荐阅读
相关推荐
【图像分类】Vision Transformer理论解读+实践测试
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验