【深度学习】语义分割-论文阅读:( CVPR 2021)SETR:Rethinking Semantic Segmentation from a Sequence-to-Sequence Perspe

0.详情

名称:Rethinking Semantic Segmentation from a Sequence-to-Sequence Perspective with Transformers
单位:发表于2021年3月份,是由复旦和腾讯优图联合提出的一个基于ViT的新型架构的语义分割模型。
论文:论文
代码:代码
参考笔记:
1。归纳点清晰
2.简洁版

FCN编码器使用CNN提取特征,即增加特征图深度、牺牲分辨率的方式提取特征。
而SETR使用的transformer,不增加特征图深度、也不牺牲分辨率。

本文介绍基于ViT的语义分割的第一个代表模型——SEgementation TRansformer (SETR),提出以纯Transformer结构的编码器来代替CNN编码器,改变现有的语义分割模型架构。

1. 摘要

语义分割以往做法:
基于带有Encoder-Decoder结构的FCN进行设计的。Encoder逐渐降低空间分辨率,同时利用逐渐变大的感受野学习到更为抽象的语义特征

近期做法:
鉴于上下文建模对语义分割的重要性,最新的一些研究聚焦于使用空洞卷积或者插入注意力模块来增大感受野这个方面。然而,这些研究仍然是基于Encoder-Decoder的FCNs架构

本文目的:
通过将语义分割视为一个sequence-to-sequence的预测任务,提供一个可供选择的替代品。
具体地,使用了一个纯粹的transformer结构(也即:没有卷积和下采样过程)将一张图像作为一组patchs进行编码。**通过transformer中每一层所建模的全局上下文,Encoder即可接上一个简单的decoder,从而组合为一个强大的语义分割模型,**该模型称为SETR。

2. 引言

2.1 原来的模型:FCN

一个标准的FCN语义分割模型是有着Encoder-Decoder结构的:
encoder,由大量的卷积层堆叠而成。作用是提取更丰富的语义特征,一般会不断地降低特征图的空间分辨率(大小)来实现更大的感受野
解码器则用于将编码器所提取到的高级特征上采样到原始输入分辨率以进行像素级的分类。

	1.感受野的大小决定了特征是否能足够捕获更大范围的周边信息甚至是全局信息,但对于语义分割,损失分辨率意味着空间损失大,分割效果可能会变差
	2.上下文(context)信息是提升语义分割性能最关键的因素,而感受野(respect-field)则大致决定了网络能够利用到多少的信息。
由于网络中的有效感受野是有限的,这将会严重制约模型的表示能力。

优点:平移等变性使得网络具有一定的泛化能力,而局部性通过参数共享降低了模型复杂度。
缺点:CNNs 难以学习长距离依赖关系

解决:

  • 直接修改卷积操作:大卷积核、空洞卷积、图像/特征金字塔等;
  • 引入注意力模块,对feature map中各个像素建模全局上下文信息。
    上述两种方式的结构仍然属于Encoder-Decoder的FCN。

Transformer 的一个特性便是能够保持输入和输出的空间分辨率不变,同时还能够有效的捕获全局的上下文信息。因此,作者这里便采用了类似ViT的结构来进行特征提取同时结合Decoder来恢复分辨率。

2.2 使用transformers

使用仅包含transformers的Encoder,替代原来的堆叠卷积进行特征提取的方式,这种方式称之为 SEgmentation TRansformer (SETR)。
SETR的Encoder通过学习patch embedding将一副图片视为一个包含了一组image patches的序列,并利用全局自注意力对这个序列进行学习。具体来说:
首先,将
图像分解
成一个由固定大小的小块组成的网格,形成一系列的patches;
然后,对每个patch拉直后使用一个线性embedding层进行学习,即可获得一个特征嵌入向量的序列,并将该序列作为transformers的输入;
接着,经过transformers Encoder之后,得到学习后的高度抽象feature maps
最后,使用一个简单的decoder获得原始分辨率大小的分割map
SETR的整个过程中,很关键的一点就是没有下采样过程,这和传统基于卷积的backbone进行特征提取的方式是不同的。

2.3 主要贡献

(1)对语义分割任务重新进行了定义,将其视为sequence-to-sequence的问题,这是除了基于Encoder-decoder结构的FCN模型的另一个选择;
(2)使用纯transformers作为Encoder,对序列化的图片进行特征表示;
(3)设计了三种decoder,来对自注意力进行深入研究;

3. 相关工作-语义分割模型发展

3.1 以前基于FCN的改进

FCN移除分类模型的全连接层,并添加了decoder,开启了深度学习的语义分割时代。

而FCN的预测结果比较粗糙,因此又发展出了CRF/MRF的后处理方式来对结果进行精细化调整。

