標籤:
Deep learning:三十八(Stacked CNN簡單介紹)
前言:
本節主要是來簡單介紹下stacked CNN(深度卷積網路),起源於本人在構建SAE網路時的一點困惑:見Deep learning:三十六(關於構建深度卷積SAE網路的一點困惑)。因為有時候針對大圖片進行recognition時,需要用到無監督學習的方法去pre-training(預訓練)stacked CNN的每層網路,然後用BP演算法對整個網路進行fine-tuning(微調),並且上一層的輸出作為下一層的輸入。這幾句話說起來很簡單,可是真的這麼容易嗎?對於初學者來說,在實際實現這個流程時並不是那麼順利,因為這其中要涉及到很多細節問題。這裡不打算細講deep statcked網路以及covolution,pooling,這幾部分的內容可以參考前面的博文:Deep learning:十六(deep networks),Deep learning:十七(Linear Decoders,Convolution和Pooling)。而只只重點介紹以下一個方面的內容(具體見後面的解釋)。
基礎知識:
首先需要知道的是,convolution和pooling的優勢為使網路結構中所需學習到的參數個數變得更少,並且學習到的特徵具有一些不變性,比如說平移,旋轉不變性。以2維映像提取為例,學習的參數個數變少是因為不需要用整張圖片的像素來輸入到網路,而只需學習其中一部分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了。
終於把想要講的講完了,LeNet5後面的結構可以類似的去推理。其實發現用文字去描述這個過程好難,如果是面對面交談的話,幾句話就可以搞定。
因為在經典的CNN網路結構中(比如這裡的LeNet5),是不需要對每層進行pre-traing的。但是在目前的stacked CNN中,為了加快最終網路參數尋優的速度,一般都需要用無監督的方法進行預訓練。現在來解決在Deep learning:三十六(關於構建深度卷積SAE網路的一點困惑)中的第1個問題,對應到LeNet5架構中該問題為:pre-training從S2到C3的那個150-16網路權值W時,訓練樣本從哪裡來?
首先,假設我們總共有m張大圖片作為訓練樣本,則S2中共得到6*m張特徵圖,其大小都是14*14,而我們對其進行convolution時使用的5*5大小的,且我們輸入到該網路是150維的,所以肯定需要對這些資料進行sub-sample。因此我們只需對這6*m張圖片進行採樣,每6張特徵圖(S2層的那6張)同時隨機採樣若干個5*5大小(即它們每個的採樣位置是一樣的)的patch, 並將其按照順序res為hape150維,此作為150-16網路的一個訓練樣本,用同樣的方法擷取多個樣本,共同構成該網路的訓練樣本。
這裡給出這幾天在網上搜的一些資料:
首先是LeNet5對應的手寫字型識別的demo,可以參考其網頁:LeNet-5, convolutional neural networks,以及該demo對應的paper:LeCun, Y., et al. (1998). "Gradient-based learning applied to document recognition.",這篇paper內容比較多,只需看其中的單個文字識別那部分。paper中關於LeNet5各層網路的詳細內容可以參考網頁:Deep Learning(深度學習)學習筆記整理系列之(七).
下面這個是用python寫的一個簡單版本的LeNet5,用Theano機器學習庫實現的:Convolutional Neural Networks (LeNet),懂Python的同學可以看下,比較通俗易懂(不懂Python其實也能看懂個大概)。關於stacked CNN的matlab實現可以參考:https://sites.google.com/site/chumerin/projects/mycnn。裡面有源碼和介面。
最後Hition在2012年ImageNet識別時用的演算法paper:Imagenet classification with deep convolutional neural networks. 他還給出了對應的code,基於GPU,c++的:https://code.google.com/p/cuda-convnet/。
總結:
關於Statcked CNN網路pre-training過程中,後續層的訓練樣本來源已經弄清楚了,但是關於最後對整個網路的fine-tuning過程還不是很明白,裡面估計有不少數學公式。
參考資料:
Deep learning:三十六(關於構建深度卷積SAE網路的一點困惑)
Deep learning:十六(deep networks)
Deep learning:十七(Linear Decoders,Convolution和Pooling)
Deep Learning(深度學習)學習筆記整理系列之(七)
Convolutional Neural Networks (LeNet)
https://sites.google.com/site/chumerin/projects/mycnn.
Gradient-based learning applied to document recognition.
Imagenet classification with deep convolutional neural networks.
Feature extraction using convolution
Pooling
Gradient-based learning applied to document recognition(轉載)