本節主要是來簡單介紹下stacked CNN(深度卷積網絡),有時候針對大圖片進行recognition時,需要用到無監督學習的方法去pre-training(預訓練)stacked CNN的每層網絡,然後用BP算法對整個網絡進行fine-tuning(微調),並且上一層的輸出作爲下一層的輸入。這幾句話說起來很簡單,可是真的這麼容易嗎?對於初學者來說,在實際實現這個流程時並不是那麼順利,因爲這其中要涉及到很多細節問題。這裏不打算細講deep statcked網絡以及covolution,pooling,而只只重點介紹以下一個方面的內容。
首先我們知道,convolution和pooling的優勢爲使網絡結構中所需學習到的參數個數變少,並且學習到的特徵具有一些不變性,比如說平移,旋轉不變性。以二維圖像提取爲例,學習的參數個數變少是因爲不需要用整張圖片的像素來輸入到網絡,而只需學習其中一部分patch。而不變的特性則是由於採用了mean-pooling或者max-pooling等方法。
以經典的LeNet5結構圖爲例:
由上可以看出對於這個網絡,每輸入一張32*32大小的圖片,就輸出一個84維的向量,這個向量即我們提取出的特徵向量。
網絡的C1層是由6張28*28大小的特徵圖構成,其來源是我們用6個5*5大小的patch對32*32大小的輸入圖進行convolution得到,28=32-5+1,其中每次移動步伐爲1個像素。 而到了s2層則變成了6張14*14大小的特徵圖,原因是每次對4個像素(即2*2的)進行pooling得到1個值。這些都很容易理解,在ufldl教程Feature extraction using convolution,Pooling中給出了詳細的解釋。
有人可能會講,C3那16張10*10大小的特徵圖,是將S2層的內容輸入到一個輸入層爲5*5,隱含層爲16的網絡即可。其實這種解釋是錯的,還是沒有說到問題本質。我的答案是:將S2的特徵圖用1個輸入層爲150(=5*5*6,不是5*5)個節點,輸出層爲16個節點的網絡進行convolution。
並且此時, C3層的每個特徵圖並不一定是都與S2層的特徵圖相連接,有可能只與其中的某幾個連接,比如說在LeNet5中,其連接情況如下所示:
其中打X了的表示兩者之間有連接的。取我們學習到的網絡(結構爲150-16)中16個隱含節點種的一個拿來分析,比如拿C3中的第3號特徵圖來說,它與上層網絡S2第3,4,5號特徵圖連接。那麼該第3號特徵圖的值(假設爲H3)是怎麼得到的呢?其過程如下:
首先我們把網絡150-16(以後這樣表示,表面輸入層節點爲150,隱含層節點爲16)中輸入的150個節點分成6個部分,每個部分爲連續的25個節點。取出倒數第3個部分的節點(爲25個),且同時是與隱含層16個節點中的第4(因爲對應的是3號,從0開始計數的)個相連的那25個值,reshape爲5*5大小,用這個5*5大小的特徵patch去convolution S2網絡中的倒數第3個特徵圖,假設得到的結果特徵圖爲h1。
同理,取出網絡150-16中輸入的倒數第2個部分的節點(爲25個),且同時是與隱含層16個節點中的第5個相連的那25個值,reshape爲5*5大小,用這個5*5大小的特徵patch去convolution S2網絡中的倒數第2個特徵圖,假設得到的結果特徵圖爲h2。
繼續,取出網絡150-16中輸入的最後1個部分的節點(爲25個),且同時是與隱含層16個節點中的第5個相連的那25個值,reshape爲5*5大小,用這個5*5大小的特徵patch去convolution S2網絡中的最後1個特徵圖,假設得到的結果特徵圖爲h3。
最後將h1,h2,h3這3個矩陣相加得到新矩陣h,並且對h中每個元素加上一個偏移量b,且通過sigmoid的激發函數,即可得到我們要的特徵圖H3了。
因爲在經典的CNN網絡結構中(比如這裏的LeNet5),是不需要對每層進行pre-traing的。但是在目前的stacked CNN中,爲了加快最終網絡參數尋優的速度,一般都需要用無監督的方法進行預訓練。那麼pre-training從S2到C3的那個150-16網絡權值W時,訓練樣本從哪裏來?