为了弥补语义和空间之间的固有矛盾,又在Encoder和Decoder中对深层、浅层进行了融合,这也导致产生了大量具有不同融合方式的变种。

近期研究:都集中在解决有限感受野和上下文信息建模的问题上。

为了增大感受野:
DeepLab和Dilation引入了空洞卷积;而PSPNet和DeepLabv2则是为了进行更好的上下文建模。PSPNet提出了PPM模块来获取不同区域的上下文信息,DeepLabv2则提出了带有不同膨胀率的金字塔空洞卷积模块——ASPP。

此外,GCN则通过分解大卷积核来获取大的感受野;PSANet开发了逐点的空间注意力模块来动态捕获长距离上下文;DANet则同时嵌入了空间注意力和通道注意力;CCNet则侧重于在引入全局注意力的同时降低计算量;DGMN构建了一个动态的图消息传递网络用于场景建模,大大降低了计算复杂度。

需要注意的是,这些方法都是基于FCN进行的改进:特征提取部分(也即Encoder)都是基于分类模型,如VGG、ResNet等卷积网络,去掉全连接后得到的部分

本文所提出的SETR只这些方法则完全不同,给出了一种新的解决思路。

3.2 基于transformer的改进

transformer和自注意模型已经彻底改变了机器翻译和自然语言处理。近年来,对transformer结构在图像识别中的应用也进行了一些探索。
Non-local network将transformer的attention附加到卷积主干上。
AANet混合了卷积和self-ateention用于主干的训练。
LRNet和stand- alone networks探索局部自注意,以避免全局自注意带来的繁重计算。
SAN探索了两种self-attention模块。Axial-Attention 将全局空间注意分解为两个单独的axial attentions ,从而大大减少了计算量。
cnn -transformer混合模型。
DETR和以下变形版本利用transformer进行目标检测,transformer被附加在检测头内。
STTR和LSTR分别采用transformer进行视差估计和车道形状预测。
ViT是第一个证明纯transformer图像分类模型可以达到最先进水平的工作。它为在语义分割模型中开发基于纯transformer的编码器设计提供了直接的启发。

Axial-Attention也利用注意力进行图像分割。但是他们的模型仍然遵循传统的FCN设计,即采用特征图的空间分辨率逐渐降低的编码方式。而SETR始终保持相同的空间分辨率。

4. 方法

4.1 基于FCN的语义分割

FCNs语义分割的Encoder由一系列卷积层堆叠而成,
第一层接受尺寸为HW3的输入图像,
随后若干卷积层的输入尺寸为hwd,其中,h和w是feature maps的高和宽,d为其通道数。

在深层中每个张量的位置,是由其前面所有浅层一层层计算得来的,也即:感受野。
由于卷积运算的局部性,感受野是随着层的叠加而线性增加的,增加的快慢取决于卷积核的大小。
最终**,在FCN架构中,只有深层才能够具有大感受野,才能建模长距离依赖关系。**
但是,也有研究表明,随着层次的加深,其带来的感受野增加等收益也在逐渐降低。
因此,对于普通的FCN架构来说,在上下文建模方面,其有限的感受野成为其固有的限制。

近期,一些SOTA方法也表明了,将FCNs与注意力机制相结合是一种更为有效的提取长距离上下文信息的策略
但是,由于注意力机制的次幂复杂度,feature maps的分辨率越高所需的计算量就越大,因此这些方法都是将注意力机制放在分辨率较小的深层后面,以利用其小尺寸的输入来降低计算复杂度
这也就意味着,缺失了浅层中注意力依赖关系的学习。SETR的提取也就是为了解决这个问题。

4.2 SETR

整个的SETR结构:输入→转换→输出
图1 Schematic illustration of the proposed SEgmentation TRansformer (SETR) 。(a) 输入预处理及特征提取;(b)渐进式上采样;(c)多层级特征聚合。
1 .Image to sequence 图像序列化方法
首先,需要将原始的输入图片处理成Transformer能够支持的格式,这里作者参考了ViT的做法,即对输入图像进行切片处理,将每一个2D的图像切片(patch)视为一个“1D”的序列作为整体输入到网络当中。通常来说,Transformer接收的输入是一个1维的特征嵌入序列Z∈R (L×C),其中 ,L为序列的长度,C为隐藏层的通道尺寸。因此,对于图像序列而言,我们也需要将输入x∈R H×W×3转换为Z。
文章采用切片的方式,每个切片大小为16X16,那么对于一张256X256大小的图片来说就可以切成256块。为了对每个切片的空间信息进行编码,可以为每个局部位置都学习一个特定的嵌入,并将其添加到一个线性的投影函数中来形成最终的输入序列 。如此一来,尽管Transofomer是无序的,也仍然可以保留相对应的空间位置信息,因为对原始的位置信息进行了关联。

