天天看點

【深度學習】 - MobileNet使用的可分離卷積

任何看過MobileNet架構的人都會遇到可分離卷積(separable convolutions)這個概念。但什麼是“可分離卷積”,它與标準的卷積又有什麼差別?可分離卷積主要有兩種類型:

空間可分離卷積(spatial separable convolutions)深度可分離卷積(depthwise separable convolutions)空間可分離卷積

從概念上講,這是兩者中較容易的一個,并說明了将一個卷積分成兩部分(兩個卷積核)的想法,是以我将從這開始。 不幸的是,空間可分離卷積具有一些顯着的局限性,這意味着它在深度學習中沒有被大量使用。

空間可分卷積之是以如此命名,是因為它主要處理圖像和卷積核(kernel)的空間次元:寬度和高度。 (另一個次元,“深度”次元,是每個圖像的通道數)。

空間可分離卷積簡單地将卷積核劃分為兩個較小的卷積核。 最常見的情況是将3x3的卷積核劃分為3x1和1x3的卷積 核,如下所示:

【深度學習】 - MobileNet使用的可分離卷積

圖1:在空間上分離3x3核心

現在,我們不是用9次乘法進行一次卷積,而是進行兩次卷積,每次3次乘法(總共6次),以達到相同的效果。 乘法較少,計算複雜性下降,網絡運作速度更快。

【深度學習】 - MobileNet使用的可分離卷積

圖2:簡單且空間可分離的卷積

最著名的可在空間上分離的卷積是用于邊緣檢測的sobel卷積核:

【深度學習】 - MobileNet使用的可分離卷積

圖3:分離的Sobel卷積核

空間可分卷積的主要問題是并非所有卷積核都可以“分離”成兩個較小的卷積核。 這在訓練期間變得特别麻煩,因為網絡可能采用所有可能的卷積核,它最終隻能使用可以分成兩個較小卷積核的一小部分。

深度可分離卷積

與空間可分離卷積不同,深度可分離卷積與卷積核無法“分解”成兩個較小的核心。 是以,它更常用。 這是在keras.layers.SeparableConv2D或tf.layers.separable_conv2d中看到的可分離卷積的類型。

深度可分離卷積之是以如此命名,是因為它不僅涉及空間次元,還涉及深度次元(信道數量)。 輸入圖像可以具有3個信道:R、G、B。 在幾次卷積之後,圖像可以具有多個信道。 你可以将每個信道想象成對該圖像特定的解釋說明(interpret); 例如,“紅色”信道解釋每個像素的“紅色”,“藍色”信道解釋每個像素的“藍色”,“綠色”信道解釋每個像素的“綠色”。 具有64個通道的圖像具有對該圖像的64種不同解釋。

類似于空間可分離卷積,深度可分離卷積将卷積核分成兩個單獨的卷積核,這兩個卷積核進行兩個卷積:深度卷積和逐點卷積。 但首先,讓我們看看正常的卷積是如何工作的。

标準的卷積:

如果你不知道卷積如何在一個二維的角度下進行工作,請閱讀本文或檢視此站點。

然而,典型的圖像并不是2D的; 它在具有寬度和高度的同時還具有深度。 讓我們假設我們有一個12x12x3像素的輸入圖像,即一個大小為12x12的RGB圖像。

讓我們對圖像進行5x5卷積,沒有填充(padding)且步長為1.如果我們隻考慮圖像的寬度和高度,卷積過程就像這樣:12x12 - (5x5) - > 8x8。 5x5卷積核每25個像素進行标量乘法,每次輸出1個數。 我們最終得到一個8x8像素的圖像,因為沒有填充(12-5 + 1 = 8)。

然而,由于圖像有3個通道,我們的卷積核也需要有3個通道。 這就意味着,每次卷積核移動時,我們實際上執行5x5x3 = 75次乘法,而不是進行5x5 = 25次乘法。

和二維中的情況一樣,我們每25個像素進行一次标量矩陣乘法,輸出1個數字。經過5x5x3的卷積核後,12x12x3的圖像将成為8x8x1的圖像。

【深度學習】 - MobileNet使用的可分離卷積

圖4:具有8x8x1輸出的标準卷積

如果我們想增加輸出圖像中的信道數量呢?如果我們想要8x8x256的輸出呢?

好吧,我們可以建立256個卷積核來建立256個8x8x1圖像,然後将它們堆疊在一起便可建立8x8x256的圖像輸出。

【深度學習】 - MobileNet使用的可分離卷積

圖5:擁有8x8x256輸出的标準卷積

這就是标準卷積的工作原理。我喜歡把它想象成一個函數:12x12x3-(5x5x3x256)->12x12x256(其中5x5x3x256表示核心的高度、寬度、輸入信道數和輸出信道數)。并不是說這不是矩陣乘法;我們不是将整個圖像乘以卷積核,而是将卷積核移動到圖像的每個部分,并分别乘以圖像的一小部分。

