用 Excel 來闡釋什麼是多層卷積

AIBigbull2050發表於2019-08-22


用 Excel 來闡釋什麼是多層卷積

原來 Excel 也有這種妙用?!

原標題 | Multi-Channel Convolutions explained with… MS Excel!

作者 | Thom Lane

翻譯 | 廖穎、希貝兒•蘭姆、Diyz、micah壹路向北、通夜

編輯 | Pita

在之前的系列裡,我們討論了 1D 卷積, 2D 卷積 ,3D 卷積,今天的我們將會討論 4D 卷積,5D 卷積, 6D卷積…

開玩笑的,我們將會討論一些更有用的,更容易用Excel 視覺化的東西, 首先我們看一下多輸入通道中的卷積, 之後會討論多輸出通道的卷積,在MXNET Gluon 中很簡單。

多輸入通道

目前 在卷積系列中我們已經應用了:

  • 1D 卷積應用 一維資料(時間)

  • 2D 卷積應用 二維資料 (高,寬)

  • 3D 卷積 應用 三維資料 (長 寬 高)

這裡 你會看到明顯的應用模式,但是在這些簡單的通訊之間隱藏了一個重要的細節。我們輸入的資料通常在每一個位置都定義了多個變數 (通過時間,空間),不僅僅只是一個數值。我們稱其為通道。

Conv1D 和多輸入通道

來看一個有趣的例子,讓我們用冰激凌銷售額的預測作為案例。在我們的時間維度上,輸入以天為間隔,正態化我們的產品價格,營銷話費, 室外溫度,是否為週末等資料。總計4個輸入通道

用 Excel 來闡釋什麼是多層卷積

圖1:一個4通道的輸入陣列,覆蓋了6個時間間隔

儘管輸入資料看起來像二維,但只有一個維度是空間的。我們期待從本地相鄰閾值中找到模型,而不是跨越本地相鄰值的通道變數。從一個隨機序列的4個變數開始(A,B,C,D),我們不期待在A&B ,B&C,C&D 之間找到相似的空間關係(如果我們在這個維度上將將核層設為2)。

由於這個原因,在處理多通道時間資料的時候,最好使用1D 卷積, 儘管資料看上去像是二維的。

應用了 1D 卷積之後 (卷積核的大小是3) 我們的卷積核看起來不同於上一篇文章的應用了單個通道的例子。這次我們有4個輸入通道,我們的卷積核也會用4個通道初始化。所以儘管我們使用了1D 卷積 但是我們有一個2D 卷積核!一個1D 卷積只代表我們在一個維度上滑動卷積核,但是並沒有定義卷積核的形狀,因為這也取決於輸入通道的形狀。

用 Excel 來闡釋什麼是多層卷積

圖2:一個 卷積核大小為3 的1D 卷積, 應用於 一個4*6 的輸入矩陣,輸出一個1*4 的矩陣

用 Excel 來闡釋什麼是多層卷積 圖3:單元格Q4使用的Excel公式

進階:在這種情況下, 一個卷積核形狀為(3,4)的2D卷積,達到的效果是相等的,但是對於一個1D 卷積你不用詳細列出通道的維度。我們通常依賴於卷積核形狀來推斷 (例如,在傳入第一批資料之後),但是我們通常可以指出輸入通道的個數 通過 in_channels。在對公式增加內邊距,寬度和擴張的時候, 2D 卷積核和1D 卷積可能是不一樣的。


# define input_data and kernel as above

# input_data.shape is (4, 6)

# kernel.shape is (4, 3)

conv = mx.gluon.nn.Conv1D(channels=1, kernel_size=3)
# see appendix for definition of `apply_conv` output_data = apply_conv(input_data, kernel, conv) print(output_data)
# [[[24. 25. 22. 15.]]] # <NDArray 1x1x4 @cpu(0)>

我們的程式碼相比單一輸入通道的情況是沒有改變的

在我們用1D 卷積包裝之前, 有一個非常值得一提的常見用例。在自然語言處理的模型中第一個階段通常需要將有序的原始文字轉化成有序的向量,要麼是字元,單詞或者語句向量。在每一個時間跨度, 我們有一個有特定數值的向量(比如 128), 每一個值代表了字元,單詞或者語句的不同屬性。我們應當認為他們是時間序列的例子,將他們當做通道。由於我們隨著時間的推移得到時間通道,1D 卷積對於本地時間模型的選擇非常有效。

Conv2D 多通道輸入

彩色影像也是多通道空間資料的一個非常好的例子。在每一個位置,我們通常有3個通道來代表顏色:對於紅,綠,藍不同的顏色強度。但我們這次有一些不一樣的方法,我們將使用2個空間維度:高,寬。

