即插即用Vision Permutator,涨点起飞起飞了!

文摘   2024-12-30 17:20   中国香港  

论文介绍

题目:Vision Permutator: A Permutable MLP-Like Architecture for Visual Recognition

论文地址:https://arxiv.org/pdf/2106.12368

QQ深度学习交流群:994264161

扫描下方二维码,加入深度学习论文指南星球!

加入即可获得,模块缝合、制作、写作技巧,学会“结构”创新、“创新点”创新,从三区到顶会,小论文大论文,毕业一站式服务

创新点

  • 独特的结构设计:提出了一种名为 Vision Permutator (ViP) 的新型多层感知机 (MLP) 架构,与传统的 CNN 和 Vision Transformer (ViT) 不同,该架构通过分别在高度和宽度维度上编码特征来保留位置信息。这种方法可以捕获长距离的依赖关系,同时保留精确的位置信息,从而实现更具表现力的特征表示。

  • 独立的维度处理:与其他将空间维度展平处理的 MLP 架构(如 Mixer 和 ResMLP)不同,ViP 在不丢失二维特征表示的情况下分别对高度和宽度维度进行处理。通过这种方法,ViP 能够生成对视觉识别至关重要的方向敏感输出。

  • 高效的性能表现:在无需依赖卷积或自注意力机制的情况下,ViP 在 ImageNet 数据集上达到了 81.5% 的 Top-1 准确率,仅使用 25M 参数。这一表现超过了大多数相同规模的 CNN 和 Transformer 模型。

  • 灵活的模型扩展:论文设计了三种不同规模的 ViP 模型(Small, Medium, Large),通过扩展模型的层数和隐藏维度,进一步提升性能。例如,88M 参数的 ViP-Large 模型实现了 83.2% 的 Top-1 准确率。

  • 实验证明的有效性:通过实验,论文展示了单独编码高度和宽度维度信息的优势,尤其是在精细级别的特征表示上表现突出。同时,提出的 Weighted Permute-MLP 方法也进一步提高了模型的表现。

  • 简单的数据依赖:与其他需要大规模数据集(如 ImageNet-22K)的 MLP 模型不同,ViP 在仅使用 ImageNet-1K 数据集的情况下就能实现优异的性能,这表明该架构在数据效率方面具有显著优势。

方法

整体架构

     论文提出的 Vision Permutator (ViP) 模型通过将输入图像划分为小块(patches),使用线性投影生成特征嵌入,再经过多个 Permutator 块 处理特征,每个块包含 Permute-MLPChannel-MLP,分别编码空间(高度和宽度)和通道信息,保留二维空间特性。最终通过全局平均池化和全连接层完成分类。ViP 创新地保留空间维度,捕捉位置敏感信息,在效率和性能上优于传统 MLP、CNN 和 Transformer 模型。

  • 输入图像分块

    • 输入图像首先被均匀划分为小块(patches),每个小块的尺寸如16×1616 \times 1614×1414 \times 147×77 \times 7

    • 每个小块通过线性投影映射为嵌入表示(tokens)。这样,图像被转化为形状为H×W×CH \times W \times C 的特征表示,其中HH 和WW 是图像的高度和宽度,CC是通道数。

  • Permutator 块的堆叠

    • 使用三个分支分别处理高度、宽度和通道信息。

    • 高度维度的处理通过高度-通道的维度置换(Permutation)实现;宽度维度类似。

    • 每个分支输出后通过逐元素相加(element-wise addition)融合,并通过一个全连接层完成特征融合。

    • Permute-MLP:负责分别在高度(H)和宽度(W)维度上编码空间信息,同时还处理通道(C)维度信息。


    • Channel-MLP:负责对通道信息进行混合。

    • 特征嵌入经过一系列的 Permutator 块 用于编码特征信息。

    • 每个 Permutator 块包含以下两个主要模块:

    • Permute-MLP 的处理方法:

  • 全局平均池化和分类

    • 经过 Permutator 块的特征最终通过全局平均池化 (Global Average Pooling),生成固定大小的特征向量。

    • 这一特征向量输入一个全连接层,用于进行分类任务。

  • 模型的不同配置

    • ViP-Small: 较少的参数和层数,适用于资源受限的场景。

    • ViP-Medium: 参数和层数适中。

    • ViP-Large: 参数和层数最多,性能最强。

    • 论文提出了三种不同规模的模型配置:

即插即用模块作用