深度可分離卷積的過程可以分為兩部分:深度卷積(depthwise convolution)和逐點卷積(pointwise convolution)。

第1部分-深度卷積:

在第一部分,深度卷積中,我們在不改變深度的情況下對輸入圖像進行卷積。我們使用3個形狀為5x5x1的核心。

視訊1:通過一個3通道的圖像疊代3個核心:

​​https://www.youtube.com/watch?v=D_VJoaSew7Q​​

【深度學習】 - MobileNet使用的可分離卷積

圖6:深度卷積,使用3個核心将12x12x3圖像轉換為8x8x3圖像

每個5x5x1核心疊代圖像的一個通道(注意:一個通道,不是所有通道),得到每25個像素組的标量積,得到一個8x8x1圖像。将這些圖像疊加在一起可以建立一個8x8x3的圖像。

第2部分-逐點卷積:

記住,原始卷積将12x12x3圖像轉換為8x8x256圖像。目前,深度卷積已經将12x12x3圖像轉換為8x8x3圖像。現在,我們需要增加每個圖像的通道數。

逐點卷積之是以如此命名是因為它使用了一個1x1核函數,或者說是一個周遊每個點的核函數。該核心的深度為輸入圖像有多少通道;在我們的例子中,是3。是以,我們通過8x8x3圖像疊代1x1x3核心,得到8x8x1圖像。

【深度學習】 - MobileNet使用的可分離卷積

圖7:逐點卷積,将一個3通道的圖像轉換為一個1通道的圖像

【深度學習】 - MobileNet使用的可分離卷積

我們可以建立256個1x1x3核心,每個核心輸出一個8x8x1圖像,以得到形狀為8x8x256的最終圖像。

圖8:256個核的逐點卷積,輸出256個通道的圖像

就是這樣!我們把卷積分解成兩部分:深度卷積和逐點卷積。更抽象地說,如果原始卷積函數是12x12x3 - (5x5x3x256)→12x12x256,我們可以将這個新的卷積表示為12x12x3 - (5x5x1x1) - > (1x1x3x256) - >12x12x256。

好的,但是建立一個深度可分離卷積有什麼意義呢?

我們來計算一下計算機在原始卷積中要做的乘法的個數。有256個5x5x3核心可以移動8x8次。這是256 x3x5x5x8x8 = 1228800乘法。

可分離卷積呢?在深度卷積中,我們有3個5x5x1的核它們移動了8x8次。也就是3x5x5x8x8 = 4800乘以。在點态卷積中,我們有256個1x1x3的核它們移動了8x8次。這是256 x1x1x3x8x8 = 49152乘法。把它們加起來,就是53952次乘法。

52,952比1,228,800小很多。計算量越少,網絡就能在更短的時間内處理更多的資料。

然而,這是如何實作的呢?我第一次遇到這種解釋時,我的直覺并沒有真正了解它。這兩個卷積不是做同樣的事情嗎?在這兩種情況下,我們都通過一個5x5核心傳遞圖像,将其縮小到一個通道,然後将其擴充到256個通道。為什麼一個的速度是另一個的兩倍多?

經過一段時間的思考,我意識到主要的差別是:在普通卷積中,我們對圖像進行了256次變換。每個變換都要用到5x5x3x8x8=4800次乘法。在可分離卷積中,我們隻對圖像做一次變換——在深度卷積中。然後,我們将轉換後的圖像簡單地延長到256通道。不需要一遍又一遍地變換圖像,我們可以節省計算能力。

值得注意的是,在Keras和Tensorflow中,都有一個稱為“深度乘法器”的參數。預設設定為1。通過改變這個參數,我們可以改變深度卷積中輸出通道的數量。例如,如果我們将深度乘法器設定為2,每個5x5x1核心将輸出8x8x2的圖像,使深度卷積的總輸出(堆疊)為8x8x6,而不是8x8x3。有些人可能會選擇手動設定深度乘法器來增加神經網絡中的參數數量,以便更好地學習更多的特征。

深度可分離卷積的缺點是什麼?當然!因為它減少了卷積中參數的數量,如果你的網絡已經很小,你可能會得到太少的參數,你的網絡可能無法在訓練中正确學習。然而,如果使用得當,它可以在不顯著降低效率的情況下提高效率,這使得它成為一個非常受歡迎的選擇。

1x1核心:

最後,由于逐點卷積使用了這個概念,我想讨論一下1x1核心的用法。

一個1x1核心——或者更确切地說,n個1x1xm核心,其中n是輸出通道的數量,m是輸入通道的數量——可以在可分離卷積之外使用。1x1核心的一個明顯目的是增加或減少圖像的深度。如果你發現卷積有太多或太少的通道,1x1核可以幫助平衡它。

繼續閱讀