用 Excel 來闡釋什麼是多層卷積

圖4:彩色影像通常用3個通道代表 (來源:https:// www.howtogeek .com/howto/42393/rgb-cmyk-alpha-what-are-image-channels-and-what-do-they-mean/)

我們的核心將相應地調整通道,即使我們定義了一個3x3核心,初始化時核心的真實尺寸將是3x3x3,因為我們有3個輸入通道。既然我們又回到了三維,在使用MS Excel之前,讓我們先看一下three.js圖。

用 Excel 來闡釋什麼是多層卷積

圖5:與3x3核心的2D卷積應用於大小為5x5的3通道RGB輸入,得到3x3的輸出。(源地址:https://thomelane.github.io/convolutions/2DConvRGB.html)

有了上面的圖表,如果你想看實際的影像,你應該考慮看上面的圖,但是我們感興趣的是看到通道,因此我們從滑動的角度看。檢視此連結以獲得上面圖表的互動式版本:https://thomelane.github.io/convolutions/2DConvRGB.html。觀察到一個有趣的現象是,核心的每個“層”都與輸入的相應通道互動。

我們可以在MS Excel中更詳細地看到這一點。

用 Excel 來闡釋什麼是多層卷積

圖6:與3x3核心的2D卷積應用於大小為5x5的3通道RGB輸入,得到3x3的輸出。

從這個角度來看,我們認為每個通道都有自己的3x3核心。我們將核心的每個“層”應用於相應的輸入通道,並獲得中間值,即每個通道的單個值。最後一步是對這些值求和,以獲得輸出的最終結果。忽略0得到:

紅色輸出= (3*2) +(1*1) = 7

綠色輸出 = (1*2) +(1*3) = 5

藍色輸出 = (2*1) +(3*1) +(1*2) = 7

輸出 = 紅色輸出 + 綠色輸出 + 藍色輸出 = 7 +5+ 7 = 19

在實際應用中我們並不會真的去計算那些中間值,但是這樣理解很好地詮釋了不同輸入通道之間的分離。由於我們在最終要得到所有通道值的求和,每個核心實際上是在觀察跨越所有通道的模式。

進階:在上述情況下,該多輸入卷積核其實等價於一個形狀為(3,3,3)的三維卷積核,但是在用二維卷積的時候你不用指明有幾個輸入通道。事實上,我們一般會利用對於資料的形狀的獲取(比如在輸入第一批資料之後), 但是我們依然可以利用 in_channels 這個屬性去指定輸入通道的數量。當加入 填充,步長和空洞時,三維和二維卷積之間的等價關係或許會被破壞。


# define input_data and kernel as above

# input_data.shape is (3, 5, 5)

# kernel.shape is (3, 3, 3)

conv = mx.gluon.nn.Conv2D(channels=1, kernel_size=(3,3))
output_data = apply_conv(input_data, kernel, conv) print(output_data)
# [[[[19. 13. 15.] # [28. 16. 20.] # [23. 18. 25.]]]] # <NDArray 1x1x3x3 @cpu(0)>

在MXNet Gloun中的程式碼看起來跟單輸入通道一樣,但是請注意卷積核的形狀黑(3,3,3), 因為我們將每個卷積核都用在三個通道上,並且在每個通道中的視野域的長和寬均為3。因此,我們卷積核的佈局為(in_channels,hieght,width).

多輸出通道的卷積

用 Excel 來闡釋什麼是多層卷積

圖7:ImageNet中,能夠最大化卷積層中某些卷積核的影像區塊(連結:https://ar xiv.org/pdf/ 1311.2901.pdf)。

在我們本系列第一個部落格(https://medium .com/apache-mxnet/convolutions-explained-with-ms-excel-465d6 649831c)中,我們介紹了,卷積就像一個特徵探測器,卷積核定義了我們想要探測的特徵。目前為止,在我們所有給出的例子中,我們在每層卷積上均只使用了一個卷積核,也就是說我們只是在尋找一個特徵。顯然,在圖片分類,目標檢測和分割等複雜的任務中,我們在每一層卷積網路中需要探測多個特徵。

用 Excel 來闡釋什麼是多層卷積

圖8:ImageNet中,能夠最大化卷積層中某4個卷積核的影像區塊(連結:https://ar xiv.org/pdf/ 1311.2901.pdf)。

第一層卷積層,在探測不同角度和不同顏色襯度(就像在多輸入通道中我們所看到的哪樣)的邊或許會很有用。然後在接下來的卷積層中,我們或許就能探測到螺旋,甚至狗臉。

在計算上,加入多個輸出通道很簡單。我們需要幾個輸出通道,就只需要將前面的過程重複多少次,當然每次的卷積核是不同且獨立的,之後我們將這幾次的輸出疊在一起,搞定!

用 Excel 來闡釋什麼是多層卷積

圖9: 一個1維的卷積層,擁有4個大小為3的卷積核,應用在形狀 1x6 的矩陣上,給出了形狀 4x4 的輸出。

將這張圖與上一個部落格(https://medium .com/p/5f88c0f35941)中的圖2進行比較。這裡的第一個卷積核和那個例子中的一模一樣,並且我們也得到了一樣的(形狀為 1x4)輸出,但是在這裡我們又加上了3個卷積核,最後的輸出形狀為 4x4。

通常,這很容易新增到 MXNet Gluon的卷積中。我們需要做的,就是改變引數 channels ,把它設為4而不是1。

用 Excel 來闡釋什麼是多層卷積

進階:我們之前提到一個跟這個引數看上去很像的一個引數 in_channels。注意二者的區別至關重要。in_channels 用於指定輸入資料期望的通道數,而不是用卷積核形狀來推斷(通過傳入的第一批資料)。channels 被用來指定需要的輸出通道數,比如卷積核/濾波器的數量。

用 Excel 來闡釋什麼是多層卷積

之前,在上一篇文章裡提到,一維數卷積的卷積核也是一維的。當有多個輸入通道時,我們必須增加額外的維度來解決多通道問題。現在,我們就在 關注多個輸出通道的問題,我們已經看到另一個問題!也就是對一維卷積實現三維輸出。其實這些維度一直到在(很抱歉又向你們隱瞞),但是忽略它們會使問題更簡單,因為它們都是單位長度,而且只需要使用 apply_conv 就可以新增這些維度了。

從上面的例子可以看出,卷積的大小為(4, 1, 3)。我們有4個卷積核,每個核都被用在相同的一維(單通道)輸入上,在時間維度上,它們的寬度為3。因此,卷積核的形式就為(channels, in_channels, widths)。下表列出了更完整的預設維度形式以便檢視。

用 Excel 來闡釋什麼是多層卷積

表1:MXNet Gluon 預設維度

進階:深度可分離卷積

常見卷積神經網路結構中大部分卷積都被用於多輸入多輸出問題。計算量與輸出通道的數量成線性關係,但當引數 in_channels 和 channels 設定很大時,計算量也相當龐大。一種更有效的解決方法,就是使用深度可分離卷積。我們看一下多輸入通道(參見圖5),圖中在對輸入通道求和之前有一箇中間步驟。使用深度可分離卷積,可以用1*1卷積代替求和操作。我們基本上把卷積分為兩個階段:第一個階段 關注每個輸入通道各自的空間模式,第二個階段 關注各個通道(不是空間上的)。

用 Excel 來闡釋什麼是多層卷積

圖10:常見卷積和深度可分離卷積

MXNet Gluon 中,可以使用卷積引數 groups 來指定如何對操作進行分割槽。可以看看 用 MXNet Gluon 實現 MobileNet 這個使用例項。groups 用來設定輸入通道的數量,從而給出深度可分離卷積。

進行實驗

本文中展示的所有示例都可以在這些用於 Conv1D 和 Conv2D 的MS Excel電子表格中找到(或分別在此處和此處的谷歌表格中)。單擊輸出單元格檢查公式,並嘗試使用不同的核心值更改輸出。在MXnet Gluon中複製您的結果後,我認為您可以在LinkedIn配置檔案中正式新增“卷積大師”作為標題!

接下來

但在我們理解反摺積之前,這個系列是不會完結的!在這個系列的最後一篇博文中,我們將看到兩種不同的思維模式來思考轉置卷積,並看到一些實際的例子。

附錄:

def apply_conv(data, kernel, conv):  """ Args: data (NDArray): input data. kernel (NDArray): convolution's kernel parameters. conv (Block): convolutional layer. Returns: NDArray: output data (after applying convolution). """ # add dimensions for batch and channels if necessary while data.ndim < len(conv.weight.shape): data = data.expand_dims(0) # add dimensions for channels and in_channels if necessary while kernel.ndim < len(conv.weight.shape): kernel = kernel.expand_dims(0) # check if transpose convolution if type(conv).__name__.endswith("Transpose"): in_channel_idx = 0 else: in_channel_idx = 1 # initialize and set weight conv._in_channels = kernel.shape[in_channel_idx] conv.initialize conv.weight.set_data(kernel) return conv(data)

感謝 Simon Corston-Oliver.

via https://medium .com/apache-mxnet/multi-channel-convolutions-explained-with-ms-excel-9bbf8eb77108



https://www.toutiao.com/i6726481186366947852/

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946223/viewspace-2654532/,如需轉載,請註明出處,否則將追究法律責任。

相關文章