2 Transformer
通过将序列输入到Transformer架构可进行特征的提取,其主要包含两个部分Multi-head Self-Attention (MSA) and Multilayer Perceptron (MLP) blocks。

3.Decoder
关于解码器,文章给出了三种结构。经过TF所提取出的特征其输入和输出的维度是一致的,为了进行最终的像素级分割,需要将其reshape成原始的空间分辨率

  • Naive upsampling (Naive)
    将Transformer输出的特征维度降到分类类别数后经过双线性上采样恢复原分辨率, 也就是2-layer: 1 × 1 conv + sync batch norm (w/ ReLU) + 1 × 1 conv

  • Progressive UPsampling (PUP)
    为了从H/16 × W/16 × 1024 恢复到H × W × 19(19是cityscape的类别数) 需要4次操作, 交替使用卷积层和两倍上采样操作来恢复到原分辨率。

  • Multi-Level feature Aggregation (MLA)
    首先将Transformer的输出{Z1,Z2,Z3…ZLe}均匀分成M等份,每份取一个特征向量。如下图, 24个transformer的输出均分成4份,每份取最后一个,即{Z6,Z12,Z18,Z24},后面的Decoder只处理这些取出的向量。
    具体是先将ZL 从2D (H × W)/256 × C恢复到3D H/16 × W/16 × C,然后经过3-layer的卷积1 × 1, 3 × 3, and 3 × 3后再经过双线性上采样4×自上而下的融合。以增强Zl 之间的相互联系,如下图最后一个Zl理论上拥有全部上面三个feature的信息,融合,再经过3 × 3卷积后通过双线性插值4× 恢复至原分辨率。

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

4.3 解码器设计

在这里插入图片描述

5 总结

总体而言,SETR的几个重要贡献如下:

  • 主要是将分割任务作为序列-序列的预测任务,从而提出了一种新的语义分割的模型设计角度。
    与现有基于FCN的模型利用空洞卷积和注意力模块来增大感受野的方式不同,SETR使用transformer作为encoder,在encoder的每层中都进行全局上下文建模,完美去掉了对FCN中卷积的依赖。

  • 结合所设计的三种不同复杂度的decoder,形成了强大的分割模型,且没有最近一些模型中的花哨的操作。

  • 大量实验也表明,SETR达到了新的SOTA:ADE20K (50.28% mIoU)、 Pascal Context(55.83% mIoU) 、Cityscapes中有竞争力的结果,并在ADE20K测试服务器排行榜位列第一。

但SETR也有诸多不足。跟ViT一样,SETR要取得好的结果,对预训练和数据集大小都有较大的依赖性。

6.实验-复现

论文的实验

官方的Segmentation Transformer源码是基于MMSegmentation框架的,不便于阅读和学习,想使用官方版本的就不用参考此博客了。
1笔记:采用Segmentation Transformer(SETR)(Pytorch版本)训练CityScapes数据集步骤
代码:大佬复现-非mm-不完整

2.简洁-大佬复现-非mm
笔记:
大佬复现原笔记
模型魔改—基于SETR模型的边缘检测

给出的代码能很好的实现输入与输出图像尺寸的不变,**相当于整个SETR的块代码都写好了,只需要设置相应的参数即可直接使用。**将Dense Extreme Inception Network中的模型部分整个替换掉,换成上面的SETR模型。其他的参数可以保持不变,依然是Dense Extreme Inception Network的训练设置。

from SETR.transformer_seg import SETRModel
import torch 

if __name__ == "__main__":
    net = SETRModel(patch_size=(32, 32), 
                    in_channels=3, 
                    out_channels=1, 
                    hidden_size=1024, 
                    num_hidden_layers=8, 
                    num_attention_heads=16, 
                    decode_features=[512, 256, 128, 64])
    t1 = torch.rand(1, 3, 256, 256)
    print("input: " + str(t1.shape))
    
    # print(net)
    print("output: " + str(net(t1).shape))

接着是模型的部分,只需要将原始的模型替换成SETR的模型,其他的都不需要修改。由于没有预训练的参数,所以不需要导入参数,从头开始训练。

原始的代码
# Instantiate model and move it to the computing device
model = DexiNedVit().to(device)

修改之后的
model = SETRModel(patch_size=(32, 32),
                 in_channels=3,
                 out_channels=1,
                 hidden_size=1024,
                 sample_rate=5,
                 num_hidden_layers=1,
                 num_attention_heads=16,
                 decode_features=[512, 256, 128, 64, 32]).to(device)

猜你喜欢

转载自blog.csdn.net/zhe470719/article/details/124301829