Convolutional Neural Networks for Visual Recognition 8
Convolutional Neural Networks (CNNs / ConvNets)
前面做了如此漫長的鋪墊,現在終于來到了課程的重點。Convolutional Neural Networks, 簡稱CNN,與之前介紹的一般的神經網絡類似,CNN同樣是由可以學習的權值與偏移量構成,每一個神經元接收一些輸入,做點積運算加上偏移量,然后選擇性的通過一些非線性函數,整個網絡最終還是表示成一個可導的loss function,網絡的起始端是輸入圖像,網絡的終端是每一類的預測值,通過一個full connected層,最后這些預測值會表示成SVM或者Softmax的loss function,在一般神經網絡里用到的技巧在CNN中都同樣適用。
那么,CNN與普通的神經網絡相比,又有哪些變化呢?CNN的網絡結構可以直接處理圖像,換句話說CNN的輸入就是直接假設為圖像,這一點有助于我們設計出具備某些特性的網絡結構,同時前向傳遞函數可以更加高效地實現,并且將網絡的參數大大減少。
Architecture Overview
前面介紹的普通的神經網絡,我們知道該網絡接收一個輸入,通過一系列的隱含層進行變換,每個隱含層都是由一些神經元組成,每一個神經元都會和前一層的所有神經元連接,這種連接方式稱為 full connected,每一層的神經元的激勵函數都是相互獨立,沒有任何共享。最后一個full connected層稱為輸出層,在分類問題中,它表示每一類的score。
一般來說,普通的神經網絡不能很好地擴展到處理圖像,特別是高維圖像,因為神經元的連接是full connected的方式,導致一般的神經網絡處理大圖像的時候將會引入海量的參數,而這樣很容易造成overfitting。
而CNN,利用了輸入是圖像這一事實,他們用一種更加明智的方法來設計網絡結構,具體說來,不像普通的神經網絡,CNN中的每一層的神經元被排列成一個三維模型:擁有width,height以及depth。這里的depth指的是CNN每一層的縱深,并非指整個CNN結構的縱深。比如,對于CIFAR-10數據庫來說,輸入是一個三維的volume,32×32×3,分別對應width,height和depth,我們將會看到,CNN中,每一層的神經元只跟前一層的部分神經元相連,而沒有full connected,而且最后的輸出層是一個1×1×10的volume,因為最后一層表示每一類的score,CNN通過這種結構,將一個輸入的圖像最后轉化成一個表示每一類score的向量,下圖給出了兩種神經網絡的示意圖:
上圖左邊是一般的神經網絡,這個網絡有兩個隱含層,右邊是CNN,將每一層的神經元排列成一個三維的volume,可以將3D的輸入volume轉化為3D的輸出volume.
Layers used to build ConvNets
上一節已經提到,CNN的每一層都將某種輸入通過某些可導函數轉化為另一種輸出,一般來說,我們主要利用三種類型的layer去構建一個CNN,這三種類型的layer分別是convolutional layer, pooling layer 以及full connected layer,這三種類型的layer通過組合疊加從而組成一個完整的CNN網絡。我們先來看一個簡單的例子,以CIFAR-10數據庫為例,我們要設計一個CNN網絡對CIFRA-10進行分類,那么一個可能的簡單結構是:[INPUT-CONV-RELU-POOL-FC],其中:
INPUT:[32×32×3] 表示輸入層,是圖像的像素值,這種情況下表示圖像是寬為32個像素,高為32個像素,并且有R,G,B三個通道。
CONV: 是卷積層,計算輸入層的局部神經元與連接到CONV層神經元的連接系數的點積,如果假設depth是12的話,那么可能的輸出就是[32×32×12]。
POOL: 這一層主要執行降采樣的功能,可能的輸出為[16×16×12]。
FC: 這一層計算最終的每一類的score,輸出為[1×1×10]。與普通的神經網絡一樣,這一層的神經元與上一層的所有神經元都會連接。
所以,利用這種結構,CNN通過一層一層的傳遞作用,將原始的圖像最后映射到每一類的score。我們可以看到,有些層有參數,有些層沒有參數。特別地,CONV/FC層不僅僅只是通過激勵函數做轉化,而且參數(權值,偏移量)也起到非常重要的作用,另一方面,POOL/RELU 層只是固定的函數在起作用,并沒有涉及到參數,CONV/FC層的參數將通過梯度下降的方法訓練得到,使得訓練樣本的預測值與目標值吻合。
下圖給出了一個典型的CNN結構。
總之,CNN可以總結如下:
1):一個CNN結構是由一系列的執行不同轉化功能的layers組成的,將輸入的原始圖像映射到最后的score。
2):整個網絡結構,只有少數幾類不同功能的layer (CONV/FC/RELU/POOL 是目前比較流行的幾種)。
3):每一層都接收一個3-D的數據體,最后也會輸出一個3-D的數據體。
4):有些層有參數(CONV/FC),有些層沒有(RELU/POOL)。
5):有些層還可能有hyperparameters(CONV/POOL/FC),有些層則沒有(RELU)。
接下來,我們要描述每一類layer的作用,以及相關的參數。
Convolutional Layer
Conv layer是CNN網絡的核心部件,它的輸出可以看成是一個3-D的數據體,CONV 層包含一系列可學的filters,這些filter的尺寸都很小,但是可以擴展到input的整個depth,前向傳遞的時候,filter在輸入圖像上滑動,產生一個2-D的關于filter的激勵映射,filter只會和局部的一些像素(神經元)做點積,所以每一個輸出的神經元可以看成是對輸入層的局部神經元的激勵,我們希望這些filter通過訓練,可以提取某些有用的局部信息。我們接下來探討到更加詳細的細節。
當輸入是高維的變量,比如圖像等,如果采用full connected的連接是不切實際的,相反,我們會采用局部連接的方式,那么每一個局部區域我們稱為receptive field,這種局部連接是針對輸入層的寬,高這兩個維度來說,但是對于第三個維度depth來說,依然是要完全連接,所以我們處理局部空間在寬,高維度與depth這個維度是不一樣的。寬,高維度上,我們采取局部連接,但是對于depth維度,我們采用全連方式。
比如,如果一個輸入圖像的尺寸是[32×32×3],我們定義下一層神經元的receptive field的尺寸是5×5,那么考慮到depth這個維度,最終每一次都有5×5×3=75個神經元與CONV層的一個神經元連接,意味著有5×5×3=75個權值。
再比如,假設現在有一個輸入的數據體是16×16×20,那么如果定義一個receptive field為3×3的連接方法,那么在CONV層的每一個神經元最終連接到上一層神經元的個數是3×3×20=180。
這兩個例子都說明了,在寬,高維度我們采用局部連接的方式,而在depth維度,我們會全部連接。下面給出了一個簡單的示意圖:
前面我們介紹了CONV層的神經元與前一層的連接方式,但是CONV層本身的神經元如何排列,而且其尺寸如何,我們還沒有討論,事實上,CONV層本身的神經元如何排列以及CONV層的尺寸由三個因素決定:depth,stride,zero padding。
首先,depth決定了CONV層中有多少神經元可以與前一層相同的神經元相連,這個類似普通的神經網絡,在普通的神經網絡中,我們知道每一個神經元都與上一層的所有神經元相連,所有每一層的所有神經元都是與上一層相同的神經元相連。我們將會看到,所有這些神經元將通過學習從而對輸入的不同特征產生應激作用,比如,如果第一個CONV層接收的是原始輸入圖像,那么沿著depth維度排列的神經元(注意:這些神經元連接的輸入層的神經元都相同)可能對不同的特性(比如邊界,顏色,斑塊)等產生激勵。我們將這些連接到輸入層同一區域的神經元稱為一個depth volume。
接下來,我們必須指定stride,這個決定了我們如何在CONV層排列depth volume,如果我們指定stride為1,那么depth volume的排列將會非常緊湊,意味著隔一個神經元就會有一個depth volume,這樣會產生比較大的重疊,而且輸出的尺寸也會很大,如果我們增大stride,可以減少重疊,并且可以減少輸出的尺寸。
zero padding就是為了控制輸出的尺寸,對輸入圖像的邊緣進行補零操作,因為卷積可能使輸出圖像的尺寸減少,有的時候為了得到與輸入一樣的尺寸,我們可以在做卷積之前先對輸入圖像的邊緣補零,即先增大輸入圖像的尺寸,這樣可以使得最終的卷積結果與補零前的輸入圖像的尺寸一致。
我們可以看到,輸出層有一個depth,一個spatial size,depth可以指定,spatial size與輸入層的size(W),receptive field的size,即filter的size(F),我們定義的stride(S),還有邊緣的zero padding的size(P)有關,可以看成是這些變量的一個函數,我們可以證明最終輸出的spatial size為:(W?F+2P)/S+1。
我們可以看一個例子,如果輸入圖像的尺寸為[227×227×3],我們設計一個CONV層,每個神經元的receptive field為11,即F=11,stride為S=4,沒有zero padding,那么輸出的CONV層的spatial size為(227?11)/4+1=55,如果我們定義CONV層的depth為96,那么這個CONV層的最終尺寸為55×55×96, 從上面這個定義看出,這55×55×96個神經元中的每一個都和輸入圖像的一個11×11×3的局部區域相連,并且每一個depth volume中含有96個神經元,這96個神經元與輸入圖像的同一個11×11×3的局部區域相連,它們唯一的區別在于連接權值的不同。
繼續看上面的例子,我們知道CONV層有55×55×96=29040個神經元,每個神經元都與輸入層的11×11×3個神經元連接,那么CONV層的每一個神經元都將有11×11×3=363個權值外加一個bias,那么最終的系數將會達到29040×(363+1)=105,705,600。很明顯,這個系數量太大了。
我們可以利用一個合理的假設來大大系數的數量,我們將CONV層看成一個depth volume,比如上面這個例子,CONV層是一個55×55×96的volume,其depth為96,那么每一個55×55的排列可以看成是一個slice,那么這個CONV層有96個slices,每一個slice的尺寸都為55×55,我們讓每一個slice里的神經元都共享一組同樣的連接系數,或者說同樣的filter,那么意味著每一個slice都只有11×11×3個不同的系數,整個CONV層將只有11×11×3×96=34848,如果每個slice的神經元也共享同樣的bias,那么最終的系數為34848+96=34944個,我們看到,通過這種假設,系數的總量大大減少了,每一個slice里的55×55個神經元都共享同樣的連接系數,實際運算中,所有的神經元都會計算相應的梯度,但是這些梯度最終會相加,在每一個slice中只做一次更新。
如果每一個slice里的神經元都共享同樣的連接系數,那么實際運算的時候可以利用卷積運算,其實這也是這個網絡名稱的由來,卷積在其中發揮重要的作用,所有我們有的時候把這些系數稱為filter或者kernel,卷積的結果就是activation map,每一個activation map疊加,最后形成一個55×55×96的volume。
總結一下CONV的特點:
接收一個尺寸為W1×H1×D1的volume。
定義一些相關的hyperparameter,比如filter的個數K,filter的size或者稱為receptive fieldF,stride S以及zero padding P,通過運算可以得到一個如下的
尺寸為:W2×H2×D2的depth volume,其中,W2=(W1?F+2P)/S+1,H2=(H1?F+2P)/S+1,D2=K,通過參數共享,每個slice
會有一個F?F?D1的kernel,一共有K個kernel,所以一共有系數(F?F?D1)?K,在輸出的數據體中,每一個slice的尺寸都是W2×H2,一共有D2=K個slice。
CONV層的backpropagation 同樣是卷積運算,這個具體的細節留到后面詳細探討。
Pooling Layer
一般來說,在兩個CONV layer之間,會插入一共pooling layer,pooling layer的作用一個是減少輸入的空間尺寸,從而可以降低參數的數量及運算量,同時也可以控制overfitting。Pooling layer與上一層的每一個slice是一一對應的,沒有相互交叉。最常見的pooling 運算是采用max 操作,在2×2的一個空間區域內,以stride為2進行將采樣,pooling操作只在寬,高維度上進行,所以不會改變depth,輸出與輸入的depth將會一樣。總結來說,Pooling layer:
接收一個尺寸為W1×H1×D1的volume。定義一些相關的hyperparameter,filter的size或者稱為receptive fieldF,stride S,通過運算可以得到一個如下的尺寸為:W2×H2×D2的depth volume,其中,W2=(W1?F)/S+1,H2=(H1?F)/S+1,D2=D1,pooling layer不會又系數,也不會使用zero padding。下圖給了一個pooling的示意圖:
max pooling 的backpropagation,簡單來說就是只對輸入的最大值進行梯度運算,所以每次前向運算的時候,最好可以將最大值的位置記錄下來,這樣每次backward的時候就可以方便運算。
Full-connected Layer
FC layer就像普通神經網絡里的隱含層一樣,FC layer中的每一個神經元與上一層所有的神經元都會連接(full connected),涉及到的運算也和普通的神經網絡一樣。值得注意的一點是,FC與CONV layer之間的區別僅在于CONV layer里的神經元只和上一層的局部神經元相連,但是兩者的運算模式是一樣的,都是做點積,因此在FC與CONV之間存在相互轉換的可能。
對于CONV layer,如果我們從FC的角度來看,相當于乘了一個非常大的稀疏矩陣(大部分系數為0,因為只有局部神經元的連接是有效的),而且這些非0系數在某些block中是相等的(系數共享)。反過來,任何FC layer也可以有效地轉換成CONV layer,比如一個神經元個數K=4096的FC layer,接收的輸入是7×7×512,我們可以等同于利用一個CONV層其hyperparameter設定為 F=7, P=0, S=1, K=4096,我們設定filter的spatial size與輸入的spatial size是一樣的,這樣最后會得到一個1×1×4096的輸出。
上面所說的兩種轉換,其中FC 轉換為CONV 在實際運算中非常有用,考慮一個實際的CNN網絡,最原始的輸入為224×224×3的圖像,經過一系列的轉換運算,我們得到了一個尺寸為7×7×512的volume,接下來我們用兩個FC layer,將這個volume轉換為尺寸為4096的volume,最后連接到size為1000的輸出,我們可以將這三個FC layer用CONV layer的運算模式來表示。
將第一個FC layer替換成CONV layer,其filter size 為7,我們可以得到1×1×4096的輸出。將第二個FC layer替換成CONV layer,其filter size 為1,輸出的volume為1×1×4096。同樣,最后一個FC layer用filter size為1的CONV layer替換,最后的輸出為1×1×1000。
上面所說的每一個轉換都涉及到系數矩陣的reshape問題,這種轉換可以讓我們將CNN結構非常有效的在更大的圖像上滑動。比如,如果一個224×224的圖像生成了一個尺寸為7×7×512的volume,從224降到7,一共降了32倍,那么,如果輸入的圖像是384×384,那么我們會生成一個12×12×512的volume,那么我們利用這三層FC layer,轉換成CONV layer,我們最終會得到6×6×1000的輸出,意味著每一類的score不只是一個數,而是一個6×6的數組。
我們可以看到,如果圖像保持不動,而CNN網絡每次以32個像素的stride在圖像上移動,最后得到的結果是一樣的。
一般來說,利用CNN網絡做一次遍歷,得到一個6×6的score,比重復調用CNN結構36次計算其在圖像不同位置之間的score要更加高效,因為這36次調用使用的是同一個網絡結構,共享完全一樣的系數及運算模式。這種實際應用中,是一種提高分類性能的技巧,比如我們將一幅圖先放大,然后再利用CNN結構做遍歷,最后將所有得到的score求平均。
最后一點,如果我們想將CNN網絡以小于32的stride有效地應用在圖像上,可以通過多次前向傳遞運算達到目的。比如,我們想以16個像素的stride遍歷圖像,可以做兩次運算,第一次是直接將CNN網絡在原圖上做遍歷,第二次,先將原圖在寬,高方向分別平移16個像素,然后在平移后的圖像上做遍歷。
ConvNet Architectures
我們已經看到,CNN網絡一般只有幾種類型的layer:CONV,POOL(一般默認為max pooling)以及FC,一般我們也會把RELU單獨列為一層,用來執行非線性運算的操作,我們看看這些layer如何構建一個完整的CNN網絡。
比較常見的模式是先疊加幾層CONV-RELU layer,后面連上POOL layer,這樣將輸入的圖像逐漸減少到一個比較小的尺寸,接來下,就連上Full connected layer,最后的FC layer是輸出,所以一般比較常見的模式如下所示:
INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC
其中*表示重復疊加的意思,而POOL?表示這是可選擇的,而且N>=0,一般N<=3,M>=0,K>=0,通常K<=3,下面是一些常見的CNN網絡結構。
INPUT -> FC,這是最普通的線性分類器,N = M = K = 0.
INPUT -> CONV -> RELU -> FC
INPUT -> [CONV -> RELU -> POOL]*2 -> FC -> RELU -> FC 我們看到CONV layer后面連著Pool layer。
INPUT -> [CONV -> RELU -> CONV -> RELU -> POOL]*3 -> [FC -> RELU]*2 -> FC 我們看到在連接POOL layer之前,已經有兩個CONV layer疊加到一起了。
一般我們會選擇小尺寸的filter,這在實際應用中的效果會更好。一般來說,輸入圖像的尺寸最好是2的冪次方,比如32,64,96,224,384以及512。CONV 層一般用比較小的filter,比如3×3或者5×5,stride一般設為1,為了讓卷積運算之后圖像的尺寸保持不變,有的時候會引入zero padding,zero padding的大小一般為P=(F-1)/2,pool layer執行降采樣的功能,最常見的pool是用max pooling,在一個2×2的區域內,這樣相當于將圖像縮小一半,在設計CNN網絡的時候,對于這些參數要小心設定,要確保每個layer的輸出尺寸與設想的一致。
現在流行的CNN網絡結構都是非常龐大的,比較著名的CNN結構有如下幾個LeNet, AlexNet, ZF Net, Google Net, VGGNet,具體的介紹可以參考課程網站。這里不再詳述。
聲明:lecture notes里的圖片都來源于該課程的網站,只能用于學習,請勿作其它用途,如需轉載,請說明該課程為引用來源。
http://cs231n.stanford.edu/
轉載于:https://www.cnblogs.com/mtcnn/p/9412601.html
總結
以上是生活随笔為你收集整理的Convolutional Neural Networks for Visual Recognition 8的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Installation error:
- 下一篇: Spring的IOC原理