【Transformer】PoolFormer: MetaFormer is Actually What You Need for Vision
文章目錄
- 一、背景和動機
- 二、方法
- 2.1 MetaFormer
- 2.2 PoolFormer
- 三、效果
- 四、代碼
論文鏈接:https://arxiv.org/pdf/2111.11418.pdf
代碼鏈接:https://github.com/sail-sg/poolformer
一、背景和動機
如圖1a所示,Transformer 的 encoder 由兩個部分組成:
- attention for mixing information
- MLP & residual connections
Transformer 最近在計算機視覺任務上展示了很好的效果,大家基本上都認為這種成功來源于基于 self-attention 的結構。但又有文章證明,只使用 MLP 也能達到很好的效果,所以作者假設 Transformer 的效果來源于 transformer 的結構,而非將 token 進行融合交互的模塊。
所以,作者使用簡單的 spatial pooling 模塊替換了 attention 模塊,來實現 token 之間的信息交互,稱為 PoolFormer,也能達到很好的效果。
在 ImageNet-1K 上達到了 82.1% 的 top-1 acc。
作者使用 PoolFormer 證明了他們的猜想,并且提出了 “MetaFormer” 的概念,也就是一種從 Transformer 中抽象出來的結構,沒有特殊的 token mixer 方式。
二、方法
2.1 MetaFormer
MetaFormer 其實是 Transformer 的一個抽象,其他部分和 Transformer 保持一致,token mixer 方式是不特殊指定的。
① 首先,輸入 III 經過 embedding:
X=InputEmd(I)X=InputEmd(I)X=InputEmd(I)
② 然后,將 embedding token 輸入 MetaFormer blocks,該 block 包含兩個殘差 sub-blocks
- 第一個 sub-block:token mixer,即在 tokens 之間進行信息傳遞
Y=TokenMixer(Norm(X))+XY=TokenMixer(Norm(X))+XY=TokenMixer(Norm(X))+X
- 第二個 sub-block:兩個 MLP & 激活層
Z=σ(Norm(Y)W1)W2+YZ=\sigma(Norm(Y)W_1)W_2+YZ=σ(Norm(Y)W1?)W2?+Y
2.2 PoolFormer
作者為了證明猜想,使用了非常簡單的 pooling 算子來實現 token mixer,沒有任何可學習參數。
假設輸入形式為 T∈RC×H×WT\in R^{C\times H \times W}T∈RC×H×W,channel 維度在前,則 pooling 操作如下,kkk 為 pooling 大小:
偽代碼如下:
已知,self-attention 和 spatial MLP 的計算復雜度是 token 個數的平方,且僅僅能處理一百個左右的 token,pooling 的復雜度與序列的長度是呈線性關系的,且沒有可學習參數。
作者使用層級的方式來進行 pooling,如圖 2 所示。
PoolFormer 共 4 個 stages,tokens 的大小分別為:
- H4×W4\frac{H}{4} \times \frac{W}{4}4H?×4W?
- H8×W8\frac{H}{8} \times \frac{W}{8}8H?×8W?
- H16×W16\frac{H}{16} \times \frac{W}{16}16H?×16W?
- H32×W32\frac{H}{32} \times \frac{W}{32}32H?×32W?
不同大小的模型使用不同的編碼維度:
- 小尺度模型:4 個 stages 分別為 64,128,320,512
- 中尺度模型:4 個 stages 分別為 96,192,384,768
假設模型中共有 LLL 個 PoolFormer blocks,則 4 個 stages 中包含的 block 數量分別為:
- L/6L/6L/6
- L/6L/6L/6
- L/2L/2L/2
- L/6L/6L/6
MLP expansion ratio:4
五種不同大小的 PoolFormer 模型參數如表 1 所示:
三、效果
1、分類
使用 pooling 操作,每個 token 都能從其鄰近的 token 中平均的抽取特征,所以可以看做是最基本的 token mixing 方式,但 PoolFormer 仍然取得了很好的效果。
2、檢測
作者將 PoolFormer 作為 RetinaNet 和 Mask RCNN 的主干網絡,來證明 PoolFormer 的效果。
PoolFormer-based RetinaNet 超越了基于 ResNet 的效果,
3、語義分割
作者使用 PoolFormer 作為 Semantic FPN 的主干網絡,使用 mmsegmentation 訓練的結果如下。超越了基于 CNN 的網絡。
4、消融實驗
① 為了證明使用 pooling 的效果,作者對該操作做了消融實驗。
作者首先使用恒等映射來代替 pooling,發現仍能達到 74.3% 的top-1 acc,證明了作者認為的 Transformer 的結構的重要性。
然后對不同 pooling size 做了實驗,當使用 3,5,7 的時候,效果都差不多。使用 9 的時候,性能下降了 0.5%,所以,作者使用了 3。
② 多個 stage 的效果
關于 pooling、MLP、attention 這三種不同的 token mixer 方式。pooling 方式能夠處理更長的輸入序列,attention 和 MLP 更能捕捉全局信息,所以,這也是作者使用 pooling 在低層 stage 來解決長序列問題,在高層 stage 使用 attention 或 MLP 的原因。
為了驗證這種方法的效果,作者使用 FC 或 attention 來代替低層的 pooling,如表 6 所示,效果也不錯。但前兩層用 pooling,最后兩層用 attention 的方法達到了最好的效果。
四、代碼
pooling 模塊代碼 class Pooling(nn.Module):"""Implementation of pooling for PoolFormer--pool_size: pooling size"""def __init__(self, pool_size=3):super().__init__()self.pool = nn.AvgPool2d(pool_size, stride=1, padding=pool_size//2, count_include_pad=False)def forward(self, x):return self.pool(x) - x poolformer block class PoolFormerBlock(nn.Module):"""Implementation of one PoolFormer block.--dim: embedding dim--pool_size: pooling size--mlp_ratio: mlp expansion ratio--act_layer: activation--norm_layer: normalization--drop: dropout rate--drop path: Stochastic Depth, refer to https://arxiv.org/abs/1603.09382--use_layer_scale, --layer_scale_init_value: LayerScale, refer to https://arxiv.org/abs/2103.17239"""def __init__(self, dim, pool_size=3, mlp_ratio=4., act_layer=nn.GELU, norm_layer=GroupNorm, drop=0., drop_path=0., use_layer_scale=True, layer_scale_init_value=1e-5):super().__init__()self.norm1 = norm_layer(dim)self.token_mixer = Pooling(pool_size=pool_size)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)# The following two techniques are useful to train deep PoolFormers.self.drop_path = DropPath(drop_path) if drop_path > 0. \else nn.Identity()self.use_layer_scale = use_layer_scaleif use_layer_scale:self.layer_scale_1 = nn.Parameter(layer_scale_init_value * torch.ones((dim)), requires_grad=True)self.layer_scale_2 = nn.Parameter(layer_scale_init_value * torch.ones((dim)), requires_grad=True)def forward(self, x):if self.use_layer_scale:x = x + self.drop_path(self.layer_scale_1.unsqueeze(-1).unsqueeze(-1) * self.token_mixer(self.norm1(x)))x = x + self.drop_path(self.layer_scale_2.unsqueeze(-1).unsqueeze(-1) * self.mlp(self.norm2(x)))else:x = x + self.drop_path(self.token_mixer(self.norm1(x)))x = x + self.drop_path(self.mlp(self.norm2(x)))return x 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【Transformer】PoolFormer: MetaFormer is Actually What You Need for Vision的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Transformer】Are Tra
- 下一篇: 理想L9当街起火 燃烧之后只剩铁架