Vision Transformers for Dense Prediction论文笔记

news/2025/2/13 23:05:25/

文章目录

  • Vision Transformers for Dense Prediction, ICCV, 2021
  • 一、背景介绍
  • 二、网络结构
  • 三、实验结果
      • 1.语义分割实验
      • 2.消融实验

Vision Transformers for Dense Prediction, ICCV, 2021

一、背景介绍

本篇论文主要提出一种网络,基于Transformer去进行密集预测。

众所周知,对于密集预测任务,常见的网络架构为Encoder+Decoder结构。当Encoder提取的特征有损时,Decoder很难去进行恢复。但是目前常用的卷积网络架构常常使用下采样方式,**逐步增加感受野,将低级特征分组为抽象的高级特征,同时确保网络的内存和计算需求保持易于处理。**但是,下采样有一个明显的缺点,特征分辨率和粒度(我感觉这里的粒度像是细粒度特征)在模型的更深层特征丢失,在Decoder中难以恢复。虽然,特征分辨率和粒度对于图像分类这种任务可能影响不大,但是对于密集预测任务如语义分割而言却是极为重要的。

目前为了缓解特征和粒度的丢失,不少方法被提出来,如以更高的输入分辨率进行训练(如果计算预算允许)、扩张卷积 [51] 以快速增加感受野而无需下采样、适当放置从编码器的多个阶段到解码器的跳过连接,或者,更多最近,通过在整个网络中并行连接多分辨率表示。 作者认为这些方法始终没有脱离使用卷积,故作者想要使用Transformer,如ViT来进行特征提取。

作者认为与全卷积网络不同,视觉转换器主干在计算初始化图像嵌入后放弃显示下采样操作,并在所有处理阶段保持具有恒定维度的表示。此外,他在每个阶段都有一个全局感受野。

二、网络结构

在这里插入图片描述

还是类似Swin Transformer有着上下采样操作。

Encoder部分就是直接使用的VIT,不同点在于作者令patch大小为16x16,输入维度为768(ViT-Base)和1024(ViT-Large)。作者这样解释道说768已经大于等于16x16x3了,这也就意味着可以保留对任务有益的信息。

Decoder部分,作者分别先选取ViT中的四个Transformer block的输出,通过Ressemble模块先把特征转化为卷积能够处理的特征,之后进行上采样或下采样,然后通过Fusion模块将这4个层的特征连接起来。这样便得到最终的输出了,但最终的输出尺寸大小并不是输入图片的原图大小,而是原图的一半。后续会根据具体任务添加不同的Head。

Ressemble模块分为三个部分Read,这个部分就是对于readout token如何处理,因为接下来要通过Concatenate模块将Transformer Block的输出转化为卷积能够处理的特征,故需要从原来的RNp+1×DR^{N_p+1\times D}RNp+1×D变成RNp×DR ^{N_p\times D}RNp×D。关于readout token如何处理作者提出了三种解决方案:

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述

Concatenate模块就比较简单了,之前Transformer Block输出特征维度是RNp×DR^{N_p\times D}RNp×D,而卷积需要的特征维度是类似于H×W×CH\times W\times CH×W×C,这就需要进行转化了,因为Transformer Block输出特征始终令token个数Np=HW/p2N_p=HW/p^2Np=HW/p2。故只需要reshape类似的操作即可。接下来便是需要进行上下采样得到不同尺度的特征了,这里作者使用了卷积进行下采样,反卷积进行上采样(密集预测常见做法,因为ViT每个Transformer Block模块输出特征尺寸一样,且p=16p=16p=16,故需要使用其它方法进行上下采样,这里作者是基于卷积,而Swin Transformer却不是基于卷积)。

最后就是不同尺度的特征融合模块Fusion了。这个模块内容就简单很多了,其中的Residual Conv Unit模块就是一个残差卷积模块。Resample模块使用的是线性插值。

class ResidualConvUnit(nn.Module):"""Residual convolution module."""def __init__(self, features):"""Init.Args:features (int): number of features"""super().__init__()self.conv1 = nn.Conv2d(features, features, kernel_size=3, stride=1, padding=1, bias=True)self.conv2 = nn.Conv2d(features, features, kernel_size=3, stride=1, padding=1, bias=True)self.relu = nn.ReLU(inplace=True)def forward(self, x):"""Forward pass.Args:x (tensor): inputReturns:tensor: output"""out = self.relu(x)out = self.conv1(out)out = self.relu(out)out = self.conv2(out)return out + xclass FeatureFusionBlock(nn.Module):"""Feature fusion block."""def __init__(self, features):"""Init.Args:features (int): number of features"""super(FeatureFusionBlock, self).__init__()self.resConfUnit1 = ResidualConvUnit(features)self.resConfUnit2 = ResidualConvUnit(features)def forward(self, *xs):"""Forward pass.Returns:tensor: output"""output = xs[0]if len(xs) == 2:output += self.resConfUnit1(xs[1])output = self.resConfUnit2(output)output = nn.functional.interpolate(output, scale_factor=2, mode="bilinear", align_corners=True)return output

