b站網(wǎng)頁入口免費不收費搜索引擎廣告推廣
一、說明
????????在這個由 4 部分組成的系列中,我們將使用 PyTorch 中的深度學(xué)習(xí)技術(shù)從頭開始逐步實現(xiàn)圖像分割。本部分將重點介紹如何實現(xiàn)基于視覺轉(zhuǎn)換器的圖像分割模型。
?
圖 1:使用視覺轉(zhuǎn)換器模型架構(gòu)運行圖像分割的結(jié)果。
????????從上到下,輸入圖像、地面實況分割掩碼和預(yù)測分割掩碼。來源:作者
二、文章大綱
????????在本文中,我們將參觀風(fēng)靡深度學(xué)習(xí)世界的變壓器架構(gòu)。變壓器是一種多模態(tài)架構(gòu),可以對語言、視覺和音頻等不同模態(tài)進行建模。
????????在本文中,我們將
- 了解變壓器架構(gòu)和所涉及的關(guān)鍵概念
- 了解視覺變壓器架構(gòu)
- 介紹從頭開始編寫的視覺轉(zhuǎn)換器模型,以便您可以欣賞所有構(gòu)建塊和移動部件
- 跟蹤輸入到該模型的輸入張量,并檢查它如何改變形狀
- 使用此模型對牛津 IIIT 寵物數(shù)據(jù)集執(zhí)行圖像分割
- 觀察此分割任務(wù)的結(jié)果
- 簡要介紹SegFormer,一種用于語義分割的最先進的視覺轉(zhuǎn)換器
????????在本文中,我們將引用此筆記本中的代碼和結(jié)果進行模型訓(xùn)練。如果要重現(xiàn)結(jié)果,則需要一個 GPU 來確保第一個筆記本在合理的時間內(nèi)完成運行。
三、本系列文章
????????本系列面向所有深度學(xué)習(xí)經(jīng)驗水平的讀者。如果您想了解深度學(xué)習(xí)和視覺AI的實踐以及一些扎實的理論和實踐經(jīng)驗,那么您來對地方了!這將是一個由 4 部分組成的系列,包含以下文章:
- 概念和想法
- 基于 CNN 的模型
- 深度可分離卷積
- 基于視覺變壓器的模型(本文)
????????讓我們從對變壓器架構(gòu)的介紹和直觀理解開始我們的視覺變壓器之旅。
四、變壓器架構(gòu)
????????我們可以將變壓器架構(gòu)視為交錯的通信和計算層的組合。圖 2 直觀地描述了這一想法。變壓器有N個處理單元(圖3中的N為2),每個單元負責(zé)處理輸入的1/N部分。為了使這些處理單元產(chǎn)生有意義的結(jié)果,每個處理單元都需要具有輸入的全局視圖。因此,系統(tǒng)將有關(guān)每個處理單元中的數(shù)據(jù)的信息重復(fù)傳達給每個其他處理單元;使用從每個處理單元到每個其他處理單元的紅色、綠色和藍色箭頭進行顯示。接下來是基于此信息進行的一些計算。在充分重復(fù)此過程后,模型能夠產(chǎn)生預(yù)期的結(jié)果。
圖 2:變壓器中的交錯通信和計算。該圖像僅顯示了 2 層通信和計算。
????????值得注意的是,大多數(shù)在線資源通常會討論變壓器的編碼器和解碼器,如題為“注意力是你所需要的”的論文中所述。但是,在本文中,我們將僅描述變壓器的編碼器部分。
????????讓我們仔細看看變壓器中的通信和計算構(gòu)成。
4.1 變壓器中的通信:注意
????????在變壓器中,通信由稱為注意力層的層實現(xiàn)。在 PyTorch 中,這被稱為?MultiHeadAttention。我們稍后會談到這個名字的原因。
????????文檔說:
“允許模型共同關(guān)注來自不同表示子空間的信息,如論文中所述:注意力就是你所需要的。
????????注意力機制使用形狀(批處理、長度、特征)的輸入張量?x,并生成形狀相似的張量?y,以便根據(jù)張量在同一實例中關(guān)注的其他輸入更新每個輸入的特征。因此,在大小為“長度”的實例中,長度為“特征”的每個張量的特征會根據(jù)其他每個張量進行更新。這就是注意力機制的二次成本的用武之地。
圖3:相對于句子中其他單詞顯示的單詞“it”的注意。我們可以看到,“它”是在同一句話中注意“動物”、“太”和“tire(d)”等詞。?
????????在視覺變壓器的上下文中,變壓器的輸入是圖像。假設(shè)這是一個 128 x 128(寬度、高度)的圖像。我們將其分成多個較小的大小塊(16 x 16)。對于 128 x 128 的圖像,我們得到 64 個補丁(長度),每行 8 個補丁和 8 行補丁。
????????這 64 個大小為 16 x 16 像素的塊中的每一個都被視為變壓器模型的單獨輸入。在不深入細節(jié)的情況下,將此過程視為由 64 個不同的處理單元驅(qū)動就足夠了,每個處理單元都在處理單個 16x16 圖像補丁。
????????在每一輪中,每個處理單元中的注意力機制負責(zé)查看它負責(zé)的圖像補丁,并查詢其余 63 個處理單元中的每一個,以詢問它們可能相關(guān)和有用的任何信息,以幫助它有效地處理自己的圖像補丁。
????????通過注意力的溝通步驟之后是計算,我們接下來將研究。
4.2 變壓器中的計算:多層感知器
????????變壓器中的計算只不過是一個多層感知器(MLP)單元。該單元由 2 個線性層組成,介于兩者之間具有 GeLU 非線性。也可以考慮使用其他非線性。該單元首先將輸入投影到大小的 4 倍,然后將其重新投影回 1 倍,這與輸入大小相同。
????????在我們將在筆記本中看到的代碼中,此類稱為多層感知器。代碼如下所示。
class MultiLayerPerceptron(nn.Sequential):def __init__(self, embed_size, dropout):super().__init__(nn.Linear(embed_size, embed_size * 4),nn.GELU(),nn.Linear(embed_size * 4, embed_size),nn.Dropout(p=dropout),)# end def
# end class
????????現(xiàn)在我們了解了變壓器架構(gòu)的高級工作原理,讓我們把注意力集中在視覺轉(zhuǎn)換器上,因為我們將執(zhí)行圖像分割。
五、視覺轉(zhuǎn)換器
????????視覺轉(zhuǎn)換器最初是由題為“圖像價值16x16字:大規(guī)模圖像識別的變壓器”的論文介紹的。本文討論了作者如何將原版變壓器架構(gòu)應(yīng)用于圖像分類問題。這是通過將圖像拆分為大小為 16x16 的補丁,并將每個補丁視為模型的輸入令牌來完成的。轉(zhuǎn)換器編碼器模型被饋送這些輸入令牌,并被要求預(yù)測輸入圖像的類。
圖 4:來源:用于大規(guī)模圖像識別的變壓器。
????????在我們的例子中,我們對圖像分割感興趣。我們可以將其視為像素級分類任務(wù),因為我們打算預(yù)測每個像素的目標(biāo)類。
????????我們對原版視覺轉(zhuǎn)換器進行了一個小但重要的更改,并更換了MLP頭,以便由MLP頭進行像素級分類。我們在輸出中有一個線性層,由每個補丁共享,其分割掩模由視覺變壓器預(yù)測。此共享線性層預(yù)測作為模型輸入發(fā)送的每個補丁的分割掩碼。
????????在視覺轉(zhuǎn)換器的情況下,大小為 16x16 的補丁被視為等效于特定時間步長的單個輸入令牌。
圖 5:用于圖像分割的視覺轉(zhuǎn)換器的端到端工作。使用此筆記本生成的圖像。
5.1 在視覺轉(zhuǎn)換器中構(gòu)建張量維度的直覺
????????當(dāng)使用深度CNN時,我們大部分使用的張量維度是(N,C H,W),其中字母代表以下內(nèi)容:
- N:批量大小
- C:通道數(shù)
- H:身高
- W:寬度
????????您可以看到這種格式面向 2D 圖像處理,因為它聞起來非常特定于圖像的特征。
????????另一方面,有了變壓器,事情變得更加通用和領(lǐng)域無關(guān)。我們將在下面看到的內(nèi)容適用于視覺、文本、NLP、音頻或其他輸入數(shù)據(jù)可以表示為序列的問題。值得注意的是,當(dāng)張量流經(jīng)我們的視覺轉(zhuǎn)換器時,在張量的表示中幾乎沒有視覺特定偏差。
????????在使用轉(zhuǎn)換器和一般情況下,我們希望張量具有以下形狀:(B,T,C),其中字母代表以下內(nèi)容:
- B:批量大小(與CNN相同)
- T:時間維度或序列長度。此維度有時也稱為 L。在視覺變壓器的情況下,每個圖像塊對應(yīng)于這個維度。如果我們有 16 個圖像補丁,那么 T 維度的值將為 16
- C:通道或嵌入大小維度。此維度有時也稱為 E。處理圖像時,大小為 3x16x16(通道、寬度、高度)的每個補丁通過補丁嵌入層映射到大小為 C 的嵌入。我們稍后會看到如何做到這一點。
????????讓我們深入了解輸入圖像張量在預(yù)測分割掩碼的過程中如何變異和處理。
5.2 視覺轉(zhuǎn)換器中張量的旅程
????????在深度CNN中,張量的旅程看起來像這樣(在UNet,SegNet或其他基于CNN的架構(gòu)中)。
????????輸入張量通常是形狀為 (1, 3, 128, 128)。該張量經(jīng)過一系列卷積和最大池化操作,其中其空間維度減小,通道維度增加,通常每個增加 2 倍。這稱為特征編碼器。在此之后,我們執(zhí)行反向操作,增加空間維度并減少通道維度。這稱為特征解碼器。在解碼過程之后,我們得到一個形狀的張量(1,64,128,128)。然后將其投影到我們希望的輸出通道 C 的數(shù)量中,使用 1x128 無偏差的逐點卷積作為 (128, C, 1, 1)。
圖 6:張量形狀通過用于圖像分割的深度 CNN 的典型進展。?
????????使用視覺變壓器時,流程要復(fù)雜得多。讓我們看一下下面的一張圖片,然后嘗試了解張量如何在每一步中轉(zhuǎn)換形狀。
圖 7:張量形狀通過用于圖像分割的視覺轉(zhuǎn)換器的典型進展。?
????????讓我們更詳細地看一下每個步驟,看看它如何更新流經(jīng)視覺轉(zhuǎn)換器的張量的形狀。為了更好地理解這一點,讓我們?yōu)閺埩烤S度取具體值。
- 批量規(guī)范化:輸入和輸出張量具有形狀 (1, 3, 128, 128)。形狀保持不變,但值歸一化為零均值和單位方差。
- 圖像到補丁:形狀 (1, 3, 128, 128) 的輸入張量被轉(zhuǎn)換為 16x16 圖像的堆疊塊。輸出張量具有形狀 (1, 64, 768)。
- 補丁嵌入:補丁嵌入層將 768 個輸入通道映射到 512 個嵌入通道(在本例中)。輸出張量的形狀為 (1, 64, 512)。補丁嵌入層基本上只是一個 nn。PyTorch 中的線性層。
- 位置嵌入:位置嵌入層沒有輸入張量,但有效地貢獻了一個可學(xué)習(xí)的參數(shù)(PyTorch 中的可訓(xùn)練張量),其形狀與補丁嵌入相同。這是形狀(1,64,512)。
- 加:貼片和位置嵌入分段地加在一起,以產(chǎn)生視覺變壓器編碼器的輸入。這個張量的形狀是(1,64,512)。您會注意到,視覺變壓器的主要主力,即編碼器基本上保持這種張量形狀不變。
- 變壓器編碼器:形狀為(1,64,512)的輸入張量流經(jīng)多個變壓器編碼器塊,每個轉(zhuǎn)換器編碼器塊具有多個注意頭(通信),后跟一個MLP層(計算)。張量形狀保持不變,如 (1, 64, 512)。
- 線性輸出投影:如果我們假設(shè)要將每個圖像分成 10 個類,那么我們需要每個大小為 16x16 的補丁有 10 個通道。該 nn.用于輸出投影的線性層現(xiàn)在會將 512 個嵌入通道轉(zhuǎn)換為 16x16x10 = 2560 個輸出通道,此張量將類似于 (1, 64, 2560)。在上圖中 C' = 10。理想情況下,這將是一個多層感知器,因為“MLP 是通用函數(shù)近似器”,但我們使用單個線性層,因為這是一項教育練習(xí)
- 補丁到映像:該層將編碼為 (64, 1, 64) 張量的 2560 個補丁轉(zhuǎn)換回看起來像分割掩碼的東西。這可以是 10 個單通道圖像,或者在本例中是單個 10 通道圖像,每個通道是 10 個類別之一的分割掩碼。輸出張量的形狀為 (1, 10, 128, 128)。
?????????就是這樣 — 我們已經(jīng)使用視覺轉(zhuǎn)換器成功分割了輸入圖像!接下來,讓我們看一個實驗以及一些結(jié)果。
5.3 視覺變壓器的實際應(yīng)用
????????此筆記本包含此部分的所有代碼。
????????就代碼和類結(jié)構(gòu)而言,它非常模仿上面的框圖。上面提到的大多數(shù)概念都與此筆記本中的類名 1:1 對應(yīng)。
????????有一些與注意力層相關(guān)的概念是我們模型的關(guān)鍵超參數(shù)。我們之前沒有提到多頭關(guān)注的細節(jié),因為我們提到它超出了本文的范圍。如果您對變壓器中的注意力機制沒有基本的了解,我們強烈建議您在繼續(xù)之前閱讀上述參考資料。
????????我們將以下模型參數(shù)用于視覺變壓器進行分割。
- 補丁嵌入層的 768 個嵌入維度
- 12 變壓器編碼器塊
- 每個變壓器編碼器塊中有 8 個注意頭
- 多頭注意力和 MLP 中 20% 的輟學(xué)率
這種配置可以在 VisionTransformerArgs Python 數(shù)據(jù)類中看到。
@dataclass
class VisionTransformerArgs:"""Arguments to the VisionTransformerForSegmentation."""image_size: int = 128patch_size: int = 16in_channels: int = 3out_channels: int = 3embed_size: int = 768num_blocks: int = 12num_heads: int = 8dropout: float = 0.2
# end class
????????在模型訓(xùn)練和驗證期間使用了與以前類似的配置。配置指定如下。
- 隨機水平翻轉(zhuǎn)和顏色抖動數(shù)據(jù)增強應(yīng)用于訓(xùn)練集以防止過度擬合
- 在非寬高比保留調(diào)整大小操作中將圖像大小調(diào)整為 128x128 像素
- 不會對圖像應(yīng)用任何輸入歸一化,而是使用批量歸一化層作為模型的第一層
- 該模型使用 LR 為 50.0 的 Adam 優(yōu)化器和每 0004 個 epoch 將學(xué)習(xí)率衰減 0.8 倍的 StepLR 調(diào)度器訓(xùn)練 12 個 epoch
- 交叉熵損失函數(shù)用于將像素分類為屬于寵物、背景或?qū)櫸镞吙?/span>
????????該模型具有 86.28M 參數(shù),經(jīng)過 85 個訓(xùn)練周期后,驗證準(zhǔn)確率為 89.50%。這低于深度 CNN 模型在 88 個訓(xùn)練周期后達到的 28.20% 的準(zhǔn)確率。這可能是由于一些需要通過實驗驗證的因素。
- 最后一個輸出投影圖層為單個 nn。線性而非多層感知器
- 16x16 色塊大小太大,無法捕獲更細粒度的細節(jié)
- 訓(xùn)練時期不足
- 沒有足夠的訓(xùn)練數(shù)據(jù) - 眾所周知,與深度CNN模型相比,轉(zhuǎn)換器模型需要更多的數(shù)據(jù)來有效訓(xùn)練
- 學(xué)習(xí)率太低
我們繪制了一個 gif,顯示了模型如何學(xué)習(xí)預(yù)測驗證集中 21 張圖像的分割掩碼。
圖 8:顯示圖像分割模型的視覺轉(zhuǎn)換器預(yù)測的分割掩碼進程的 gif。?
????????我們在早期訓(xùn)練時期注意到一些有趣的事情。預(yù)測的分割掩碼有一些奇怪的阻塞偽影。我們能想到的唯一原因是,我們將圖像分解為大小為 16x16 的補丁,經(jīng)過很少的訓(xùn)練時期,模型除了一些非常粗略的信息之外,沒有學(xué)到任何有用的東西關(guān)于這個 16x16 補丁通常被寵物或背景像素覆蓋。
圖 9:使用視覺轉(zhuǎn)換器進行圖像分割時,預(yù)測分割中看到的阻塞偽影會掩蓋。?
????????現(xiàn)在我們已經(jīng)看到了一個基本的視覺轉(zhuǎn)換器,讓我們把注意力轉(zhuǎn)向用于分割任務(wù)的最先進的視覺轉(zhuǎn)換器。
5.4 SegFormer:使用轉(zhuǎn)換器進行語義分割
????????本文于?2021 年提出了 SegFormer 架構(gòu)。我們在上面看到的轉(zhuǎn)換器是SegFormer 架構(gòu)的簡化版本。
圖 10:SegFormer 架構(gòu)。資料來源:?
????????最值得注意的是,SegFormer:
- 生成 4 組映像,其中包含大小為 4x4、8x8、16x16 和 32x32 的修補程序,而不是具有大小為 16x16 的修補程序的單個修補映像
- 使用 4 個變壓器編碼器塊,而不僅僅是 1 個。這感覺就像一個模型合奏
- 在自我注意的前階段和后期階段使用卷積
- 不使用位置嵌入
- 每個變壓器模塊以空間分辨率 H/4 x W/4、H/8 x W/8、H/16 x W/16 和 H/32、W/32 處理圖像
- 同樣,當(dāng)空間維度減小時,通道也會增加。這感覺類似于深度CNN
- 對多個空間維度的預(yù)測進行上采樣,然后在解碼器中合并在一起
- MLP 將所有這些預(yù)測結(jié)合起來,提供最終預(yù)測
- 最終的預(yù)測是在空間維度H/4,W/4,而不是在H,W。
六、結(jié)論
在本系列的第 4 部分中,我們特別介紹了變壓器架構(gòu)和視覺變壓器。我們對視覺變壓器的工作原理以及視覺變壓器的通信和計算階段所涉及的基本構(gòu)建塊有了直觀的理解。我們看到了視覺轉(zhuǎn)換器采用的基于補丁的獨特方法,用于預(yù)測分割掩模,然后將預(yù)測組合在一起。
我們回顧了一個實驗,該實驗顯示了視覺轉(zhuǎn)換器的實際作用,并能夠?qū)⒔Y(jié)果與深度CNN方法進行比較。雖然我們的視覺轉(zhuǎn)換器不是最先進的,但它能夠取得相當(dāng)不錯的結(jié)果。我們提供了對最先進的方法的一瞥,例如SegFormer。
現(xiàn)在應(yīng)該很清楚,與基于深度CNN的方法相比,變壓器具有更多的活動部件,并且更復(fù)雜。從原始FLOP的角度來看,變壓器有望提高效率。在變壓器中,唯一計算繁重的實層是nn。線性。這是在大多數(shù)架構(gòu)上使用優(yōu)化的矩陣乘法實現(xiàn)的。由于這種架構(gòu)的簡單性,與基于深度CNN的方法相比,變壓器有望更容易優(yōu)化和加速。
恭喜你走到了這一步!我們很高興您喜歡閱讀有關(guān) PyTorch 中高效圖像分割的系列文章。如果您有任何問題或意見,請隨時將其留在評論部分。
七、延伸閱讀
注意力機制的細節(jié)超出了本文的范圍。此外,您還可以參考許多高質(zhì)量的資源來詳細了解注意力機制。以下是我們強烈推薦的一些內(nèi)容。
- 圖解變壓器
- 使用 PyTorch 從頭開始 NanoGPT
我們將在下面提供文章的鏈接,這些文章提供了有關(guān)視覺轉(zhuǎn)換器的更多詳細信息。
- 在 PyTorch 中實現(xiàn)視覺轉(zhuǎn)換器?(ViT):本文詳細介紹了在 PyTorch 中實現(xiàn)用于圖像分類的視覺轉(zhuǎn)換器。值得注意的是,它們的實現(xiàn)使用 einops,我們避免這樣做,因為這是一個以教育為中心的練習(xí)(我們建議學(xué)習(xí)和使用?einops?以提高代碼可讀性)。我們改用原生 PyTorch 運算符來排列和重新排列張量維度。此外,作者在一些地方使用 Conv2d 而不是線性圖層。我們希望構(gòu)建一個完全不使用卷積層的視覺轉(zhuǎn)換器實現(xiàn)。
- 視覺轉(zhuǎn)換器:AI之夏
- 在 PyTorch 中實現(xiàn) SegFormer
德魯夫·馬塔尼
?