前言:
本節主要是來簡單介紹下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