三、实验结果

由于我只对语义分割比较熟悉,故只看了语义分割的相关实验,当然消融实验也看了。

在此,先说一下因为论文通过最后一个Fusion输出的特征图只有原图的1/2,故需要添加Head将特征图上采样到原图大小。

	    head = nn.Sequential(nn.Conv2d(features, features, kernel_size=3, padding=1, bias=False),nn.BatchNorm2d(features),nn.ReLU(True),nn.Dropout(0.1, False),nn.Conv2d(features, num_classes, kernel_size=1),Interpolate(scale_factor=2, mode="bilinear", align_corners=True), # 上采样两倍)self.auxlayer = nn.Sequential(nn.Conv2d(features, features, kernel_size=3, padding=1, bias=False),nn.BatchNorm2d(features),nn.ReLU(True),nn.Dropout(0.1, False),nn.Conv2d(features, num_classes, kernel_size=1),)

1.语义分割实验

在这里插入图片描述

其中ViT-Large因为数据集相对较小,故性能相对较差。此外,在Table 5中作者在小数据集上进行了微调结果还是挺不错的。下面的可视化结果可以发现DPT 倾向于产生更清晰和更细粒度的对象边界描绘,并且在某些情况下预测也不会那么混乱。
在这里插入图片描述

2.消融实验

这里面有个实验我是比较感兴趣的,就是Inference resolution。下面我们来看看消融实验都干了些啥。

  • Skip connections: 作者探讨了ViT不同层的输出,得到结果发现从包含低级特征的层以及包含高级特征的更深层中挖掘特征是有益的。

在这里插入图片描述

  • Readout token: 作者方案中提供了三种readout token处理方式,效果如下。
    在这里插入图片描述

  • Backbones:
    在这里插入图片描述

  • Inference speed:

在这里插入图片描述

  • Inference resolution: 虽然全卷积架构在其最深层可以具有较大的有效感受野,但靠近输入的层是局部的并且具有较小的感受野。因此,当以与训练分辨率明显不同的输入分辨率执行推理时,性能会受到严重影响。另一方面,Transformer 编码器在每一层都有一个全局感受野。我们推测这会降低 DPT 对推理分辨率的依赖。为了检验这个假设,我们绘制了在高于 384 × 384 像素训练分辨率的分辨率下执行推理时不同架构的性能损失。我们在图 4 中绘制了相对于在训练分辨率下执行推理的性能的相对性能下降。我们观察到,随着推理分辨率的增加,DPT 变体的性能确实下降得更加优雅。
    在这里插入图片描述

http://www.ppmy.cn/news/41460.html

相关文章

tpm2-tools源码分析之tpm2_createprimary.c(3)

接前一篇文章:tpm2-tools源码分析之tpm2_createprimary.c(2) 本文对tpm2_createprimary.c中的tpm2_tool_onrun函数进行详细解析。 先再次贴出该函数源码: static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flag…

js闭包处理

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 闭包的作用:通过一系方法,将函数内部的变量(局部变量)转化为全局变量 一、变量的作用域 要理解闭包,首先必须理解Javascrip…

不良事件上报系统源码 有演示,已在多家医院运营多年

不良事件上报系统源码,医院安全不良事件管理系统源码 技术架构:前后端分离,仓储模式,BS架构,有演示,已在多家医院完美运营。 相关技术:PHPvscodevue2elementlaravel8mysql5.7 文末获取联系&am…

1.让自己习惯C++(条款1-4)

目录 条款01:视C为一个语言联邦 条款02:尽量以const,enum,inline替换#define 条款03:尽可能使用 const 条款04:确定对象被使用前已经被初始化 条款01:视C为一个语言联邦 可以将C的语言分为…

黑马点评Redis实战(短信登录;商户查询缓存)

黑马点评 通过一个类似于大众点评的项目了解学习redis在实战项目中的使用,下面是项目中会涉及到的模块: 一、导入黑马点评项目 导入springboot项目,导入sql脚本到数据库,开启nginx,更改项目配置文件中的redis和mys…

腾讯空降测试工程师,绩效次次拿S,真是砂纸擦屁股,给我露了一手啊

​上周我们公司的绩效面谈全部结束了,每年到这个时间点就是打绩效的时候了,对于职场打工人来说绩效绝对是最重要的事情之一,原因也很简单:奖金、晋升、涨薪都和它有关系。 比如下面这个美团员工在脉脉上的自曝就很凄凉&#xff1…

leetcode785. 判断二分图

https://leetcode.cn/problems/is-graph-bipartite/判断给定的图是否为二分图,如果图是二分图,返回 true ,否则,返回 false 。二分图 定义:如果能将一个图的节点集合分割成两个独立的子集 A 和 B ,并使图中…

科易动力携手企企通,打造数字化采购与供应链管理平台

近日,苏州科易新动力科技有限公司(以下简称“科易动力”)携手企企通举办了数字化采购项目启动会,双方企业高层、相关部门负责人参加了此次会议。会上,双方就数字化采购管理平台建设达成共识,企企通将将根据…