(原文:http://www.moonshile.com/post/juan-ji-shen-jing-wang-luo-quan-mian-jie-xi)
卷積神經網絡全面解析
最近仔細學習了一下卷積神經網絡(CNN,Convolutional Neural Network),發現各處資料都不是很全面,經過艱苦努力終於弄清楚了。爲了以後備查,以及傳播知識,決定記錄下來。本文將極力避免廢話,重點聚焦在推導過程上,爲打算從零開始的孩紙說清楚“爲什麼”。
另外,因本人才疏學淺(是真的才疏學淺,不是謙虛),肯定會有很多謬誤,歡迎大家指出!
卷積神經網絡(CNN)概述
- 由來:神經元網絡的直接升級版
- 相關:Yann LeCun和他的LeNet
- 影響:在圖像、語音領域不斷突破,復興了神經元網絡並進入“深度學習”時代
卷積神經網絡沿用了普通的神經元網絡即多層感知器的結構,是一個前饋網絡。以應用於圖像領域的CNN爲例,大體結構如圖1。
很明顯,這個典型的結構分爲四個大層次
- 輸入圖像I。爲了減小複雜度,一般使用灰度圖像。當然,也可以使用RGB彩色圖像,此時輸入圖像有三張,分別爲RGB分量。輸入圖像一般需要歸一化,如果使用sigmoid激活函數,則歸一化到[0, 1],如果使用tanh激活函數,則歸一化到[-1, 1]。
- 多個卷積(C)-下采樣(S)層。將上一層的輸出與本層權重W做卷積得到各個C層,然後下采樣得到各個S層。怎麼做以及爲什麼,下面會具體分析。這些層的輸出稱爲Feature Map。
- 光柵化(X)。是爲了與傳統的多層感知器全連接。即將上一層的所有Feature Map的每個像素依次展開,排成一列。
- 傳統的多層感知器(N&O)。最後的分類器一般使用Softmax,如果是二分類,當然也可以使用LR。
接下來,就開始深入探索這個結構吧!
從多層感知器(MLP)說起
卷積神經網絡來源於普通的神經元網絡。要了解箇中淵源,就要先了解神經元網絡的機制以及缺點。典型的神經元網絡就是多層感知器。
摘要:本節主要內容爲多層感知器(MLP,Multi-Layer Perceptron)的原理、權重更新公式的推導。熟悉這一部分的童鞋可以直接跳過了~但是,一定一定要注意,本節難度比較大,所以不熟悉的童鞋一定一定要認真看看!如果對推導過程沒興趣,可直接在本節最後看結論。
感知器
感知器(Perceptron)是建立模型
其中激活函數 act 可以使用{sign, sigmoid, tanh}之一。
- 激活函數使用符號函數 sign ,可求解損失函數最小化問題,通過梯度下降確定參數
- 激活函數使用 sigmoid (或者 tanh ),則分類器事實上成爲Logistic Regression(個人理解,請指正),可通過梯度上升極大化似然函數,或者梯度下降極小化損失函數,來確定參數
- 如果需要多分類,則事實上成爲Softmax Regression
- 如要需要分離超平面恰好位於正例和負例的正中央,則成爲支持向量機(SVM)。
感知器比較簡單,資料也比較多,就不再詳述。
多層感知器
感知器存在的問題是,對線性可分數據工作良好,如果設定迭代次數上限,則也能一定程度上處理近似線性可分數據。但是對於非線性可分的數據,比如最簡單的異或問題,感知器就無能爲力了。這時候就需要引入多層感知器這個大殺器。
多層感知器的思路是,儘管原始數據是非線性可分的,但是可以通過某種方法將其映射到一個線性可分的高維空間中,從而使用線性分類器完成分類。圖1中,從X到O這幾層,正展示了多層感知器的一個典型結構,即輸入層-隱層-輸出層。
輸入層-隱層
是一個全連接的網絡,即每個輸入節點都連接到所有的隱層節點上。更詳細地說,可以把輸入層視爲一個向量
也就是每個隱層節點都相當於一個感知器。每個隱層節點產生一個輸出,那麼隱層所有節點的輸出就成爲一個向量,即
若輸入層有
隱層-輸出層
可以視爲級聯在隱層上的一個感知器。若爲二分類,則常用Logistic Regression;若爲多分類,則常用Softmax Regression。
Back Propagation
搞清楚了模型的結構,接下來就需要通過某種方法來估計參數了。對於一般的問題,可以通過求解損失函數極小化問題來進行參數估計。但是對於多層感知器中的隱層,因爲無法直接得到其輸出值,當然不能夠直接使用到其損失了。這時,就需要將損失從頂層反向傳播(Back Propagate)到隱層,來完成參數估計的目標。
首先,約定標量爲普通小寫字母,向量爲加粗小寫字母,矩陣爲加粗大寫字母;再約定以下記號:
- 輸入樣本爲
x ,其標籤爲t - 對某個層
Q ,其輸出爲oQ ,其第j 個節點的輸出爲o(j)Q ,其每個節點的輸入均爲上一層P 的輸出oP ;層Q 的權重爲矩陣ΘQ ,連接層P 的第i 個節點與層Q 的第j 個節點的權重爲θ(ji)Q - 對輸出層
Y ,設其輸出爲oY , 其第y 個節點的輸出爲o(y)Y
現在可以定義損失函數
其中,
上邊兩個式子的等號右邊部有三個導數比較容易確定
然後再看剩下的比較複雜的一個偏導數。考慮層
令
則對每個隱層
考慮到輸出層,有
故有
綜合以上各式,有梯度結果
本來到這裏應該就結束了,不過同正向的時候一樣,爲了計算方便,我們依然希望能夠以矩陣或者向量的方式來表達。結論在這裏:
假設有層
其中,運算
最後,補充幾個常用的激活函數的導數結果,推導很簡單,從略。
存在的問題
多層感知器存在的最大的問題就是,它是一個全連接的網絡,因此在輸入比較大的時候,權值會特別多。比如一個有1000個節點的隱層,連接到一個1000×1000的圖像上,那麼就需要 10^9 個權值參數(外加1000個偏置參數)!這個問題,一方面限制了每層能夠容納的最大神經元數目,另一方面也限制了多層感知器的層數即深度。
多層感知器的另一個問題是梯度發散。 (這個問題的具體原因還沒有完全弄清楚,求指教!) 一般情況下,我們需要把輸入歸一化,而每個神經元的輸出在激活函數的作用下也是歸一化的;另外,有效的參數其絕對值也一般是小於1的;這樣,在BP過程中,多個小於1的數連乘,得到的會是更小的值。也就是說,在深度增加的情況下,從後傳播到前邊的殘差會越來越小,甚至對更新權值起不到幫助,從而失去訓練效果,使得前邊層的參數趨於隨機化(補充一下,其實隨機參數也是能一定程度上捕捉到圖像邊緣的)。
感謝shwley提供的幫助~
因爲這些問題,神經元網絡在很長一段時間內都被冷落了。
從MLP到CNN
卷積神經網絡的名字怪嚇人,實際理解起來也挺嚇人的。哈哈,其實只要看明白了多層感知器的推導過程,理解卷積神經網絡就差不多可以信手拈來了。
摘要:首先解釋卷積神經網絡爲什麼會“長”成現在這般模樣。然後詳細推導了卷積神經網絡的預測過程和參數估計方法。
CNN的前世今生
既然多層感知器存在問題,那麼卷積神經網絡的出現,就是爲了解決它的問題。卷積神經網絡的核心出發點有三個。
- 局部感受野。形象地說,就是模仿你的眼睛,想想看,你在看東西的時候,目光是聚焦在一個相對很小的局部的吧?嚴格一些說,普通的多層感知器中,隱層節點會全連接到一個圖像的每個像素點上,而在卷積神經網絡中,每個隱層節點只連接到圖像某個足夠小局部的像素點上,從而大大減少需要訓練的權值參數。舉個栗子,依舊是1000×1000的圖像,使用10×10的感受野,那麼每個神經元只需要100個權值參數;不幸的是,由於需要將輸入圖像掃描一遍,共需要991×991個神經元!參數數目減少了一個數量級,不過還是太多。
- 權值共享。形象地說,就如同你的某個神經中樞中的神經細胞,它們的結構、功能是相同的,甚至是可以互相替代的。也就是,在卷積神經網中,同一個卷積核內,所有的神經元的權值是相同的,從而大大減少需要訓練的參數。繼續上一個栗子,雖然需要991×991個神經元,但是它們的權值是共享的呀,所以還是只需要100個權值參數,以及1個偏置參數。從MLP的 10^9 到這裏的100,就是這麼狠!作爲補充,在CNN中的每個隱藏,一般會有多個卷積核。
- 池化。形象地說,你先隨便看向遠方,然後閉上眼睛,你仍然記得看到了些什麼,但是你能完全回憶起你剛剛看到的每一個細節嗎?同樣,在卷積神經網絡中,沒有必要一定就要對原圖像做處理,而是可以使用某種“壓縮”方法,這就是池化,也就是每次將原圖像卷積後,都通過一個下采樣的過程,來減小圖像的規模。以最大池化(Max Pooling)爲例,1000×1000的圖像經過10×10的卷積核卷積後,得到的是991×991的特徵圖,然後使用2×2的池化規模,即每4個點組成的小方塊中,取最大的一個作爲輸出,最終得到的是496×496大小的特徵圖。
現在來看,需要訓練參數過多的問題已經完美解決。
而梯度發散的問題,因爲還不清楚具體緣由,依然留待討論。關於梯度發散,因爲多個神經元共享權值,因此它們也會對同一個權值進行修正,積少成多,積少成多,積少成多,從而一定程度上解決梯度發散的問題!
下面我們來揭開卷積神經網絡中“卷積”一詞的神祕面紗。
CNN的預測過程
回到開頭的圖1,卷積神經網絡的預測過程主要有四種操作:卷積、下采樣、光柵化、多層感知器預測。
卷積
先拋開卷積這個概念不管。爲簡便起見,考慮一個大小爲5×5的圖像,和一個3×3的卷積核。這裏的卷積核共有9個參數,就記爲
圖2的上方是第一個神經元的輸出,下方是第二個神經元的輸出。每個神經元的運算依舊是
需要注意的是,平時我們在運算時,習慣使用
現在我們回憶一下離散卷積運算。假設有二維離散函數
現在發現了吧!上面例子中的9個神經元均完成輸出後,實際上等價於圖像和卷積核的卷積操作!這就是“卷積神經網絡”名稱的由來,也是爲什麼在神經元運算時使用
如果你足夠細心,就會發現其實上述例子中的運算並不完全符合二維卷積的定義。實際上,我們需要用到的卷積操作有兩種模式:
- valid模式,用
∗v 表示。即上邊例子中的運算。在這種模式下,卷積只發生在被卷積的函數的定義域“內部”。一個m×n 的矩陣被一個p×q 的矩陣卷積(m≥p,n≥q ),得到的是一個(m−p+1)×(n−q+1) 的矩陣。 - full模式,用
∗f 表示。這種模式纔是上邊二維卷積的定義。一個m×n 的矩陣被一個p×q 的矩陣卷積,得到的是一個(m+p−1)×(n+q−1) 的矩陣。
現在總結一下卷積過程。如果卷積層
下采樣
下采樣,即池化,目的是減小特徵圖,池化規模一般爲2×2。常用的池化方法有:
- 最大池化(Max Pooling)。取4個點的最大值。這是最常用的池化方法。
- 均值池化(Mean Pooling)。取4個點的均值。
- 高斯池化。借鑑高斯模糊的方法。不常用。具體過程不是很清楚。。。
- 可訓練池化。訓練函數
f ,接受4個點爲輸入,出入1個點。不常用。
由於特徵圖的變長不一定是2的倍數,所以在邊緣處理上也有兩種方案:
- 忽略邊緣。即將多出來的邊緣直接省去。
- 保留邊緣。即將特徵圖的變長用0填充爲2的倍數,然後再池化。一般使用這種方式。
對神經中樞
光柵化
圖像經過池化-下采樣後,得到的是一系列的特徵圖,而多層感知器接受的輸入是一個向量。因此需要將這些特徵圖中的像素依次取出,排列成一個向量。具體說,對特徵圖
多層感知器預測
將光柵化後的向量連接到多層感知器即可。
CNN的參數估計
卷積神經網絡的參數估計依舊使用Back Propagation的方法,不過需要針對卷積神經網絡的特點進行一些修改。我們從高層到底層,逐層進行分析。
多層感知器層
使用多層感知器的參數估計方法,得到其最低的一個隱層
光柵化層
從上一層傳過來的殘差爲
重新整理成爲一系列的矩陣即可,若上一層
池化層
對應池化過程中常用的兩種池化方案,這裏反傳殘差的時候也有兩種上採樣方案:
- 最大池化:將1個點的殘差直接拷貝到4個點上。
- 均值池化:將1個點的殘差平均到4個點上。
即傳播到卷積層的殘差
卷積層
卷積層有參數,所以卷積層的反傳過程有兩個任務,一是更新權值,另一是反傳殘差。先看更新權值,即梯度的推導。
如圖三上方,先考慮卷積層的某個“神經中樞”中的第一個神經元。根據多層感知器的梯度公式
那麼在圖三上方的例子中,有
考慮到其他的神經元,每次更新的都是這四個權值,因此實際上等價於一次更新這些偏導數的和。如果僅考慮對
- 在計算對
θ11 的偏導數時,淡藍色區域和灰色區域的對應位置做運算,但是在卷積運算中,這些位置應該是旋轉過來的! θ11 在Θ 矩陣的左上角,而淡藍色區域在右下角,同樣是旋轉過的!
因此,對卷積層
其中,
下面討論殘差反傳的問題。
如圖4,考慮淡藍色像素點影響到的神經元,在這個例子中,受影響的神經元有4個,他們分別以某個權值與淡藍色像素運算後影響到對應位置的輸出。再結合多層感知器的殘差傳播公式,不難發現這裏又是一個卷積過程!同樣需要注意的是,正如圖4中的數字標號,這裏的卷積是旋轉過的;另外,這裏用的卷積模式是full。
如果前邊的池化層
最後一公里:Softmax
前邊我有意忽略了對Softmax的討論,在這裏補上。因爲Softmax的資料已經非常多了,所以這裏不再詳細討論。具體可以參考這篇文章。
需要補充說明的是,不難發現,Softmax的梯度公式與多層感知器的BP過程是兼容的;另外,實現Softmax的時候,如果需要分爲
CNN的實現
我建立了一個Github的repo,目前內容還是空的,近期會逐漸上傳。
思路
以層爲單位,分別實現卷積層、池化層、光柵化層、MLP隱層、Softmax層這五個層的類。其中每個類都有output和backpropagate這兩個方法。
另外,還需要一系列的輔助方法,包括:conv2d(二維離散卷積,valid和full模式),downsample(池化中需要的下采樣,兩種邊界模式),upsample(池化中的上採樣),以及dsigmoid和dtanh等。
其他
還需要考慮的是可擴展性和性能優化,這些以後再談~