VIP 作为一个即插即用模块

  • 计算资源有限但对性能有较高要求的场景

    • ViP 的架构轻量高效,不依赖卷积和自注意力机制,适合在嵌入式设备、移动设备或低功耗场景中应用,例如边缘计算设备上的图像分类任务。

  • 需要保留空间位置信息的任务

    • 图像分类:提高对不同类别图像特征的精确区分能力。

    • 目标检测:对目标在图像中的位置敏感,便于精确定位。

    • 语义分割:对像素级别的分类需要精准的空间位置信息。

    • ViP 特别适合需要处理二维空间特征并对位置信息敏感的任务,例如:

  • 需要高效特征融合的多模态任务

    • 在多模态场景(例如结合图像和文本信息的任务)中,ViP 可作为特征提取模块,帮助高效融合来自不同维度的特征信息。

  • 大模型精简和高效推理场景

  • ViP 模块可以作为大型模型的替代组件,用于降低模型的参数量和计算复杂度,同时保持良好的性能,例如在 Transformer 模型中的部分替代应用。

消融实验结果

  • 说明了数据增强方法对模型性能的影响。

  • 实验对比了未使用数据增强和使用四种常见数据增强方法(Random Augmentation、CutOut、MixUp 和 CutMix)的表现。结果表明,数据增强显著提升了模型性能,其中 MixUp 和 CutMix 的效果尤为明显,将 Top-1 准确率从 75.3% 提升至 80.6%。


  • 说明了模型规模(层数、隐藏维度)对性能的影响。

  • 随着模型规模的增加(从 ViP-Small 到 ViP-Medium 再到 ViP-Large),Top-1 准确率分别提升到 81.5%、82.7% 和 83.2%,验证了扩大模型规模在性能提升上的有效性。


  • 说明了对更精细级别的 token 表示进行编码的重要性。

  • 比较不同初始 patch 大小(如16×1616 \times 1614×1414 \times 147×77 \times 7)的表现,发现较小的 patch 尺寸(如7×77 \times 7)能够捕获更细粒度的特征,显著提升性能(Top-1 准确率从 79.8% 提升至 81.5%)。


  • 说明了在 Permutator 模块中分别编码高度和宽度信息的重要性。

  • 实验表明,若仅移除高度或宽度信息的编码,Top-1 准确率分别下降至 72.8% 和 72.7%,表明单独编码空间信息对性能的显著影响。此外,引入 Weighted Permute-MLP(加权的 Permute-MLP)进一步将性能提升到 80.6%,高于原始 Permute-MLP 的 80.2%。

即插即用模块

import torch
from torch import nn

# 论文地址:https://arxiv.org/pdf/2106.12368
# 论文:Vision Permutator: A Permutable MLP-Like Architecture for Visual Recognition


class MLP(nn.Module):
    def __init__(self,in_features,hidden_features,out_features,act_layer=nn.GELU,drop=0.1):
        super().__init__()
        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) :
        return self.drop(self.fc2(self.drop(self.act(self.fc1(x)))))

class WeightedPermuteMLP(nn.Module):
    def __init__(self,dim,seg_dim=8, qkv_bias=False, proj_drop=0.):
        super().__init__()
        self.seg_dim=seg_dim

        self.mlp_c=nn.Linear(dim,dim,bias=qkv_bias)
        self.mlp_h=nn.Linear(dim,dim,bias=qkv_bias)
        self.mlp_w=nn.Linear(dim,dim,bias=qkv_bias)

        self.reweighting=MLP(dim,dim//4,dim*3)

        self.proj=nn.Linear(dim,dim)
        self.proj_drop=nn.Dropout(proj_drop)
    
    def forward(self,x) :
        B,H,W,C=x.shape

        c_embed=self.mlp_c(x)

        S=C//self.seg_dim
        h_embed=x.reshape(B,H,W,self.seg_dim,S).permute(0,3,2,1,4).reshape(B,self.seg_dim,W,H*S)
        h_embed=self.mlp_h(h_embed).reshape(B,self.seg_dim,W,H,S).permute(0,3,2,1,4).reshape(B,H,W,C)

        w_embed=x.reshape(B,H,W,self.seg_dim,S).permute(0,3,1,2,4).reshape(B,self.seg_dim,H,W*S)
        w_embed=self.mlp_w(w_embed).reshape(B,self.seg_dim,H,W,S).permute(0,2,3,1,4).reshape(B,H,W,C)

        weight=(c_embed+h_embed+w_embed).permute(0,3,1,2).flatten(2).mean(2)
        weight=self.reweighting(weight).reshape(B,C,3).permute(2,0,1).softmax(0).unsqueeze(2).unsqueeze(2)

        x=c_embed*weight[0]+w_embed*weight[1]+h_embed*weight[2]

        x=self.proj_drop(self.proj(x))

        return x



if __name__ == '__main__':
    input=torch.randn(64,8,8,512)
    seg_dim=8
    block=WeightedPermuteMLP(512,seg_dim)
    out=block(input)    print(out.shape)

便捷下载方式

浏览打开网址:https://github.com/ai-dawang/PlugNPlay-Modules

更多分析可见原文


ai缝合大王
聚焦AI前沿,分享相关技术、论文,研究生自救指南
 最新文章