SegFormer网络结构的学习和重构

因为太多的博客并没有深入理解,本文是自己学习后加入自己深入理解的总结记录,方便自己以后查看。

segformer中encoder、decoder的详解。


学习前言

一起来学习Segformer的原理,如果有用的话,请记得点赞+关注哦。


一、Segformer的网络结构图

网络结构:主要由Transformer的编码器和轻量级的多层感知机(MLP)的解码器组成

网络特点:
1、结合了Transformers与轻量级的多层感知机(MLP)解码器。
2、包含一个新颖的分层结构的Transformer编码器,该编码器输出多尺度特征。它不需要位置编码, 因此避免了位置编码的插值,这在测试分辨率与训练时不同的情况下可能会导致性能下降。
3、避免使用复杂的解码器。提议的MLP解码器从不同的层中聚合信息,从而同时结合了局部注意力和全局注意力来呈现强大的表示。
4、设计非常简单和轻量级,这是在Transformers上实现高效分割的关键。
5、SegFormer系列模型从SegFormer-B0到SegFormer-B5有多个版本,与之前的模型相比,它们的性能和效率都有显著的提高。

二、理解各模块的网络结构

encoder:作者设计了一系列的 Mix Transformer encoders (MiT),MiT-B0 到 MiT-B5,结构相同,大小不同,MiT-B0 是最轻量级的,可以用来快速推理,MiT-B5 是最重量级的,可以取得最好的效果。

encoder——OverlapPatchEmbed:通过2D卷积操作将图像分块(4分块)并将其嵌入到指定的维度的模块,通过Hierarchical Feature Representation这种方式,编码器可以同时提供高分辨率的粗糙特征和低分辨率的精细特征,从而更好地捕捉不同尺度的上下文信息。

#block1 对输入图像进行分区,并下采样512, 512, 3 => 128, 128, 32 => 16384, 32
        self.patch_embed1 = OverlapPatchEmbed(patch_size=7, stride=4, in_chans=in_chans, embed_dim=embed_dims[0])
       
#block2对输入图像进行分区,并下采样,128, 128, 32 => 64, 64, 64 => 4096, 64
        self.patch_embed2 = OverlapPatchEmbed(patch_size=3, stride=2, in_chans=embed_dims[0], embed_dim=embed_dims[1])

#block3对输入图像进行分区,并下采样  64, 64, 64 => 32, 32, 160 => 1024, 160
        self.patch_embed3 = OverlapPatchEmbed(patch_size=3, stride=2, in_chans=embed_dims[1], embed_dim=embed_dims[2])

#block4对输入图像进行分区,并下采样32, 32, 160 => 16, 16, 256 => 256, 256
        self.patch_embed4 = OverlapPatchEmbed(patch_size=3, stride=2, in_chans=embed_dims[2], embed_dim=embed_dims[3])

encoder——Efficient self-attention:Attention机制(注意力机制),encoder 中计算量最大的就是 self-attention 层模块进行特征特区

        self.attn = Attention(
            dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale,
            attn_drop=attn_drop, proj_drop=drop, sr_ratio=sr_ratio
        )

encoder——Mix FNN:在 FNN (前馈神经网络)中使用了 3x3 的卷积和 MLP,作者认为 position encoding(PE) 来引入局部位置信息在语义分割中是不需要的,所以引入了一个 Mix-FFN,考虑了零填充对位置泄露的影响,直接在 FFN 中使用 3x3 的卷积

    self.mlp = Mlp(in_features=dim, hidden_features=int(dim * mlp_ratio), act_layer=act_layer, drop=drop)

encoder——Overlapped Patch Merging:为了在保持局部连续性的同时获得分层特征图,SegFormer采用了重叠patch merging技术。这种方法通过重叠的patch来合并特征,与不重叠的patch merging相比,可以生成相同大小的特征图,同时更好地保留局部信息。

decoder:本文提出了一个轻量化的全由MLP组成的解码器,之所以可以使用如此简单轻量的decoder是因为本文的分层Transformer编码器比传统的卷积编码器具有更大的有效感受野。

Decoder 的过程:

step 1:将多层级特征输入 MLP 层,来规范通道维度
step 2:将特征图上采样为原图大小的 1/4 大小,concat 起来
step 3:使用一层 MLP 对特征通道聚合
step 4:输出预测 segmentation mask H 4 × W 4 × N 

