ViP解读:视觉MLP结构新作
最近的一篇新的視覺(jué)MLP方面的工作,天津大學(xué)程明明組參與其中,通過(guò)充分利用2D特征圖的位置信息設(shè)計(jì)的一個(gè)MLP結(jié)構(gòu)ViP(Vision Permutator),獲得了相當(dāng)不錯(cuò)的性能。
簡(jiǎn)介
論文提出一種簡(jiǎn)單高效的類(lèi)MLP結(jié)構(gòu),Vision Permutator,用于視覺(jué)識(shí)別任務(wù)。通過(guò)意識(shí)到2D特征圖所攜帶的位置信息的重要性,因此,不同于之前的MLP模型總是沿著展平的空間維度編碼空間信息,ViP通過(guò)線性投影的方式沿著高和寬兩個(gè)維度編碼特征表達(dá)。這使得ViP可以沿著某個(gè)空間方向捕獲長(zhǎng)程依賴并且同時(shí)在另一個(gè)方向保留精確的位置信息。通過(guò)這種方式獲得的位置感知的輸出特征以一個(gè)互相補(bǔ)充的方式聚合以形成感興趣目標(biāo)的有效表示。實(shí)驗(yàn)表明,ViP具有比肩CNN和視覺(jué)Transformer的能力。不需要2D卷積也不需要注意力機(jī)制,不使用額外的大尺度數(shù)據(jù)集,ViP僅僅通過(guò)25M的參數(shù)就取得了ImageNet上81.5的top-1精度,同等模型大小的約束下,這已經(jīng)超越了大多數(shù)CNN和Transformer,更大版本的ViP精度更高,達(dá)到SOTA水準(zhǔn)。
-
論文標(biāo)題
Vision Permutator: A Permutable MLP-Like Architecture for Visual Recognition
-
論文地址
http://arxiv.org/abs/2106.12368
-
論文源碼
https://github.com/Andrew-Qibin/VisionPermutator
介紹
最近的MLP-Mixer和ResMLP證明了純MLP結(jié)構(gòu)也可以在圖像分類(lèi)等任務(wù)上表現(xiàn)得非常好。相比于卷積神經(jīng)網(wǎng)絡(luò)和視覺(jué)Transformer分別使用空域卷積和自注意力層來(lái)編碼空間信息,類(lèi)MLP網(wǎng)絡(luò)只使用全連接層(或者1x1卷積),因此無(wú)論是訓(xùn)練還是測(cè)試都更加高效。但是,MLPs在圖像分類(lèi)上的優(yōu)異表現(xiàn)往往得益于大尺度數(shù)據(jù)集的訓(xùn)練(如ImageNet-22K和JFT-300M),沒(méi)有這些數(shù)據(jù)的支撐,其性能距離CNNs和Vision Transformers還有不小的差距。
這篇論文中,作者希望探索一個(gè)MLP結(jié)構(gòu)僅僅使用ImageNet-1k數(shù)據(jù)集訓(xùn)練即可達(dá)到不錯(cuò)的效果,因此,提出了Vision Permutator結(jié)構(gòu)(ViP)。具體而言是,Vision Permutator 通過(guò)提出一種新的層來(lái)創(chuàng)新現(xiàn)有的 MLP 架構(gòu),該結(jié)構(gòu)可以基于基本矩陣乘法更有效地編碼空間信息。 不同于現(xiàn)有的MLP模型,如MLP-Mixer和ResMLP,他們通過(guò)展平空間維度然后再線性投影來(lái)編碼空間信息的,也就是說(shuō)作用于尺寸為tokens x channels的張量上,這導(dǎo)致了2D特征圖的位置信息丟失,ViP則保持了原始輸入token的空間維度并沿著寬和高兩個(gè)維度編碼空間信息,這樣可以保留充分的位置信息。
具體而言,和很多視覺(jué)Transformer結(jié)構(gòu)類(lèi)似,ViP首先通過(guò)對(duì)圖像切塊進(jìn)行token化,將切得得小patch通過(guò)線性投影映射為token embedding,如上圖所示。此時(shí)獲得的token embedding的維度是height x width x channels,它們被送入一系列的Permutator block中,這個(gè)Permutator block包含一個(gè)用來(lái)編碼空間信息的Permute-MLP和一個(gè)用來(lái)混合通道信息的Channel-MLP,這兩個(gè)結(jié)構(gòu)下文會(huì)詳細(xì)介紹。隨后經(jīng)過(guò)這些block獲得的特征會(huì)送入GAP和Linear層中用于圖像分類(lèi)任務(wù)。和現(xiàn)有的很多MLP結(jié)構(gòu)混合兩個(gè)空間方向信息的方式相比,ViP沿著不同的方向獨(dú)立處理輸入特征,保證token具有特定方向的信息,這已經(jīng)被視覺(jué)中的很多方法證明是很重要的(如CoordAttention)。
ViP
ViP的整體結(jié)構(gòu)如下圖所示,該網(wǎng)絡(luò)以224x224的圖像作為輸入并且將其均分為多個(gè)圖像塊(image patches),如14x14或7x7,這些圖像塊隨后被映射為linear embedding(也叫token),這個(gè)映射通過(guò)一個(gè)共享的線性層完成,這和MLP-Mixer是一致的。
接著,這些token送入一序列的Permutator來(lái)編碼空間和通道信息,產(chǎn)生的新token沿著空間維度做平均再用全連接層做分類(lèi)。下文將詳細(xì)描述核心的Permutator block以及網(wǎng)絡(luò)的一些設(shè)置。
Permutator
Permutator的結(jié)構(gòu)如下圖所示,如果不考慮用于標(biāo)準(zhǔn)化的LN和跳躍鏈接,這個(gè)結(jié)構(gòu)的核心其實(shí)是兩個(gè)組件:Permute-MLP和Channel-MLP,從名字上也知道,它們分別負(fù)責(zé)編碼空間信息和通道信息。Channel-MLP和Transformer原論文中的前饋層結(jié)構(gòu)類(lèi)似,由兩個(gè)全連接層中間夾著一個(gè)GELU激活函數(shù)。不過(guò),關(guān)于空間信息的編碼,最近的MLP-Mixer采用對(duì)輸入token沿著空間維度進(jìn)行線性投影的方式來(lái)處理,但是ViP則選擇沿著高和寬兩個(gè)方向分別處理。 數(shù)學(xué)上,對(duì)一個(gè)CCC維的輸入tokens X∈RH×W×C\mathbf{X} \in \mathbb{R}^{H \times W \times C}X∈RH×W×C,Permutator的運(yùn)算過(guò)程可以總結(jié)如下式,其中LNLNLN表示LayerNorm,輸出的Z\mathbf{Z}Z則用于下一層block的輸入。
Y=Permute-MLP?(LN(X))+XZ=Channel-MLP?(LN?(Y))+Y\begin{aligned} &\mathbf{Y}=\text { Permute-MLP }(\mathrm{LN}(\mathbf{X}))+\mathbf{X} \\ &\mathbf{Z}=\text { Channel-MLP }(\operatorname{LN}(\mathbf{Y}))+\mathbf{Y} \end{aligned} ?Y=?Permute-MLP?(LN(X))+XZ=?Channel-MLP?(LN(Y))+Y?
由于Channel-MLP就是原始Transformer中的FFN結(jié)構(gòu),這里就不贅述了,下面來(lái)看這篇論文最核心的Permute-MLP。它的詳細(xì)結(jié)構(gòu)如下圖所示,可以發(fā)現(xiàn)和之前視覺(jué)Transformer結(jié)構(gòu)以及MLP-Mixer這類(lèi)工作不一樣的地方,它的輸入其實(shí)不是二維的(即tokens×channels=HW×Ctokens \times channels = HW \times Ctokens×channels=HW×C),而是三維的。
如上圖所示,Permute-MLP包含三個(gè)分支,每個(gè)分支負(fù)責(zé)沿高度、寬度或通道維度對(duì)信息進(jìn)行編碼。其中通道信息的編碼比較簡(jiǎn)單,只需要使用一個(gè)權(quán)重為WC∈RC×C\mathbf{W}_{C} \in \mathbb{R}^{C \times C}WC?∈RC×C的全連接層對(duì)輸入進(jìn)行X\mathbf{X}X進(jìn)行線性投影即可,得到XC\mathbf{X}_{C}XC?,這就是上圖最下面的分支。
下面介紹如何編碼空間信息,其本質(zhì)上是一個(gè)逐head的permute操作。假定隱層維度為384,輸入圖像為224x224的分辨率,為了沿著高度這個(gè)維度編碼空間信息,首先需要對(duì)height和channel這兩個(gè)維度進(jìn)行調(diào)換(PyTorch中即為Permute操作)。那么具體如何做呢?對(duì)輸入X∈RH×W×C\mathbf{X} \in \mathbb{R}^{H \times W \times C}X∈RH×W×C,首先沿著通道對(duì)其分成S組(每組為一個(gè)segment),即分為[XH1,XH2,?,XHS]\left[\mathbf{X}_{H_{1}}, \mathbf{X}_{H_{2}}, \cdots, \mathbf{X}_{H_{S}}\right][XH1??,XH2??,?,XHS??],每組包含NNN個(gè)通道,故有C=N?SC=N * SC=N?S。若patch size為14×1414 \times 1414×14,NNN為16,則XHi∈RH×W×N,(i∈{1,?,S})\mathbf{X}_{H_{i}} \in \mathbb{R}^{H \times W \times N},(i \in\{1, \cdots, S\})XHi??∈RH×W×N,(i∈{1,?,S})。接著,對(duì)每個(gè)segment XHi\mathbf{X}_{H_{i}}XHi??進(jìn)行height和channel的permute操作,產(chǎn)生的結(jié)果記為[XH1?,XH2?,?,XHS?]\left[\mathbf{X}_{H_{1}}^{\top}, \mathbf{X}_{H_{2}}^{\top}, \cdots, \mathbf{X}_{H_{S}}^{\top}\right][XH1???,XH2???,?,XHS???],它們最終沿著通道維度concat到一起作為輸出,接著這個(gè)輸出送入一個(gè)參數(shù)為WH∈RC×C\mathbf{W}_{H} \in \mathbb{R}^{C \times C}WH?∈RC×C的全連接層中進(jìn)行height信息的混合,然后再進(jìn)行一次permute即可恢復(fù)維度,記這個(gè)輸出為XH\mathbf{X}_{H}XH?,這就是上圖的第一個(gè)分支。第二個(gè)分支是和第一個(gè)分支一樣的操作不過(guò)針對(duì)于width這個(gè)維度,其輸出為XW\mathbf{X}_{W}XW?。最后,這三個(gè)分支的輸出加到一起然后通過(guò)一個(gè)全連接層得到最終的Permute-MLP的輸出,可以用下式表示,其中FC(?)FC(\cdot)FC(?)表示一個(gè)參數(shù)為WP∈RC×C\mathbf{W}_{P} \in \mathbb{R}^{C \times C}WP?∈RC×C的全連接層。
X^=FC(XH+XW+XC)\hat{\mathbf{X}}=\mathrm{FC}\left(\mathbf{X}_{H}+\mathbf{X}_{W}+\mathbf{X}_{C}\right) X^=FC(XH?+XW?+XC?)
作者也在論文中給出了Permute-MLP的PyTorch風(fēng)格的偽代碼,如下所示。
接著,作者發(fā)現(xiàn)上面這種相加融合三個(gè)分支的信息的方式采用的這種逐元素相加的操作效果不是很好,因此進(jìn)一步提出了重校準(zhǔn)不同分支重要性的加權(quán)融合方式,并順勢(shì)提出了Weighted Permute-MLP,和split attention操作類(lèi)似,只不過(guò)split attention是對(duì)組卷積的一組tensor進(jìn)行,這里是對(duì)XH,XW\mathbf{X}_{H}, \mathbf{X}_{W}XH?,XW?和XC\mathbf{X}_{C}XC?進(jìn)行的。這個(gè)過(guò)程并不復(fù)雜,我這里直接貼上作者的源碼了,需要注意的是,下文所說(shuō)的ViP默認(rèn)均采用這種Weight Permute-MLP。
class WeightedPermuteMLP(nn.Module):def __init__(self, dim, segment_dim=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):super().__init__()self.segment_dim = segment_dimself.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.reweight = 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.shapeS = C // self.segment_dimh = x.reshape(B, H, W, self.segment_dim, S).permute(0, 3, 2, 1, 4).reshape(B, self.segment_dim, W, H*S)h = self.mlp_h(h).reshape(B, self.segment_dim, W, H, S).permute(0, 3, 2, 1, 4).reshape(B, H, W, C)w = x.reshape(B, H, W, self.segment_dim, S).permute(0, 1, 3, 2, 4).reshape(B, H, self.segment_dim, W*S)w = self.mlp_w(w).reshape(B, H, self.segment_dim, W, S).permute(0, 1, 3, 2, 4).reshape(B, H, W, C)c = self.mlp_c(x)a = (h + w + c).permute(0, 3, 1, 2).flatten(2).mean(2)a = self.reweight(a).reshape(B, C, 3).permute(2, 0, 1).softmax(dim=0).unsqueeze(2).unsqueeze(2)x = h * a[0] + w * a[1] + c * a[2]x = self.proj(x)x = self.proj_drop(x)return xViPs
下圖是ViP的各種變種形式,采用不同的配置。patch size越大模型越小,ViP-Small/14與ViP-Small/16僅有一個(gè)塊嵌入模塊后接16個(gè)Permutators,而ViP-Small/7、ViP-Medium/7以及ViP-Large/7則具有兩個(gè)階段,每個(gè)階段有一個(gè)塊嵌入模塊,對(duì)于這些模型,作者添加了一些 Permutator,用于編碼細(xì)粒度表示,作者發(fā)現(xiàn)這對(duì)模型性能有益。
實(shí)驗(yàn)
下表是和近期MLP結(jié)構(gòu)的對(duì)比,不難看到,ViP-Small/7憑借25M參數(shù)取得了81.5%的top1精度,這優(yōu)于大部分MLP結(jié)構(gòu),ViP-Medium/7則憑借55M參數(shù)取得了82.7%top1精度,超越其他所有MLP結(jié)構(gòu),ViP-Large/7則憑借88M參數(shù)將精度進(jìn)一步提升到了83.2%,為當(dāng)前MLP結(jié)構(gòu)中最高精度。
下表則是ViP和SOTA的CNN和ViT的對(duì)比結(jié)果,雖然比有的方法效果好,但是距離SOTA的CNN和視覺(jué)Transformer還有不小距離,也就是說(shuō),視覺(jué)MLP模型和視覺(jué)Transformer結(jié)構(gòu)一樣還有很大的改進(jìn)空間。
消融實(shí)驗(yàn)部分感興趣的可以查看原論文,這里不多贅述了。
總結(jié)
位置信息的利用是這篇文章的核心工作,從這點(diǎn)出發(fā)設(shè)計(jì)了ViP結(jié)構(gòu),該結(jié)構(gòu)通過(guò)不同方向編碼空間信息達(dá)到了充分利用二維視覺(jué)特征的目的,大大改進(jìn)了目前MLP模型的性能,為視覺(jué)MLP模型的發(fā)展提供了一個(gè)思路。本文也只是我本人從自身出發(fā)對(duì)這篇文章進(jìn)行的解讀,想要更詳細(xì)理解的強(qiáng)烈推薦閱讀原論文。最后,如果讀到了這里并且我的文章對(duì)你有所幫助,歡迎一鍵三連,你的支持是我不懈創(chuàng)作的動(dòng)力。
總結(jié)
以上是生活随笔為你收集整理的ViP解读:视觉MLP结构新作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: GCT解读
- 下一篇: 0179-Largest Number(