卷積神經網絡初探
將神經網絡應用于大圖像時,輸入可能有上百萬個維度,如果輸入層和隱含層進行“全連接”,需要訓練的參數將會非常多。如果構建一個“部分聯通”網絡,每個隱含單元僅僅只能連接輸入單元的一部分,參數數量會顯著下降。卷積神經網絡就是基于這個原理而構建的。
前言
目前為止我已經完整地學完了三個機器學習教程:包括“Stanford CS229”,"Machine Learning on Coursrea" 和 "Stanford UFLDL",卷積神經網絡是其中最抽象的概念。
維基百科對卷積的數學定義為:
由于卷積常用與信號處理,很多人基于“輸入->系統->響應”這一模型來解釋卷積的物理意義,這里轉載一個非常通俗的版本:
比如說你的老板命令你干活,你卻到樓下打臺球去了,后來被老板發現,他 非常氣憤,扇了你一巴掌(注意,這就是輸入信號,脈沖),于是你的臉上會漸漸地鼓起來一個包,你的臉就是一個系統,而鼓起來的包就是你的臉對巴掌的響應, 好,這樣就和信號系統建立起來意義對應的聯系。下面還需要一些假設來保證論證的嚴謹:假定你的臉是線性時不變系統,也就是說,無論什么時候老板打你一巴 掌,打在你臉的同一位置,你的臉上總是會在相同的時間間隔內鼓起來一個相同高度的包,并且假定以鼓起來的包的大小作為系統輸出。好了,下面可以進入核心內 容——卷積了!
如果你每天都到地下去打臺球,那么老板每天都要扇你一巴掌,不過當老板打你一巴掌后,你5分鐘就消腫了,所以時間長了,你甚至就適應這種生活 了……如果有一天,老板忍無可忍,以0.5秒的間隔開始不間斷的扇你的過程,這樣問題就來了,第一次扇你鼓起來的包還沒消腫,第二個巴掌就來了,你臉上的 包就可能鼓起來兩倍高,老板不斷扇你,脈沖不斷作用在你臉上,效果不斷疊加了,這樣這些效果就可以求和了,結果就是你臉上的包的高度隨時間變化的一個函數 了(注意理解);如果老板再狠一點,頻率越來越高,以至于你都辨別不清時間間隔了,那么,求和就變成積分了。可以這樣理解,在這個過程中的某一固定的時 刻,你的臉上的包的鼓起程度和什么有關呢?和之前每次打你都有關!但是各次的貢獻是不一樣的,越早打的巴掌,貢獻越小,所以這就是說,某一時刻的輸出是之 前很多次輸入乘以各自的衰減系數之后的疊加而形成某一點的輸出,然后再把不同時刻的輸出點放在一起,形成一個函數,這就是卷積,卷積之后的函數就是你臉上 的包的大小隨時間變化的函數。本來你的包幾分鐘就可以消腫,可是如果連續打,幾個小時也消不了腫了,這難道不是一種平滑過程么?反映到劍橋大學的公式 上,f(a)就是第a個巴掌,g(x-a)就是第a個巴掌在x時刻的作用程度,乘起來再疊加就ok了,大家說是不是這個道理呢?我想這個例子已經非常形象 了,你對卷積有了更加具體深刻的了解了嗎?
</blockquote>
這是一些嘗試解釋卷積的文章:
http://www.guokr.com/post/342476/
http://blog.csdn.net/yeeman/article/details/6325693
https://zh.wikipedia.org/wiki/%E5%8D%B7%E7%A7%AF
而在圖像處理中通常使用離散形式的卷積,在下一節中介紹。
卷積特征提取(convolution)
卷積特征提取的過程
假設有一個稀疏自編碼器 SAE,訓練使用的是 3×3 的小圖。將 SAE 用作深度網絡的隱藏層時,它依然只接受 3×3 的數據作為輸入,且假設這個隱藏層有 k 個單元(每個單元也被稱為一個卷積核 - Convolution Kernel,由對應的權值向量 W 和 b 來體現)。
每個隱藏單元的輸入是用自己的權值向量 W 與 3×3 的小圖做內積,再與截距項相加得到的:
![]()
假如深度網絡的輸入是 5×5 的大圖,SAE 要從中提取特征,必須將 5×5 的大圖分解成若干 3×3 的小圖并分別提取它們的特征。分解方法就是:從大圖的 (1, 1)、(1, 2)、(1, 3)、... 、(3, 3)等 9 個點開始分別作為小圖的左上角起點,依次截取 9 張帶有重合區域的小圖,然后分別提取這 9 張小圖的特征:
![]()
所以,每個隱藏單元將有 9 個輸入,不同于之前的 1 個。然后將所有輸入分別導入激活函數計算相應的輸出,卷積特征提取的工作就完成了。
對于本例,隱藏層所提取的特征共有 9×k 個;更一般化地,如果大圖尺寸是 r×c,小圖尺寸是 a×b,那么所提取特征的個數為:
![]()
卷積特征提取的原理
卷積特征提取利用了自然圖像的統計平穩性(Stationary):
自然圖像有其固有特性,也就是說,圖像的一部分的統計特性與其他部分是一樣的。這也意味著我們在這一部分學習的特征也能用在另一部分上,所以對于這個圖像上的所有位置,我們都能使用同樣的學習特征。
</blockquote>
池化(Pooling)
池化過程
在完成卷積特征提取之后,對于每一個隱藏單元,它都提取到 (r-a+1)×(c-b+1)個特征,把它看做一個矩陣,并在這個矩陣上劃分出幾個不重合的區域,然后在每個區域上計算該區域內特征的均值或最大值,然后用這些均值或最大值參與后續的訓練,這個過程就是【池化】。
![]()
池化的優點
顯著減少了參數數量
</li>池化單元具有平移不變性 (translation invariant)
有一個 12×12 的 feature map (隱藏層的一個單元提取到的卷積特征矩陣),池化區域的大小為 6×6,那么池化后,feature map 的維度變為 2×2。
![]()
假設原 feature map 中灰色元素的值為 1,白色元素的值為 0。如果采用 max pooling,那么池化后左上角窗口的值為 1。如果將圖像向右平移一個像素:
![]()
池化后左上角窗口的值還是 1。如果將圖像縮小:
![]()
池化后左上角窗口的值依然是 1。
通常我們認為圖像經過有限的平移、縮放、旋轉,不應改變其識別結果,這就要求經過平移、縮放、旋轉的圖片所提取的特征與原圖所提取的特征相同或相似,因此分類器才能把它們識別成同一類。
</li> </ol>幾種池化方式
比較主流的池化方式有如下幾種:
一般池化(General Pooling): max pooling 和 average pooling
現在已經知道了 max pooling 與 average pooling 的幾何意義,還有一個問題需要思考:它們分別適用于那些場合?在不同的場合下,它們的表現有什么不一樣?為什么不一樣?
網絡上有人這樣區分 max pooling 和 average pooling:
“average對背景保留更好,max對紋理提取更好”。
限于篇幅以及我的理解還不深,就不展開討論了,如果以后需要,我會深入研究一下。
</li>重疊池化(Overlapping Pooling)
重疊池化的相鄰池化窗口之間會有重疊區域。
</li>空間金字塔池化(Spatial Pyramid Pooling)
空間金字塔池化拓展了卷積神經網絡的實用性,使它能夠以任意尺寸的圖片作為輸入。
</li>下面列出一些研究池化的論文:
http://yann.lecun.com/exdb/publis/pdf/boureau-icml-10.pdf
http://yann.lecun.com/exdb/publis/pdf/boureau-cvpr-10.pdf
http://yann.lecun.com/exdb/publis/pdf/boureau-iccv-11.pdf
http://ais.uni-bonn.de/papers/icann2010_maxpool.pdf
</li> </ol>
匯總
有 m 張彩色自然圖片拿來訓練一個神經網絡,使它能夠對圖片中的物體做分類。訓練過程可以大致分為以下幾步:
從圖片庫中隨機裁剪出相同尺寸的小圖若干張,用來訓練一個稀疏自編碼器 C1;
</li>以 C1 作為第一個卷積層,從原圖中做卷積特征提取;
</li>在 C1 下游添加一個池化層 S1,對 C1 所提取的特征做池化計算;
</li>如果需要提取更加抽象的特征,在 S1 之后添加卷積層 C2,C2 是一個使用 S1 的數據進行訓練的稀疏自編碼器;
</li>在 C2 下游添加一個池化層 S2,如果需要提取進一步抽象的特征,重復添加卷積層與池化層即可;
</li>以最后一個池化層的輸出作為數據訓練分類器。
</li> </ol>
課后作業(Convolution and Pooling)
代碼地址,由于 GIthub 有文件大小限制,所以這次沒有上傳數據文件。
Pooling 的代碼比較簡單,所以這里把計算卷積的代碼詳細注釋后貼出來:
cnnConvolve.m
運行結果: