層、空間布局、層模式、層大小模式、AlexNet/ZFNet/VGGNet 案例研究、計算考慮
卷積神經網絡 (CNNs / ConvNets)
卷積神經網絡與前一章的神經網絡非常相似:它們是由具有可學習的權值和偏置的神經元組成的。每個神經元接收一些輸入,執行點積,跟随一個非線性計算(可選項)。整個網絡仍然表示一個可微的得分函數:從一端的原始圖像像素到另一個的分數。并且它們在最後(完全連接配接)層上仍然具有損失函數(例如SVM /Softmax),我們在之前章節開發的用于學習規則神經網絡的所有技巧/技巧仍然适用。
那有什麼不一樣呢?ConvNet 架構明确地假設輸入是圖像,這允許我們将某些屬性編碼到體系結構中。進而,使得前向功能更有效地實作,并且極大地減少了網絡中的參數量。
11.1 體系結構概述
回憶:規則的神經網絡。正如我們在前一章看到的,神經網絡接收一個輸入(一個向量),并通過一系列隐藏層來轉換它。每個隐藏層由一組神經元組成,其中每個神經元完全連接配接到前一層中的所有神經元,其中單個層中的神經元完全獨立地運作,并且不共享任何連接配接。最後一個完全連接配接的層被稱為“輸出層”,在分類場景中,它代表類分數。
規則的神經網絡不能很好地擴充到完整的圖像。在CIFAR-10中,圖像僅為大小為32×32×3的(32個寬、32個高、3個顔色通道),是以在規則的神經網絡的第一隐藏層中的單個完全連接配接的神經元将具有32×32×3=3072的權重。這一數量似乎仍然是可控的,但顯然這種完全連接配接的結構不會擴充到更大的圖像。例如,正常大小的圖像,例如,200×200×3,将導緻具有200×200×3=120000權重的神經元。此外,我們幾乎肯定希望有幾個這樣的神經元,是以參數會增加得很快!顯然,這種完全連通性是浪費的,大量的參數會很快導緻過度拟合。
三維容量的神經元。卷積神經網絡利用了輸入是由圖像這一事實,以更合理的方式限制了體系結構。特别地,不同于規則的神經網絡,卷積層具有3個維排列的神經元:寬度、高度、深度。(注意這裡的單詞深度指的是激活體積的第三個次元,而不是一個完整的神經網絡的深度,它可以指網絡中的層的總數。)例如,CIFAR-10中的輸入圖像是激活的輸入量,并且體積具有次元32x32×3(分别為寬度、高度、深度)。正如我們将很快看到的,一個層中的神經元将隻連接配接到它之前的層的一個小區域,而不是以完全連接配接的方式連接配接所有的神經元。此外,CIFAR-10的最終輸出層的次元為1x1x10,因為在ConvNet架構的最後,我們将把整個圖像縮減為沿depth次元排列的單個等級分數向量。這是可視化:

左:一個規則的三層神經網絡。右:一個卷積神經網絡,其神經元在三個次元排列(寬度,高度,深度),如在一個圖層中被可視化那樣。ConvNet 的每一層将3D輸入體積轉換成神經元激活的3D輸出體積。在這個例子中,紅色輸入層代表圖像,是以它的寬度和高度将是圖像的尺寸,深度将為3(紅色、綠色、藍色通道)。
ConvNet 是由多層組成的。每一層都有一個簡單的API:它将輸入的3D體積轉換成輸出3D體積,并具有一些可能或可能不具有參數的可微函數。
11.2 建構卷積神經網絡的層
如上所述,一個簡單的ConvNet 是一層接一層的序列,網絡中的每一層通過一個可微函數将一個體積的激活轉換為另一個。我們使用三種主要類型的層來建構ConvNet 結構:卷積層、彙集層和全連接配接層(與規則神經網絡中所述的一樣)。我們将堆疊這些層以形成完整的ConvNet 體系結構。
示例架構:概述。我們将在下面介紹更多的細節,但是一個簡單的CIFAR-10分類的ConvNet 可能的有架構是:輸入- CONV -RELU -POOL -FC]:
- 輸入[32×32×3]将保持圖像的原始像素值,在這種情況下,圖像寬度為32,高度為32,并且具有三個顔色通道R、G、B
- 卷積層中,神經元與輸入層中的一個局部區域相連,每個神經元都計算自己與輸入層相連的小區域與自己權重的點積。卷積層會計算所有神經元的輸出。如果我們使用12個濾波器(也叫作核),得到的輸出資料體的次元就是[32x32x12]
- RELU 層将會逐個元素地進行激活函數操作,例如使用以0為門檻值的max(0,x)激活函數。該層對資料尺寸沒有改變,還是[32x32x12]。
- 彙聚層在在空間次元(寬度和高度)上進行降采樣(downsampling)操作,資料尺寸有可能變為[16x16x12]。
- FC(即全連接配接)層将計算類得分,結果大小為[1x1x10],其中10個數字中的每一個對應于類得分,例如在10個類别的CIFAR-10中。全連接配接層與正常神經網絡一樣,顧名思義,這個層中的每個神經元都将連接配接到前一個卷中的所有神經元。
以這種方式,ConvNets 将原始圖像逐層地從原始像素值轉換為最終類分數。注意,一些層包含參數,有的層則沒有。具體說來,CONV/FC層對輸入執行變換操作的時候,不僅會用到激活函數,還會用到很多參數(神經元的突觸權值和偏差)。另一方面,RELU/POOL層将實作固定的函數操作。CONV/FC層中的參數将以梯度下降的方式進行訓練,進而使神經網絡計算的類得分與每個圖像的訓練集中的标簽一緻。
小結:
- ConvNet 架構在最簡單的情況下是将圖像轉換為輸出(例如保持類分數)的層清單
- 其中有幾種不同類型的層(例如CONV/FC/RELU/POOL是目前最流行的)
- 每個層的輸入是3D資料,然後使用一個可導的函數将其變換為3D的輸出資料
- 每個層可能有或可能沒有參數(例如CONV/FC層有參數,RELU/POOL就沒有)
- 每個層可能有或可能沒有額外的超參數(例如CONV/FC/POOL有,RELU 層沒有)
一個卷積神經網絡的激活輸出例子。左邊的輸入層存有原始圖像像素,右邊的輸出層存有類别分類評分。在處理流程中的每個激活資料體是鋪成一列來展示的。因為對3D資料作圖比較困難,我們就把每個資料體切成層,然後鋪成一列顯示。最後一層裝的是針對不同類别的分類得分,這裡隻顯示了得分最高的5個評分值和對應的類别。完整的網頁示範在我們的課程首頁。本例中的結構是一個小的VGG網絡,VGG網絡後面會有讨論
下面描述各個層和它們的超參數及連通性的細節。
11.2.1 卷積層
Conv 層是卷積網絡的核心建構塊,它承擔了網絡中大部分的計算量。
概述和直覺。首先讨論的是,在沒有大腦和生物意義上的神經元之類的比喻下,CONV 層到底在計算什麼。卷積層的參數由一些可學習的濾波器組成。每個濾波器在空間上(寬度和高度)都比較小,但是深度和輸入資料一緻。舉例來說,卷積神經網絡第一層的一個典型的濾波器的尺寸可以是5x5x3(寬高都是5像素,深度是3。因為圖像為RGB顔色通道,是以有3的深度)。在前向傳播的時候,讓每個濾波器都在輸入資料的寬度和高度上滑動(更精确地說是卷積),然後計算整個濾波器和輸入資料任一處的内積。當濾波器沿着輸入資料的寬度和高度滑過後,會生成一個2維的激活圖(activation map),激活圖給出了在每個空間位置處濾波器的反應。直覺地來說,網絡會讓濾波器學習到當它看到某些類型的視覺特征時就激活,具體的視覺特征可能是某些方位上的邊界,或者在第一層上某些顔色的斑點,甚至可以是網絡更高層上的蜂巢狀或者車輪狀圖案。在每個卷積層上,我們會有一整個集合的濾波器(比如12個),每個都會生成一個不同的二維激活圖。将這些激活映射在深度方向上層疊起來就生成了輸出資料。
以大腦做比喻:如果你喜歡用大腦和生物神經元來做比喻,那麼輸出的3D資料中的每個資料項可以被看做是神經元的一個輸出,而該神經元隻觀察輸入資料中的一小部分,并且和空間上左右兩邊的所有神經元共享參數(因為這些數字都是使用同一個濾波器得到的結果)。現在開始讨論神經元的連接配接,它們在空間中的排列,以及它們參數共享的模式。
局部連接配接:在處理圖像這樣的高次元輸入時,讓每個神經元都與前一層中的所有神經元進行全連接配接是不現實的。相反,我們讓每個神經元隻與輸入資料的一個局部區域連接配接。該連接配接的空間大小叫做神經元的接收域,它的尺寸是一個超參數(其實就是濾波器的空間尺寸)。在深度方向上,這個連接配接的大小總是和輸入量的深度相等。需要再次強調的是,我們對待空間次元(寬和高)與深度次元是不同的:連接配接在空間(寬高)上是局部的,但是在深度上總是和輸入資料的深度一緻。
例1。例如,假設輸入卷大小為[32×32×3],(例如RGB CIFAR-10圖像)。如果接收域(或濾波器大小)為5x5,那麼Conv 層中的每個神經元将在輸入卷中具有[5x5x3]區域的權重,總共為5×5×3=75權重(和1個偏置參數)。請注意,沿着深度軸的連通度必須是3,因為這是輸入卷的深度。
例2。假設輸入卷的大小[16x16x20]。然後使用3x3的接收域,Conv 層中的每個神經元現在總共有3×3×20=180個連接配接到輸入卷。注意,同樣地,連通性在空間中是局部的(例如3x3),但與輸入的深度(20)一樣。
左:紅色的示例輸入體(例如,32×32×3 CIFAR-10圖像),以及第一卷積層中的神經元的示例體積。卷積層中的每個神經元在空間上隻連接配接到輸入空間中的局部區域,但連接配接到全深度(即所有顔色通道)。注意,沿着深度有多個神經元(在這個例子中有5個),它們都在輸入中的同一個區域——參見下面文本中的深度列的讨論。右:神經網絡章節中介紹的神經元保持不變,它們還是計算權重和輸入的内積,然後進行非線性激活函數運算,隻是它們的連接配接被限制在一個局部空間
空間布局。我們已經解釋了Conv 層中每個神經元與輸入體積的連接配接性,但是我們還沒有讨論輸出神經元中有多少神經元,或者它們如何排列。三個超參數控制輸出量的大小:深度、步幅和零填充。我們接下來讨論:
- 首先,輸出量的深度是一個超參數:它對應于我們想要使用的濾波器的數量,每個濾波器學習在輸入中尋找不同的東西。比如,如果第一個卷積層的輸入是原始圖像,那麼在深度次元上的不同神經元将可能被不同方向的邊界,或者是顔色斑點激活。我們将這些沿着深度方向排列、感受域相同的神經元集合稱為深度列(depth column),也有人使用纖維(fibre)來稱呼它們。
- 其次,我們必須指定我們滑動濾波器的步幅。當步幅為1時,我們一次移動濾波器一個像素。當步幅為2(或不尋常的3或更多,雖然這在實踐中是罕見的),則濾波器每次跳躍2像素。這個操作會讓輸出資料體在空間上變小。
- 正如我們将很快看到的那樣,有時在邊框上用零來填充輸入卷是很友善的。這個零填充的大小是一個超參數。零填充的優良特性是,它将允許我們控制輸出卷的空間大小(最常見的是,我們将很快看到,我們将使用它來精确地保持輸入體積的空間大小,使得輸入和輸出寬度和高度是相同的)。
我們可以用輸入體積大小(W*W)、Conv 層神經元(F*F)的接收域大小、應用它們的步幅(S)、以及在邊界上使用的零填充量(P)計算輸出體積的空間大小。你可以證明,正确的公式來計算多少神經元“适合”是由(W - F+ 2P)/S + 1給出的。例如,對于一個7x7輸入和一個3x3濾波器與步幅1和邊界填充0,我們将得到一個5x5輸出。若步幅為2,我們将得到一個3x3輸出。讓我們再看一個圖形例子:
空間布局示意圖。在這個例子中,隻有一個空間次元(x軸),一個神經元具有接收域大小F=3,輸入大小是W=5,并且零填充P=1。左:神經元以S=1的步幅跨過輸入,給出大小(5 - 3+2)/ 1 + 1=5的輸出。右:神經元使用S=2的步幅,輸出大小(5 - 3+2)/ 2+1=3。注意,步幅S=3不能使用,因為它無法整齊地穿過資料體。用計算公式也可以看出,因為(5 - 3+2)=4不能被3整除。
本例中,神經元的權重是[1,0,-1],顯示在圖的右上角,偏內插補點為0。這些權重是被所有黃色的神經元共享的(參數共享的内容看下文相關内容)。
使用零填充。在上面左邊的例子中,注意輸入次元是5,輸出次元是相等的:也就是5。這是因為我們的接受域是3,我們使用的零填充為1。如果沒有使用零填充,那麼輸出體積的空間維數就隻有3。因為這就是濾波器整齊滑過并覆寫原始資料需要的數目。一般來說,當步長為S=1時,将零填充設為P=(F−1)/ 2,可確定輸入體積和輸出體積在空間上具有相同的大小。這樣使用零填充是非常常見的,我們将在讨論更多關于ConvNet 架構的充分理由時讨論。
對步幅的限制。再次注意,空間布置超參數互相制約。例如,當輸入的大小為W=10時,不使用零填充,P=0,濾波器大小為F=3,那麼就不可能使用步長S=2,因為(W−F+2P)/S+1=(10−3+0)/2+1=4.5,即不是整數,這就是說神經元不能整齊對稱地滑過輸入資料體。是以,這個超參數的設定被認為是無效的,一個卷積神經網絡庫可能會報出一個錯誤,或者修改零填充值來讓設定合理,或者修改輸入資料體尺寸來讓設定合理,或者其他什麼措施。正如我們将在ConvNet 體系結構部分中看到的那樣,可以看到合理地設定網絡的尺寸讓所有的次元都能正常工作,這件事可是相當讓人頭痛的。而使用零填充和遵守其他一些設計政策将會有效解決這個問題。
真實的例子。Krizhevsky等,赢得了2012年的ImageNet挑戰,其輸入圖像的尺寸是[227x227x3]。在第一卷積層上,它使用具有接收域大小F=11的神經元,步幅S=4,并且沒有零填充P=0。由于(227 - 11)/ 4+1=55,卷積層的深度 k=96,是以Conv 層輸出體積具有[55×55×96]的大小。這個55x55x96個神經元中,每個都和輸入資料體中一個尺寸為[11x11x3]的區域全連接配接。在深度列上的96個神經元都是與輸入資料體中同一個[11x11x3]區域連接配接,但是權重不同。作為一個有趣的旁白,如果你閱讀實際檔案,它聲稱輸入圖像是224x224,這肯定是不正确的,因為(224 - 11)/4 + 1顯然不是整數。這使許多人在曆史上迷茫,對所發生的事情知之甚少。我自己最好的猜測是,Alex 使用了3個額外像素的零填充,這是他在論文中沒有提到的。
參數共享。卷積層采用參數共享方案控制參數個數。使用上面的真執行個體子,我們看到在第一個Conv 層中有55×55×96=290400個神經元,并且每個都具有11×11×3=363個權重和1個偏置。加一起,這第一層的ConvNet就是290400×364 = 105705600個參數 。顯然,這個數字非常高。
實踐證明,可以通過做出一個合理的假設來顯著地減少參數的數量:如果一個特征在某些空間位置(x,y)上是有用的,那麼在不同的位置(x2,y2)計算也是有用的。換句話說,就是将深度次元上一個單獨的2維切片看做深度切片(depth slice),比如一個資料體尺寸為[55x55x96]的就有96個深度切片,每個尺寸為[55x55]。在每個深度切片上的神經元都使用同樣的權重和偏差。在這樣的參數共享下,例子中的第一個卷積層就隻有96個不同的權重集了,一個權重集對應一個深度切片,共有96x11x11x3=34,848個不同的權重,或34,944個參數(+96個偏差)。在每個深度切片中的55x55個權重使用的都是同樣的參數。在反向傳播的時候,都要計算每個神經元對它的權重的梯度,但是需要把同一個深度切片上的所有神經元對權重的梯度累加,這樣就得到了對共享權重的梯度。這樣,每個切片隻更新一個權重集。
注意,如果單個深度切片中的所有神經元都使用相同的權重向量,那麼在每個深度切片中的CONV 層的正向傳遞可以被計算為神經元的權重與輸入體積的卷積(convolution ,是以就有了 卷積層 這個名稱)。這也是為什麼總是将這些權重集合稱為濾波器(filter)(或卷積核(kernel)),因為它們和輸入進行了卷積。
Krizhevsky 等人學習得到的示例濾波器。這裡所示的96個濾波器中的每一個都是大小[11x11x3],并且每一個由一個深度切片中的55×55神經元共享。注意,參數共享假設是相對合理的:如果檢測水準邊緣在圖像中的某個位置是重要的,那麼由于圖像的平移不變結構,它也應該直覺地在一些其他位置有用。這是因為圖像結構具有平移不變性。是以在卷積層的輸出資料體的55x55個不同位置中,就沒有必要重新學習去探測一個水準邊界了。
請注意,有時參數共享假設可能沒有意義。尤其是當輸入到ConvNet 的圖像具有特定的中心結構時,我們可能需要,例如,在圖像的一邊應該學習與另外一邊完全不同的特征。一個實際的例子是當輸入是以人臉為中心的圖像,您可能需要不同的眼睛特定或頭發特定的特征可以(也應該)在不同的空間位置學習。在這種情況下,放寬參數共享方案是常見的,将層稱為局部連接配接層(Locally-Connected Layer)。
Numpy 舉例. 為了使上面的讨論更具體,讓我們用代碼和一個特殊的例子來表達上述意思。假設輸入卷是一個numpy 數組X:
- 一個位于(x,y)的深度列(或纖維)将會是 X[x,y,:]。
- 在深度為d處的深度切片,或激活圖應該是X[:,:,d]。
Conv 層執行個體。假設輸入體積
X
具有形狀
X.shape: (11,11,4)
。進一步假設我們不使用零填充(P=0),濾波器大小是F=5,并且步幅是S=2。是以,輸出體積将具有空間大小(11-5)/ 2 + 1=4,給出具有寬度和高度4的體積。輸出卷中的激活映射(稱為 V)将看起來如下(在本示例中僅計算了一些元素):
-
V[0,0,0] = np.sum(X[:5,:5,:] * W0) + b0
-
V[1,0,0] = np.sum(X[2:7,:5,:] * W0) + b0
-
V[2,0,0] = np.sum(X[4:9,:5,:] * W0) + b0
-
V[3,0,0] = np.sum(X[6:11,:5,:] * W0) + b0
記住,在 numpy 中,上面的
*
操作表示數組之間的逐元素相乘。還注意,權重向量W0是該神經元的權重向量,而B0是偏置。這裡,W0被假定為形狀
W0.shape: (5,5,4)
,因為濾波器的尺寸為5,輸入體積的深度為4。請注意,在每一點上,我們都在計算普通神經網絡中所見的點積。此外,我們看到,我們使用相同的重量和偏置(由于參數共享),并且沿着寬度的尺寸在2步(即步幅)中增加。為了在輸出音量中構造第二個激活圖,我們将有:
-
V[0,0,1] = np.sum(X[:5,:5,:] * W1) + b1
-
V[1,0,1] = np.sum(X[2:7,:5,:] * W1) + b1
-
V[2,0,1] = np.sum(X[4:9,:5,:] * W1) + b1
-
V[3,0,1] = np.sum(X[6:11,:5,:] * W1) + b1
-
(在y方向上)V[0,1,1] = np.sum(X[:5,2:7,:] * W1) + b1
-
(或同時在兩個方向上)V[2,3,1] = np.sum(X[4:9,6:11,:] * W1) + b1
在這裡,我們通路的是V的深度次元上的第二層(即位置1),因為我們正在計算第二個激活映射,并且現在使用了一組不同的參數(W1)。在上面的例子中,我們為了簡潔而忽略了卷積層将執行的一些其他操作來填充輸出陣列的其他部分。還有,要記得這些卷積操作通常後面接的是激活函數,對激活圖中的每個元素做激活函數運算,比如ReLU。這裡沒有顯示。
小結: 我們總結一下卷積層:
- 輸入資料體的尺寸為 W1×H1×D1
- 需要4個超參數:
- 濾波器數量 K,
- 濾波器的空間尺寸 F,
- 步幅S,
- 零填充數量P.
- 輸出資料體的尺寸為 W2×H2×D2,其中:
- W2=(W1−F+2P)/S+1
- H2=(H1−F+2P)/S+1 (寬度和高度的計算方法對稱相同 )
- D2=K
- 由于參數共享,每個濾波器包含 F⋅F⋅D1個權重,卷積層一共有(F⋅F⋅D1)⋅K個權重和K 個偏置
- 在輸出資料體中,第d個深度切片(空間尺寸是W2×H2),用第d個濾波器和輸入資料進行有效卷積運算的結果(使用步長S),最後在加上第d個偏置
通常将超參數設定為F=3,S=1,P=1。也有共同的慣例和經驗法則來設定這些超參數。參閱下面的 ConvNet architectures 部分。
卷積示範。下面是一個CONV 層的運作示範。由于3D體積很難可視化,所有的卷(輸入(藍色),權重(紅色),輸出(綠色))被可視化,每個深度切片以行堆疊。輸入體積的大小為W1=5,H1=5,D1=3,而CONV層參數為K=2,F=3,S=2,P=1。也就是說,我們有兩個大小為3×3的過濾器,它們的步幅為2。是以,輸出體積大小具有空間大小(5 - 3+2)/2+1=3。此外,注意到對輸入卷施加P=1的填充,使得輸入卷的外部邊界為零。下面的可視化疊代輸出激活(綠色),并顯示每個元素是通過元素化計算突出顯示的輸入(藍色)與濾波器(紅色)相乘,求和,最後加上偏差得來。
用矩陣乘法實作。注意到卷積運算就是在輸入的濾波器和局部區域之間的點積操作。卷積層的常用實作方式就是利用這一點,将卷積層的前向傳播變成一個巨大的矩陣乘法:
- 輸入圖像的局部區域被通常稱為“im2col”的操作中拉伸為列。比如,如果輸入是[227x227x3],要與尺寸為11x11x3的濾波器以步長為4進行卷積,就取輸入中的[11x11x3]資料塊,然後将其拉伸為長度為11x11x3=363的列向量。重複進行這一過程,因為步長為4,是以輸出的寬高為(227-11)/4+1=55,是以得到im2col操作的輸出矩陣
的尺寸是[363x3025],其中每列是拉伸的感受域,共有55x55=3,025個。注意因為感受域之間有重疊,是以輸入資料體中的數字在不同的列中可能有重複。X_col
- 卷積層的權重同樣伸展成行。例如,如果有大小為[11x11x3]的96個濾波器,這将給出一個大小為[96×363 ]矩陣
。W_row
- 卷積的結果現在相當于執行一個大矩陣乘法的
,它評估每個濾波器和每個接收域位置之間的點積。在我們的示例中,這個操作的輸出将是[96×3025 ],給出每個位置的每個濾波器的點積的輸出。np.dot(W_row, X_col)
- 最終的結果必須重新調整到其正确的輸出尺寸[55 x55 x96]
這種方法的缺點在于它會使用大量的記憶體,因為輸入量中的一些值在
X_col
中被複制了多次。然而,好處是矩陣乘法有很多非常有效的實作方式(例如,通常使用 BLAS API。此外,同樣的im2col 思想可以被重用來執行彙聚操作,這是我們接下來讨論的。
反向傳播。卷積運算(對于資料和權值)的反向傳遞也是卷積(但在空間上翻轉的濾波器)。使用一個1維的例子比較容易示範。
1x1卷積。作為一個旁白,一些論文使用1x1卷積,最先提出的論文是 Network in Network。人們剛開始看見這個1x1卷積的時候比較困惑,尤其是那些具有信号處理專業背景的人。因為信号是2維的,是以1x1卷積就沒有意義。但是,在卷積神經網絡中不是這樣,因為這裡是對3個次元進行操作,濾波器和輸入資料體的深度是一樣的。比如,如果輸入是[32x32x3],那麼1x1卷積就是在高效地進行3維點積(因為輸入深度是3個通道)。
擴張卷積。最近的發展(例如,見 Fisher Yu and Vladlen Koltun 的論文)是将一個更多的超參數引入到稱為擴張的CONV 層。到目前為止,我們隻讨論了連續的CONV濾波器。然而,有可能在每個細胞之間有空間,稱為擴張。作為一個例子,在一維中,大小為3的濾波器W将在輸入X上計算:
w[0]*x[0] + w[1]*x[1] + w[2]*x[2]
。這是0的膨脹。對于膨脹1,濾波器将計算
w[0]*x[0] + w[1]*x[2] + w[2]*x[4]
;換句話說,應用之間存在1的間隙。在某些設定中,擴張卷積與正常卷積結合起來非常有用,因為在很少的層數内更快地彙集輸入圖檔的大尺度特征。例如,如果你将兩個3x3 CONV層疊加在上面,那麼你可以說服自己,第二層上的神經元是輸入的5x5更新檔的函數(我們會說這些神經元的有效感受域是5x5)。如果我們使用擴張的卷積,那麼這個有效的感受域會生長得更快。
11.2.2 彙聚層
在卷積網絡體系結構中,在連續卷積層之間周期性地插入彙集層是常見的。它的功能是逐漸減少表示的空間大小,以減少網絡中的參數和計算量,進而也控制過拟合。彙集層在輸入的每個深度切片上獨立操作,并使用MAX操作在空間上重新調整大小。最常見的形式是具有2x2大小的濾波器的彙集層,在寬度和高度兩個輸入中,每一個深度切片施加2個步幅的降采樣,丢棄75%的激活。在這種情況下,每個MAX操作是從4個數字中取最大值(也就是在深度切片中某個2x2的區域)。深度次元保持不變。更一般地說,彙集層:
- 輸入資料尺寸 W1×H1×D1
- 需要兩個超參數:
- 濾波器大小F
- 步幅S
- 輸出大學 W2×H2×D2 其中:
- W2=(W1−F)/S+1
- H2=(H1−F)/S+1
- D2=D1
- 因為對輸入進行的是固定函數計算,是以沒有引入參數
- 在彙聚層中很少使用零填充
值得注意的是,在實踐中發現隻有兩個常見的最大彙聚層的超參數取值:一個池組,F=3,S=2(也稱為重疊池),更常見的是F=2,S=2。具有較大接收域的彙聚尺寸的破壞性太強。
常用彙聚。除了最彙聚之外,彙聚單元還可以執行其他功能,例如平均彙聚或甚至L2範數彙聚。過去往往使用平均彙聚,但最近失寵了,現在常用最大彙聚操作,實踐證明最大彙聚操作能地工作。
彙集層在輸入卷的每個深度切片中獨立地空間地對體積進行采樣。左:在這個例子中,輸入大小的大小[224x224x64 ]與濾波器大小2合并,跨步2到大小[112x112x64 ]的輸出音量。請注意,深度不變。右:最常見的下采樣操作是max,産生最大池,這裡顯示的步幅為2。也就是說,每個max操作都是從4個數字中選取(即2x2的方塊區域中)。
反向傳播。回顧反向傳播章節,max(x,y)操作的反向傳播有一個簡單的解釋,即隻将梯度傳遞到在正向傳遞中具有最高值的輸入。是以,在彙集層的正向傳遞期間,通常會記下最大激活的索引(有時也被稱為開關),這樣在反向傳播期間就能高效地計算梯度。
擺脫彙聚。許多人不喜歡彙聚操作,認為沒有它我們也可以。例如,力求簡單:所有卷積網絡 建議丢棄彙聚層,而隻支援由重複的CONV層構成的體系結構。為了減少表示的大小,他們建議在CONV層中偶爾使用更大的步幅。在訓練良好的生成模型,如變分自動編碼器(VAES)或生成對抗網絡(GANS)時,丢棄彙聚層也被發現是重要的。很可能未來的架構将很少有沒有彙聚層的特征。
11.2.3 歸一化層
在ConvNet 架構中,人們提出了有許多類型的歸一化層,有時意圖實作在生物腦中觀察到的抑制方案。然而,這些層已經失去了青睐,因為在實踐中,他們的貢獻已被證明是最小的,如果有的話。對于各種類型的規範化,請參見 Alex Krizhevsky的 cuda-convnet library API 中的讨論。
11.2.4 全連接配接層
完全連接配接層中的神經元與前一層中的所有激活具有完全連接配接,如在正常神經網絡中所見。是以,它們的激活可以用矩陣乘法計算,然後是偏置偏移。有關更多資訊,請參閱筆記部分的神經網絡。
11.2.5 全連接配接層到卷積層的轉換
值得注意的是,FC和CONV層之間的唯一差別是CONV層中的神經元僅連接配接到輸入中的局部區域,并且CONV卷中的許多神經元共享參數。然而,兩層神經元仍然計算點積,是以它們的函數形式是相同的。是以,可以在FC和CONV層之間轉換:
- 對于任一個卷積層,都存在一個能實作和它一樣的前向傳播函數的全連接配接層。權重矩陣是一個巨大的矩陣,除了某些特定塊(這是因為有局部連接配接),其餘部分都是零。而在其中大部分塊中,元素都是相等的(因為參數共享)。
- 相反,任何FC層都可以轉換為CONV層。例如,一個具有深度K=4096的FC層,即在某個輸入量為7×7×512的情況下,可以等價地表示為一個具有濾波器尺寸F=7、零填充的值P= 0、步幅S=1、卷積層的深度K= 4096的CONV層。換言之,我們将濾波器的大小設定為輸入體積的大小,是以輸出僅為1×1×4096,因為隻有一個單獨的深度列覆寫并滑過輸入資料體,這樣其結果就與普通的FC層的結果相同的結果。
FC -> CONV轉換。在這兩種轉換中,将FC層轉換為CONV層的能力在實踐中特别有用。考慮一個使用224x224x3圖像的ConvNet 架構,然後使用一系列CONV層和彙聚層将圖像縮小到7X7X512大小的激活卷(在AlexNet中就是這樣,通過使用5個彙聚層來對輸入資料進行空間上的降采樣,每次尺寸下降一半,是以最終空間尺寸為224/2/2/2/2/2=7)。從這裡可以看到,AlexNet使用了兩個尺寸為4096的全連接配接層,最後一個有1000個神經元的全連接配接層用于計算分類評分。我們可以将這3個全連接配接層中的任意一個轉化為卷積層:
- 将第一個連接配接區域是[7x7x512]的全連接配接層,轉換為濾波器尺寸為F=7的CONV層,這樣輸出資料體就為[1x1x4096]了
- 将第二個全連接配接層,轉換為濾波器尺寸為F=7的CONV 層,這樣輸出資料體就為[1x1x4096]
- 同樣,将第三個FC層,轉換為濾波器尺寸為F=7的CONV 層,這樣最終輸出資料體就是[1x1x1000]
這些轉換中的每一個在實踐中可以包括操縱(例如整形)每個FC層中的權重矩陣W到CONV層濾波器。事實證明,這種轉換允許我們在一個更大的圖像中非常有效地“滑動”原始的對流,在一個單一的向前通過。
實際操作中,每次這樣的變換都需要把全連接配接層的權重W重塑成卷積層的濾波器。那麼這樣的轉化有什麼作用呢?它在下面的情況下可以更高效:讓卷積網絡在一張更大的輸入圖檔上滑動(譯者注:即把一張更大的圖檔的不同區域都分别帶入到卷積網絡,得到每個區域的得分),得到多個輸出,這樣的轉化可以讓我們在單個向前傳播的過程中完成上述的操作。
例如,如果我們想讓224x224尺寸的浮窗,以步長為32在384x384的圖檔上滑動,把每個經停的位置都帶入卷積網絡,最後得到6x6個位置的類别得分。上述的把全連接配接層轉換成卷積層的做法會更簡便。如果224x224的輸入圖檔經過卷積層和彙聚層之後得到了[7x7x512]的數組,那麼,384x384的大圖檔直接經過同樣的卷積層和彙聚層之後會得到[12x12x512]的數組(因為途徑5個彙聚層,尺寸變為384/2/2/2/2/2 = 12)。然後再經過上面由3個全連接配接層轉化得到的3個卷積層,最終得到[6x6x1000]的輸出(因為(12 - 7)/1 + 1 = 6)。這個結果正是浮窗在原圖經停的6x6個位置的得分!(譯者注:這一段的翻譯與原文不同,經過了譯者較多的修改,使更容易了解)
對于384x384的圖像,讓(含全連接配接層)初始ConvNet 以32像素的步幅獨立對圖像中的224x224塊進行多次評價,其效果和使用把全連接配接層變換為卷積層後的卷積神經網絡進行一次前向傳播是一樣的。
在36個評估共享計算的情況下,将轉換後的ConvNet 轉發一次比在所有36個位置上疊代原始的ConvNet 更有效。這一技巧經常在實踐中被用來獲得更好的性能,例如,通常調整圖像大小以使其變大,使用轉換的神經網絡來評估許多空間位置的類得分,然後平均類分數。
最後,如果我們想用步長小于32的浮窗怎麼辦?用多次的向前傳播就可以解決。比如我們想用步長為16的浮窗。那麼先使用原圖在轉化後的卷積網絡執行向前傳播,然後分别沿寬度,沿高度,最後同時沿寬度和高度,把原始圖檔分别平移16個像素,然後把這些平移之後的圖分别帶入卷積網絡。(譯者注:這一段的翻譯與原文不同,經過了譯者較多的修改,使更容易了解)
- Net Surgery 上面的代碼展示了如何進行轉換 (使用 Caffe)
11.3 卷積神經網絡體系結構
我們已經看到卷積網絡通常隻由三個層類型組成:CONV,POOL (預設指最大值彙聚)和FC(全連接配接)。ReLU激活函數也應該算是一層,它逐元素地進行激活函數操作。在這一節中,我們将讨論這些是如何堆疊在一起形成整個ConvNets的。
11.3.1 層模式
ConvNet架構的最常見形式是堆切幾個CONV-RELU層,之後是POOL層,并重複此模式,直到圖像在空間上合并為小尺寸。在某種程度上,過渡到完全連接配接的層是常見的。最後一個完全連接配接的層保持輸出,例如類分數。換言之,最常見的CONNETE架構遵循以下模式:
INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC
* 号表示重複,
POOL? 表示
可選的彙聚層。此外,n>=0(通常為n<=3),m>0,k>=0(通常為k<3)。常見的ConvNet架構有:
-
, 這就是一個線性分類器,INPUT -> FC
.N = M = K = 0
-
INPUT -> CONV -> RELU -> FC
-
. 此處在每個彙聚層之前都有一個卷積層INPUT -> [CONV -> RELU -> POOL]*2 -> FC -> RELU -> FC
-
此處每個彙聚層前有兩個卷積層,這個思路适用于更大更深的網絡,因為在執行具有破壞性的彙聚操作前,多重的卷積層可以從輸入資料中學習到更多的複雜特征。INPUT -> [CONV -> RELU -> CONV -> RELU -> POOL]*3 -> [FC -> RELU]*2 -> FC
幾個小濾波器卷積層的組合比一個大濾波器卷積層好:假設你一層一層地重疊了3個3x3的卷積層(層與層之間有非線性激活函數)。在這個排列下,第一個卷積層中的每個神經元都對輸入資料體有一個3x3的視野。第二個卷積層上的神經元對第一個卷積層有一個3x3的視野,也就是對輸入資料體有5x5的視野。同樣,在第三個卷積層上的神經元對第二個卷積層有3x3的視野,也就是對輸入資料體有7x7的視野。假設不采用這3個3x3的卷積層,而是使用一個單獨的有7x7的感受域的卷積層,那麼所有神經元的感受域也是7x7,這會就有一些缺點。首先,多個卷積層與非線性的激活層交替的結構,比單一卷積層的結構更能提取出深層的更好的特征。其次,假設所有的資料有
個通道,那麼單獨的7x7卷積層将會包含C×(7×7×C)=49C*C個參數,而3個3x3的卷積層的組合僅有3×(C×(3×3×C))=27C*C個參數。直覺說來,最好選擇帶有小濾波器的卷積層組合,而不是用一個帶有大的濾波器的卷積層。前者可以表達出輸入資料中更多個強力特征,使用的參數也更少。唯一的不足是,在進行反向傳播時,中間的卷積層可能會導緻占用更多的記憶體。
最新進展:傳統的将層按照線性進行排列的方法已經受到了挑戰,挑戰來自谷歌的Inception結構和微軟亞洲研究院的殘差網絡(Residual Net)結構。這兩個網絡(下文案例學習小節中有細節)的特征更加複雜,連接配接結構也不同。
在實踐中:使用任何對ImageNet最有效的方案。如果您在思考架構決策時感到有點疲憊,那麼您将很高興地知道,在90%或更多的應用程式中,您不必擔心這些。我想把這一點總結為“不要成為英雄”:你應該看看ImageNet上目前工作最好的體系結構,下載下傳一個預先準備好的模型,然後在你的資料上精簡它,而不是為某個問題滾動你自己的架構。你很少需要從頭開始訓練一個戰車,或者從頭開始設計一個。我也在深學習學校做了這一點。
11.3.2 層大小模式
到現在為止,我們還沒有談及在一個ConvNet中的每個層中使用的常用超參數的說明。我們将首先陳述調整體系結構大小的一般經驗法則,然後按照這些規則讨論符号:
輸入層(包含圖像)應該能被2整除很多次。常用數字包括32(比如CIFAR-10),64,96(比如STL-10)或224(比如ImageNet卷積神經網絡),384和512。
conv層應該使用小的濾波器(例如,3x3或最多5x5),使用S=1的步長,并且至關重要的是,以零填充輸入體積,使得conv層不改變輸入的空間次元。也就是說,當F=3時,然後使用P=1将保留輸入的原始大小。F=5時,p=2。對于一般的F,可以看出,P=(F - 1)/ 2 能保留輸入大小。較大的過濾器大小(例如7x7左右),也隻有在輸入圖像的第一個conv層上才用。
彙聚層負責對輸入的空間維數進行降維處理。最常見的設定是使用2x2接收字段(即F=2)的最大值彙聚,并以2的步長(即S=2)。請注意,這完全丢棄輸入量中的75%的激活(由于在寬度和高度上向下采樣2)。另一個不太常見的設定是使用3x3接收域,步幅為2。很少将最大值彙聚的接收字段大小設定為大于3,因為該彙聚過于有損和具有攻擊性。這通常會導緻性能下降。
減少尺寸設定的問題。上述方案是令人滿意的,因為所有CONV層都保留其輸入的空間大小,而POOL層單獨負責在空間上對卷進行降維處理。如果使用的步長大于1并且不對卷積層的輸入資料使用零填充,那麼就必須非常仔細地監督輸入資料體通過整個卷積神經網絡結構的過程,确認所有的步長和濾波器都尺寸互相吻合,ConvNet的結構美妙對稱地聯系在一起。
為什麼在CONV中使用1的步幅?更小的步伐在實踐中能更好地工作。此外,如已經提到的,步長1允許我們将所有空間降采樣留給POOL層,其中CONV層僅對輸入體積進行深度轉換。
為什麼要使用填充?除了在CONV之後保持空間大小恒定的上述好處之外,這樣做實際上提高了性能。如果CONV層不是對輸入進行零填充,而隻執行有效的卷積,那麼在每次CONV之後,卷的大小将減少少量,并且邊界處的資訊将被快速“洗掉”。
基于記憶體限制折衷。在某些情況下(特别是在早期的神經網絡體系結構中),根據以上規則,記憶體的使用量可能迅速提升。例如,用三個3x3 CONV層過濾224x224x3圖像,每層64個過濾器,零填充為1,将建立三個大小為[224x224x64 ]的激活體積。這相當于總共大約1000萬個激活,或者72MB的記憶體(每個圖像,用于激活和梯度)。由于GPU經常被記憶體所限制,是以可能需要妥協。在實踐中,人們更傾向于隻在網絡的第一個CONV層做出妥協。例如,一個折衷方案可能是使用具有7x7和步幅2的濾波器尺寸的第一CONV層(如ZF網絡中所見)。作為另一個例子,AlexNet 使用11x11的濾波器大小和4的步長。
11.3.3 案例學習 (LeNet / AlexNet / ZFNet / GoogLeNet / VGGNet)
卷積網絡中有幾個有名的體系結構。最常見的是:
- LeNet. 第一個成功應用是由Yann LeCu在1990年代開發的,其中最著名的是用于讀取郵政編碼、數字等的LeNet架構。
- AlexNet. 在計算機視覺中普及卷積網絡的第一件工作是由Alex Krizhevsky、Ilya Sutskever和Geoff Hinton開發的AlexNet。AlexNet在2012年被送出到ImageNet ILSVRC競賽中,并且顯著優于第二名(16%的top5錯誤率,第二名是26%的top5錯誤率)。該網絡具有與LeNet非常相似的體系結構,但是更深、更大,并且具有彼此疊加的卷積層(以前通常隻有一個CONV層緊接着一個POOL層)。
- ZF Net. ILSVRC 2013年的赢家是來自Matthew Zeiler和Rob Fergus的卷積網絡。它被稱為 ZFNet (Zever和FrgUs網絡的簡稱)。它改進了AlexNet,調整了體系結構超參數,特别是通過擴充中間卷積層的大小并使第一層的步幅和濾波器大小更小。
- GoogLeNet. ILSVRC 2014年赢家是來自谷歌的 Szegedy 等人的卷積網絡。它的主要貢獻是開發了一個初始子產品,大大減少了網絡中的參數數量(4M,而AlexNet有60M)。此外,還使用平均彙聚來代替ConvNet頂部的全連接配接層,進而消除了大量似乎無關緊要的參數。GoogLeNet中還有幾個後續版本,最新的版本是 Inception-v4。
- VGGNet. ILVRC 2014中的亞軍是來自Karen Simonyan和Andrew Zisserman的網絡,後來稱為 VGGNet。它的主要貢獻在于表明了網絡的深度是良好性能的關鍵部件。它們最後的最佳網絡包含16個CONV/FC層,并且吸引人的是,具有極其同質的架構,從頭到尾隻執行3x3卷積和2x2池。他們的預訓練模型适用于Caffe中的即插即用。VGNET的缺點是評估更昂貴和使用更多的記憶體和參數(140M)。這些參數中的大多數在第一個完全連接配接的層中,并且自從發現這些FC層可以在不降低性能的情況下被去除,進而顯著地減少了參數的數量。
- ResNet. 由 何恺明等人開發的殘差網絡。是ILVRC 2015的獲勝者。它具有特殊的跳躍連接配接和大量使用批處理歸一化。該架構在網絡的末端也沒有使用完全連接配接的層。讀者可以參考何恺明的介紹(視訊、PPT)以及最近在Torch中再現這些網絡的一些實驗。ResNets是目前為止最先進的卷積神經網絡模型,并且是在實踐中使用ConvNets的預設選擇(截至2016年5月10日)。何開明等最近的工作是對原始結構做一些優化,可以看論文Identity Mappings in Deep Residual Networks(2016年3月出版)。
VGGNet 的細節。讓我們更詳細地分解VGGNET,作為一個案例研究。整個VGGNet由CONV層和POOL層組成,CONV層用步長1和零填充為1,3x3的卷積核,POOL層用步長2執行2x2 最大值彙聚(沒有零填充)。可以寫出處理過程中每一步資料體尺寸的變化,然後對資料尺寸和整體權重的數量進行檢視:
INPUT: [224x224x3] memory: 224*224*3=150K weights: 0
CONV3-64: [224x224x64] memory: 224*224*64=3.2M weights: (3*3*3)*64 = 1,728
CONV3-64: [224x224x64] memory: 224*224*64=3.2M weights: (3*3*64)*64 = 36,864
POOL2: [112x112x64] memory: 112*112*64=800K weights: 0
CONV3-128: [112x112x128] memory: 112*112*128=1.6M weights: (3*3*64)*128 = 73,728
CONV3-128: [112x112x128] memory: 112*112*128=1.6M weights: (3*3*128)*128 = 147,456
POOL2: [56x56x128] memory: 56*56*128=400K weights: 0
CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*128)*256 = 294,912
CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*256)*256 = 589,824
CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*256)*256 = 589,824
POOL2: [28x28x256] memory: 28*28*256=200K weights: 0
CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*256)*512 = 1,179,648
CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*512)*512 = 2,359,296
CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*512)*512 = 2,359,296
POOL2: [14x14x512] memory: 14*14*512=100K weights: 0
CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296
CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296
CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296
POOL2: [7x7x512] memory: 7*7*512=25K weights: 0
FC: [1x1x4096] memory: 4096 weights: 7*7*512*4096 = 102,760,448
FC: [1x1x4096] memory: 4096 weights: 4096*4096 = 16,777,216
FC: [1x1x1000] memory: 1000 weights: 4096*1000 = 4,096,000
TOTAL memory: 24M * 4 bytes ~= 93MB / image (only forward! ~*2 for bwd)
TOTAL params: 138M parameters
通常,卷積網絡的大部分記憶體(以及計算時間)都用在早期CONV層中,并且大部分參數都在最後的FC層中。在這個例子中,全部參數有140M,但第一個全連接配接層就包含了100M的參數。
11.3.4 計算考量
建構ConvNet 架構時要注意的最大瓶頸是記憶體瓶頸。許多現代GPU的記憶體限制為3/4/6GB,最好的GPU記憶體約為12GB。要注意三種記憶體占用來源:
- 來源于中間資料體尺寸::卷積神經網絡中的每一層中都有激活資料體的原始數值,以及損失函數對它們的梯度(和激活資料體尺寸一緻)。通常,大部分激活資料都是在網絡中靠前的層中(比如第一個卷積層)。在訓練時,這些資料需要放在記憶體中,因為反向傳播的時候還會用到。但是在測試時可以聰明點:讓網絡在測試運作時候每層都隻存儲目前的激活資料,然後丢棄前面層的激活資料,這樣就能減少巨大的激活資料量。
- 來自參數尺寸:即整個網絡的參數的數量,在反向傳播時它們的梯度值,以及使用momentum、Adagrad或RMSProp等方法進行最優化時每一步計算的緩存。是以,存儲參數向量的記憶體通常需要在參數向量的容量基礎上乘以3或者更多。
- ConvNet的實作還必須維護零散記憶體,例如圖像資料批量、擴充的資料等。
一旦粗略估計了值的總數(對于激活資料體、梯度和各種零散資料),這個數字應該轉換為GB的大小。取值的數量,乘以4以獲得原始的位元組數量(因為每個浮點數是4位元組,或者可能乘以8以獲得雙精度),然後多次除以1024以獲得KB、MB和最終GB的記憶體量。如果您的網絡不适合,一個常見的“使它适合”的啟發式方法是減少批處理大小,因為大多數記憶體通常被激活資料體所消耗。
11.4延伸閱讀
- Soumith benchmarks for CONV performance
- ConvNetJS CIFAR-10 demo 允許您調試ConvNet 架構,在浏覽器中實時檢視結果和計算
- Caffe, 最流行的卷積神經網絡庫之一
- State of the art ResNets in Torch7
斯坦福大學計算機視圖課程,青星大學 翻譯整理
1、資料驅動的圖像分類方法
2、最近鄰分類器
3、k - 最近鄰分類器及使用驗證集取得超參數
4、線性分類: SVM, Softmax
5、優化方法:随機梯度下降法
6、反向傳播
7、神經網絡一: 建立網絡架構
8、神經網絡二:設定資料和損失
9、神經網絡 三:學習與評價
10、神經網絡案例學習
11、卷積神經網絡:結構、卷積/彙集層
12、了解與可視化卷積神經網絡
13、傳承學習與卷積神經網絡調諧
原文位址 http://cs231n.github.io/