卷積神經網路(CNN)
1. 卷積神經網路結構介紹
如果用全連線神經網路處理大尺寸影象具有三個明顯的缺點:
(1)首先將影象展開為向量會丟失空間資訊;
(2)其次引數過多效率低下,訓練困難;
(3)同時大量的引數也很快會導致網路過擬合。
而使用卷積神經網路可以很好地解決上面的三個問題。
與常規神經網路不同,卷積神經網路的各層中的神經元是3維排列的:寬度、高度和深度。其中的寬度和高度是很好理解的,因為本身卷積就是一個二維模板,但是在卷積神經網路中的深度指的是啟用資料體的第三個維度,而不是整個網路的深度,整個網路的深度指的是網路的層數。舉個例子來理解什麼是寬度,高度和深度,假如使用CIFAR-10中的影象是作為卷積神經網路的輸入,該輸入資料體
圖 1. 全連線神經網路與卷積神經網路的對比
圖1中左側是一個3層的神經網路;右側是一個卷積神經網路,將它的神經元在成3個維度(寬、高和深度)進行排列。卷積神經網路的每一層都將3D的輸入資料變化為神經元3D的啟用資料並輸出。在圖1的右側,紅色的輸入層代表輸入影象,所以它的寬度和高度就是影象的寬度和高度,它的深度是3(代表了紅、綠、藍3種顏色通道),與紅色相鄰的藍色部分是經過卷積和池化之後的啟用值(也可以看做是神經元) ,後面是接著的卷積池化層。
2. 構建卷積神經網路的各種層
卷積神經網路主要由這幾類層構成:輸入層、卷積層,ReLU層、池化(Pooling)層和全連線層(全連線層和常規神經網路中的一樣)。通過將這些層疊加起來,就可以構建一個完整的卷積神經網路。在實際應用中往往將卷積層與ReLU層共同稱之為卷積層,所以卷積層經過卷積操作也是要經過啟用函式的。具體說來,卷積層和全連線層(CONV/FC)對輸入執行變換操作的時候,不僅會用到啟用函式,還會用到很多引數,即神經元的權值w和偏差b;而ReLU層和池化層則是進行一個固定不變的函式操作。卷積層和全連線層中的引數會隨著梯度下降被訓練,這樣卷積神經網路計算出的分類評分就能和訓練集中的每個影象的標籤吻合了。
2.1 卷積層
卷積層是構建卷積神經網路的核心層,它產生了網路中大部分的計算量。注意是計算量而不是引數量。
2.1.1 卷積層作用
1.濾波器的作用或者說是卷積的作用。卷積層的引數是有一些可學習的濾波器集合構成的。每個濾波器在空間上(寬度和高度)都比較小,但是深度和輸入資料一致(這一點很重要,後面會具體介紹)。直觀地來說,網路會讓濾波器學習到當它看到某些型別的視覺特徵時就啟用,具體的視覺特徵可能是某些方位上的邊界,或者在第一層上某些顏色的斑點,甚至可以是網路更高層上的蜂巢狀或者車輪狀圖案。
2.可以被看做是神經元的一個輸出。神經元只觀察輸入資料中的一小部分,並且和空間上左右兩邊的所有神經元共享引數(因為這些數字都是使用同一個濾波器得到的結果)。
3.降低引數的數量。這個由於卷積具有“權值共享”這樣的特性,可以降低引數數量,達到降低計算開銷,防止由於引數過多而造成過擬合。
2.1.2 感受野(重點理解)
在處理影象這樣的高維度輸入時,讓每個神經元都與前一層中的所有神經元進行全連線是不現實的。相反,我們讓每個神經元只與輸入資料的一個區域性區域連線。該連線的空間大小叫做神經元的感受野(receptive field),它的尺寸是一個超引數(其實就是濾波器的空間尺寸)。在深度方向上,這個連線的大小總是和輸入量的深度相等。需要再次強調的是,我們對待空間維度(寬和高)與深度維度是不同的:連線在空間(寬高)上是區域性的,但是在深度上總是和輸入資料的深度一致,這一點會在下面舉例具體說明。
圖 2. 舉例說明感受野的連線及尺寸說明
在圖 2 中展現的卷積神經網路的一部分,其中的紅色為輸入資料,假設輸入資料體尺寸為[32x32x3](比如CIFAR-10的RGB影象),如果感受野(或濾波器尺寸)是5x5,那麼卷積層中的每個神經元會有輸入資料體中[5x5x3]區域的權重,共5x5x3=75個權重(還要加一個偏差引數)。注意這個連線在深度維度上的大小必須為3,和輸入資料體的深度一致。其中還有一點需要注意,對應一個感受野有75個權重,這75個權重是通過學習進行更新的,所以很大程度上這些權值之間是不相等(也就對於同一個卷積核,它對於與它連線的輸入的每一層的權重都是獨特的,不是同樣的權重重複輸入層層數那麼多次就可以的)。在這裡相當於前面的每一個層對應一個傳統意義上的卷積模板,每一層與自己卷積模板做完卷積之後,再將各個層的結果加起來,再加上偏置,注意是一個偏置,無論輸入輸入資料是多少層,一個卷積核就對應一個偏置。
2.1.3 神經元的空間排列
感受野講解了卷積層中每個神經元與輸入資料體之間的連線方式,但是尚未討論輸出資料體中神經元的數量,以及它們的排列方式。3個超引數控制著輸出資料體的尺寸:深度(depth),步長(stride)和零填充(zero-padding)。
(1) 輸出資料體的深度:它是一個超引數,和使用的濾波器的數量一致,而每個濾波器在輸入資料中尋找一些不同的東西,即影象的某些特徵。如圖2 所示,將沿著深度方向排列、感受野相同的神經元集合稱為深度列(depth column),也有人使用纖維(fibre)來稱呼它們。
(2) 在滑動濾波器的時候,必須指定步長。當步長為1,濾波器每次移動1個畫素;當步長為2,濾波器滑動時每次移動2個畫素,當然步長也可以是不常用的3,或者更大的數字,但這些在實際中很少使用)。這個操作會讓輸出資料體在空間上變小。
(3) 有時候將輸入資料體用0在邊緣處進行填充是很方便的。這個零填充(zero-padding)的尺寸是一個超引數。零填充有一個良好性質,即可以控制輸出資料體的空間尺寸(最常用的是用來保持輸入資料體在空間上的尺寸,使得輸入和輸出的寬高都相等)。
輸出資料體在空間上的尺寸可以通過輸入資料體尺寸,卷積層中神經元的感受野尺寸(F),步長(S),濾波器數量(K)和零填充的數量(P)計算輸出出來。
一般說來,當步長S=1時,零填充的值是P=(F-1)/2,這樣就能保證輸入和輸出資料體有相同的空間尺寸。
步長的限制:注意這些空間排列的超引數之間是相互限制的。舉例說來,當輸入尺寸W=10,不使用零填充 P=0,濾波器尺寸 F=3,此時步長 S=2 是行不通,因為 (W-F+2P)/S+1=(10-3+0)/2+1=4.5,結果不是整數,這就是說神經元不能整齊對稱地滑過輸入資料體。因此,這些超引數的設定就被認為是無效的,一個卷積神經網路庫可能會報出一個錯誤,通過修改零填充值、修改輸入資料體尺寸,或者其他什麼措施來讓設定合理。在後面的卷積神經網路結構小節中,讀者可以看到合理地設定網路的尺寸讓所有的維度都能正常工作,是相當讓人頭痛的事;而使用零填充和遵守其他一些設計策略將會有效解決這個問題。
2.1.4 權值共享
在卷積層中權值共享是用來控制引數的數量。假如在一個卷積核中,每一個感受野採用的都是不同的權重值(卷積核的值不同),那麼這樣的網路中引數數量將是十分巨大的。
權值共享是基於這樣的一個合理的假設:如果一個特徵在計算某個空間位置 (x1,y1)(x1,y1) 的時候有用,那麼它在計算另一個不同位置 (x2,y2)(x2,y2) 的時候也有用。基於這個假設,可以顯著地減少引數數量。換言之,就是將深度維度上一個單獨的2維切片看做深度切片(depth slice),比如一個數據體尺寸為[55x55x96]的就有96個深度切片,每個尺寸為[55x55],其中在每個深度切片上的結果都使用同樣的權重和偏差獲得的。在這樣的引數共享下,假如一個例子中的第一個卷積層有96個卷積核,那麼就有96個不同的權重集了,一個權重集對應一個深度切片,如果卷積核的大小是 11x11的,影象是RGB 3 通道的,那麼就共有96x11x11x3=34,848個不同的權重,總共有34,944個引數(因為要+96個偏差),並且在每個深度切片中的55x55 的結果使用的都是同樣的引數。
在反向傳播的時候,都要計算每個神經元對它的權重的梯度,但是需要把同一個深度切片上的所有神經元對權重的梯度累加,這樣就得到了對共享權重的梯度。這樣,每個切片只更新一個權重集。這樣做的原因可以通過下面這張圖進行解釋
圖 3. 將卷積層用全連線層的形式表示
如上圖所示,左側的神經元是將每一個感受野展開為一列之後串聯起來(就是展開排成一列,同一層神經元之間不連線)。右側的 Deep1i 是深度為1的神經元的第 i 個, Deep2i 是深度為2的神經元的第 i 個,同一個深度的神經元的權值都是相同的,黃色的都是相同的(上面4個與下面4個的引數相同),藍色都是相同的。所以現在回過頭來看上面說的卷積神經網路的反向傳播公式對梯度進行累加求和也是基於這點考慮(同一深度的不同神經元共用一組引數,所以累加);而每個切片只更新一個權重集的原因也是這樣的,因為從圖3 中可以看到,不同深度的神經元不會公用相同的權重,所以只能更新一個權重集。
注意,如果在一個深度切片中的所有權重都使用同一個權重向量,那麼卷積層的前向傳播在每個深度切片中可以看做是在計算神經元權重和輸入資料體的卷積(這就是“卷積層”名字由來)。這也是為什麼總是將這些權重集合稱為濾波器(filter)(或卷積核(kernel)),因為它們和輸入進行了卷積。
注意,有時候引數共享假設可能沒有意義,特別是當卷積神經網路的輸入影象是一些明確的中心結構時候。這時候我們就應該期望在圖片的不同位置學習到完全不同的特徵(而一個卷積核滑動地與影象做卷積都是在學習相同的特徵)。一個具體的例子就是輸入影象是人臉,人臉一般都處於圖片中心,而我們期望在不同的位置學習到不同的特徵,比如眼睛特徵或者頭髮特徵可能(也應該)會在圖片的不同位置被學習。在這個例子中,通常就放鬆引數共享的限制,將層稱為區域性連線層(Locally-Connected Layer)。