SegFormer是一个基于Transformer的图像分割模型,其主要特点是采用了类似于ViT中的patch embedding策略来处理图像信息,并且使用了Transformer Encoder来提取特征。相较于传统的卷积神经网络,SegFormer具有更好的可解释性灵活性。下面是SegFormer的代码详解。 首先,SegFormer的代码结构如下: ``` SegFormer/ ├── config/ │ ├── base.py │ ├── segformer.py │ └── ... ├── dataset/ │ ├── base_dataset.py │ ├── cityscapes.py │ └── ... ├── models/ │ ├── base_model.py │ ├── segformer.py │ └── ... ├── utils/ │ ├── helpers.py │ ├── losses.py │ └── ... ├── train.py └── eval.py ``` 其中,config文件夹包含了SegFormer的配置文件,dataset文件夹包含了数据集的处理代码,models文件夹包含了SegFormer模型的实现代码,utils文件夹包含了一些辅助函数,train.pyeval.py分别是训练测试的入口文件。 接下来,我们来详细介绍SegFormer的代码实现。 1. 数据集处理 SegFormer支持多种不同的数据集,例如Cityscapes、PASCAL VOC等。在dataset文件夹中,每个数据集都有一个对应的.py文件,该文件包含了数据集的处理逻辑。 以Cityscapes数据集为例,其数据集处理代码如下: ```python class Cityscapes(BaseDataset): def __init__(self, root, list_path, num_samples=None, num_classes=19, multi_scale=True, flip=True, ignore_label=-1, base_size=2048, crop_size=(512, 1024), downsample_rate=1): super(Cityscapes, self).__init__(root, list_path, num_samples=num_samples, num_classes=num_classes, multi_scale=multi_scale, flip=flip, ignore_label=ignore_label, base_size=base_size, crop_size=crop_size, downsample_rate=downsample_rate) self.mean = np.array([0.485, 0.456, 0.406]) self.std = np.array([0.229, 0.224, 0.225]) self.files = self.read_files() ``` 其中,Cityscapes继承自BaseDataset,BaseDataset定义了数据集的一些基本属性方法。Cityscapes的构造函数中,root是Cityscapes数据集的根目录,list_path是数据集的列表文件路径,num_samples表示采样的样本数,num_classes表示数据集的类别数,multi_scaleflip表示是否进行多尺度翻转增强,ignore_label表示忽略的标签,base_size表示图像的基础尺寸,crop_size表示裁剪后的尺寸,downsample_rate表示下采样的比率。 在Cityscapes的构造函数中,首先调用了BaseDataset的构造函数,然后定义了数据集的均值标准差,最后调用了read_files()方法来读取数据集的文件列表。 2. 模型实现 SegFormer的模型实现在models文件夹中的segformer.py文件中。该文件包含了SegFormer的主要模块,包括Transformer Encoder、Decoder、Segmentation Head等。 下面是SegFormer的Encoder实现: ```python class EncoderLayer(nn.Module): def __init__(self, embed_dim, num_heads, mlp_ratio=4.0, qkv_bias=False, qk_scale=None, drop_rate=0.0, attn_drop_rate=0.0, drop_path_rate=0.0): super().__init__() self.norm1 = nn.LayerNorm(embed_dim) self.attn = Attention(embed_dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop_rate, proj_drop=drop_rate) self.drop_path = DropPath(drop_path_rate) if drop_path_rate > 0.0 else nn.Identity() self.norm2 = nn.LayerNorm(embed_dim) self.mlp = Mlp(in_features=embed_dim, hidden_features=int(embed_dim * mlp_ratio), act_layer=nn.GELU, drop=drop_rate) def forward(self, x): x = x + self.drop_path(self.attn(self.norm1(x))) x = x + self.drop_path(self.mlp(self.norm2(x))) return x class Encoder(nn.Module): def __init__(self, num_layers, embed_dim, num_heads, mlp_ratio=4.0, qkv_bias=False, qk_scale=None, drop_rate=0.0, attn_drop_rate=0.0, drop_path_rate=0.0): super().__init__() self.layers = nn.ModuleList() for _ in range(num_layers): self.layers.append(EncoderLayer(embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale, drop_rate=drop_rate, attn_drop_rate=attn_drop_rate, drop_path_rate=drop_path_rate)) def forward(self, x): for layer in self.layers: x = layer(x) return x ``` EncoderLayer是SegFormer的Transformer Encoder的一层,包含了Multi-Head AttentionFeed-Forward Network两个子模块。Encoder则是由多层EncoderLayer堆叠而成的。 在EncoderLayer中,首先进行了Layer Normalization,然后使用Multi-Head Attention来计算Attention,使用Dropout进行正则化,接着使用Feed-Forward Network进行特征提取,最后再次使用Dropout进行正则化。 在Encoder中,使用nn.ModuleList来存储多个EncoderLayer,然后依次调用每个EncoderLayer,得到最终的特征表示。 3. 训练测试 SegFormer的训练测试分别在train.pyeval.py文件中进行。 在train.py中,首先进行数据集的加载预处理,然后定义了SegFormer模型,接着定义了优化器损失函数,最后进行模型训练。 在eval.py中,首先进行数据集的加载预处理,然后定义了SegFormer模型,接着进行模型测试,并计算模型的性能指标,例如IoUmIoU等。 这就是SegFormer的代码详解。SegFormer是一个基于Transformer的图像分割模型,其代码实现相对于传统的卷积神经网络更加灵活可解释。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值