Notes on Convolutional Neural Networks


這是Jake Bouvrie在2006年寫的關於CNN的訓練原理,雖然文獻老了點,不過對理解經典CNN的訓練過程還是很有幫助的。該作者是劍橋的研究認知科學的。翻譯如有不對之處,還望告知,我好及時改正,謝謝指正!

Notes on Convolutional Neural Networks

Jake Bouvrie 2006年11月22

1引言

    這個文檔是為了討論CNN的推導和執行步驟的,並加上一些簡單的擴展。因為CNN包含着比權重還多的連接,所以結構本身就相當於實現了一種形式的正則化了。另外CNN本身因為結構的關系,也具有某種程度上的平移不變性。這種特別的NN可以被認為是以數據驅動的形式在輸入中可以自動學習過濾器來自動的提取特征。我們這里提出的推導是具體指2D數據和卷積的,但是也可以無障礙擴展到任意維度上。

     我們首先以在全連接網絡上說明經典的Bp是如何工作的,然后介紹了在2DCNN中BP是如何在過濾器和子采樣層上進行權值更新的。通過這些論述,我們強調了模型實際執行的高效的重要性,並給出一小段MATLAB代碼來輔助說明這些式子。當然在CNN上也不能過度的誇大高效代碼的重要性(畢竟結構放在那里了,就是很慢的)。接下來就是討論關於如何將前層學到的特征圖自動組合的主題,並具體的考慮學習特征圖的稀疏組合問題。

    免責聲明:這個粗糙的筆記可能包含錯誤,各位看官且看且謹慎。(作者的免責聲明)。

2用BP訓練全連接網絡

     在許多文獻中,可以發現經典的CNN是由卷積和子采樣操作互相交替組成的,然后在最后加上一個普通的多層網絡的結構:最后幾層(最靠經輸出層的部分)是全連接1D層。當准備好將最后的2D特征圖作為輸入饋送到這個全連接1D網絡的時候,也能很方便的將所有的輸出圖中表現的特征連接到一個長輸入向量中,並往回使用BP進行訓練。這個標准的BP算法將會在具體介紹CNN的情況之前介紹(【1】中有更詳細的介紹)。

2.1前向傳播

        在推導過程中,我們的損失函數采用的是誤差平方和損失函數。對於一個有着 c 個類別和 N 個訓練樣本的多類問題,這個損失函數形式如下:

  (公式1)

這里是第 n 個樣本相對應的目標(標簽)的第 k 維,是由模型的第 n 個樣本預測得到的目標(標簽)的第 k 維。對於多分類問題,這個目標通常是以“one-of-c”編碼的形式存在的,當是屬於第 k 類的,那么的第 k 個元素就是正的,其他的元素就是 0 或者是負的(這取決於激活函數的選擇)。

        因為在整個訓練集上的誤差只是簡單的將每個樣本產生的誤差進行相加得到的,所以這里先在單個樣本(第 n  個)上用BP來做講解:

  (公式2)

        在普通的全連接網絡上,我們能夠用下面的BP規則的形式來對 E求關於權重的偏導。 這里  指示當前的第幾層,輸出層為第 L 層,而輸入層(原始數據層)為第1 層。這里第層(當前層)的輸出是:

(公式3)

這里輸出的激活函數 f(·)通常是選擇邏輯(sigmoid)函數或者雙曲線 tangent 函數。這個邏輯函數可以將【-∞,+∞】的數映射到【0,1】,而這個雙曲線 tangent函數可以將【-∞,+∞】的數映射到【-a,+a】。因此雙曲線 tangent函數的輸出通常是靠近 0 ,而sigmoid函數的輸出通常是非 0 的。然而對訓練數據進行歸一化到 0 均值和單位方差(方差為1)可以在梯度下降上改善收斂。在基於一個歸一化的數據集上,通常更喜歡選擇雙曲線 tangent函數。LeCun建議 a = 1.7159;b = 2 / 3。這樣非線性最大化的點會出現在 ,因此當期望的訓練目標以值進行歸一化的時候,就可以可以避免在訓練的時候飽和的問題(估計就是防止訓練目標分布的太集中在0周圍了,這樣可以使它們更加合理的分布)。

2.2后向傳播

        網絡中我們需要后向傳播的“ 誤差”可以被認為是關於有偏置項擾動的每個單元的 “敏感性”(這個解釋來自於Sebastian Seung)。也就是說:

(公式4)

因為,所以偏置的敏感性其實等於一個單元的所有輸入產生的誤差偏導。下面的就是從高層到低層的BP:

(公式5)

這里的“o” 表示是 逐原始相乘的。對於公式2中的誤差函數,輸出層神經元的敏感性如下:

(公式6) 

最后,關於某個給定的神經元的更新權重的delta-rule就是對那個神經元的輸入部分進行復制,只是用神經元的delta進行縮放罷了(其實就是如下面公式7的兩個相乘而已)。在向量的形式中,這相當於輸入向量(前層的輸出)和敏感性向量的外積:

(公式7)

(公式8)

和公式4的偏置更新的表現形式相類似。在實際操作中這里的學習率一般是每個權重都有不同的學習率即:

3CNN

        通常卷積層都是有子采樣層的附加以此來減少計算時間並且逐步的建立更深遠的空間和構型的不變性。在照顧特異性的同時也需要一個小的子采樣因子,當然這個不是新方法,但是這個概念卻簡單而又有效。哺乳動物的視覺皮層和在【12 8 7】中的模型着重的介紹了這些方面,在過去的10年中聽覺神經科學的發展讓我們知道在不同動物的皮層上primary和belt聽覺領域中有相同的設計模型【6 11 9】.層級分析和學習結構也許就是聽覺領域獲得成功的關鍵。

3.1卷積層

        這里接着談論網絡中關於卷積層的BP更新。在一個卷積層中,前層的特征映射圖是先進行卷積核運算然后再放入一個激活函數來得到特征映射圖作為輸出。每個輸出圖也許是有許多個圖的卷積組合而成的。通常如下面的公式:

(公式9)

這里表示選的第幾個輸入圖,在MATLAB中這里的卷積是“valid”邊緣處理的。通常對輸入圖的選擇包括all-pairs或者是all-triplets,但是下面會討論如何學習組合的。每個輸出圖都有個額外的偏置 b,然而對於一個具體的輸出圖來說,輸入圖是有着不同的卷積核的。也就是說如果輸出圖 j 和 k 都是在輸入圖 i上相加得到的,應用在圖 i 上的卷積和關於輸出圖 j 和 k 是不同的。

3.1.1 計算梯度

        我們假設每個卷積層 后面都跟着一個下采樣層 +1.在BP算法中,為了計算第 層中的單元的敏感性,需要先計算與當前層中這個單元相關聯的下一層的敏感性的總和,並乘以下一層(第+1層)與這個單元之間的權重參數得到傳遞到這一層這個單元的敏感性。並用當前層的輸入 u 的激活函數的偏導乘以這個量(這里所要表達的就是BP的想法,如果熟悉BP那么這里比較繞口的意思就能很好的明白了)。在一個卷積層並后面跟個下采樣層的情況中,在下采樣層中所關聯的圖 中的一個像素相當於卷積層輸出圖中的像素塊(后來的池化的想法)。因此在第 層中的一個圖上的每個單元只與第 +1層中相對應的圖中的一個單元相連(多對一的關系)。為了高效的計算第層的敏感性,我們可以對下采樣層中的敏感圖進行上采樣去保證與卷積層圖具有相同的尺寸,隨后只需要將第 +1層中的上采樣敏感圖與第層中的激活函數偏導圖逐元素相乘即可。在下采樣層圖中定義的“權重”全等於  (一個常量,見部分3.2),所以只是將前面步驟的結果用來進行縮放以達到計算 的結果。我們能在卷積層的每個圖 j 中進行同樣的計算,並用子采樣層中相對應的圖進行搭配:

 (公式10)

這里up(·)表示一個上采樣操作,如果子采樣層用因子 n 來子采樣,那么就簡單的將輸入中的每個像素在輸出中進行水平和豎直tiles操作 n次。正如下面說的,高效的執行這個函數的一個可能的方法是通過使用Kronecker積:

(公式11)

現在,我們有了給定圖的敏感性,我們能夠立刻通過將中所有的實體進行累加來簡單的計算偏置的梯度:

(公式11)

最后,除了許多鏈接中交叉共享相同權重的情況,核權重的梯度可以通過BP來進行計算。因此,我們將在所有連接中提到這個權重的權重梯度進行累加,就像對偏置項的操作一樣:

(公式12)

這里中的塊,為了計算輸出卷積圖中位於(u,v)的元素而在卷積中用與其進行逐元素相乘。乍一看,我們可能需要仔細追蹤輸入圖中的塊對應於輸出圖中的像素(和他的相對應的敏感性圖),但是等式12可以在MATLAB中使用基於重疊的valid區域進行卷積得到,只需要一行代碼:

(公式13)

這里我們旋轉圖的目的是為了執行交叉關聯而不是卷積,將輸出旋轉回來是為了當在前饋中執行卷積的時候,這個核可以得到期望的方向。

3.2 子采樣層

        一個子采樣層可以生成輸入圖的下采樣版本。如果有 N 個輸入圖,那么就會有N 個輸出圖,雖然輸出圖可能會變得很小。但是正式的說:

(公式14)

這里down(·)表示一個子采樣函數。通常這個函數會將輸入圖像中每個不同的 n×n的塊上執行加操作,這樣這個輸出圖像在時空維度上就是原來的1/n 了。每個輸出圖都有自己相對應的乘法偏置和一個額外的偏置 b。我們可以簡單的拋開圖中的其他樣本(腳注部分:Patrice Simard的“pulling”和“pushing”當你使用0填充的conv去計算敏感性和梯度的時候是不需要的)。

3.2.1 計算梯度

        這里的困難在於計算敏感性圖。當我們做到了這步的時候,當需要更新的唯一可以學習的參數是偏置參數和 b 。我們假設這個子采樣層的上面和下面都由卷積層包圍了。如果跟隨着子采樣層的是一個全連接層,那么關於這個子采樣層的敏感性圖可以通過部分2中描述的 BP算法來進行計算。

        當我們試圖計算在部分3.1.1中的核梯度的時候,我們不得不指出在給定輸出圖中的像素並找出輸入中相對應的塊。在這里,我們必須指出在給定下一層的敏感性圖中的像素的時候指出當前層的敏感性圖中對應的塊,以便應用一個和等式5看上去差不多的delta遞歸。當然,在輸入塊和輸出像素之間的連接上相乘的權重是(旋轉)卷積核的權重。這也可以用一行代碼高效的執行卷積:


像以前一樣,我們旋轉這個核來使得卷積函數執行交叉關聯。注意到在這個情況中,我們需要“full”卷積邊緣處理,借助於MATLAB的命名法。這微小的不同讓我們可以很輕松和高效的處理邊緣的情況,輸入到層+1中一個單元的數量不是完整的n×n大小的卷積核。這些情況下這個“full”卷積會將丟失的輸入部分自動補0。

        在我們已經准備好計算和 b 的梯度下,這個額外的偏置同樣是通過對敏感性圖中的元素進行累加得到的:


這里的乘法偏置當然包含了在前饋過程中計算的當前層上的原始下采樣圖。因為這個原因,在前饋計算中保存這些圖也是很有必要的,所以我們不需要在BP中重新計算他們,這里我們定義:


的梯度由下面的式子給出:


3.3學習特征圖的組合

        很多時候,提供一個包含着在幾個不同輸入圖上的卷積的和的輸出圖是很有優勢的。在文獻中,輸入圖是通過組合去形成一個手動選擇的輸出圖的。然而,我們試圖去在訓練過程中學習這樣的組合。讓表示成在需要形成輸出圖 j 的時候與輸入圖 i 之間的權衡宗。然后輸出入可以通過下面的式子給出:


受限條件是:


這些受限條件可以通過設置變量等於基於無約束,潛在權重 的softmax來實現:


因為在指定 j 的權重的每個集合都是關於其他 j 的集合獨立的,我們可以考慮在單一圖上的更新和丟棄下標 j 的情況 。每個圖都以同樣的方式更新,除了具有不同 j 指數的圖。

        softmax函數的偏導等於:

(公式15)

(這里采用的也是Kronecker delta),而在等式2中關於層上的變量的偏導是:


這里是敏感性圖就相當於輸出圖的輸入 u 。再一次,這里的卷積是“valid”的,這樣這個結果才能匹配敏感性圖的尺寸。現在我們能使用這個鏈式法則去計算損失函數(2)關於潛在權重的梯度:

(公式16)

(公式17)

3.3.1 采用稀疏組合

        我們同樣試圖去在給定一個圖的基礎上在權重 的分布上加上稀疏約束,通過添加正則化懲罰項到最終的損失函數上。這樣的好處是可以使得權重中的某些值呈現趨於0的情況。這樣就只有很少的輸入圖會貢獻到一個給定的輸出圖中。在單個樣本上的損失圖下:

(公式18)

並發現了正則化項到權重梯度的貢獻.這個用戶自定義的參數 控制着在訓練數據上這個網絡的最小化擬合的程度,並且確保在正則化項中提到的權重是按照 1-范數 小型化的。我們再次考慮在給定輸出圖的權重和丟棄下標 j 的情況。首先,我們需要:

(公式19)

在任何除了起始的地方。將這個結果與公式15相結合可以然我們得到這個貢獻:

(公式20)

(公式21)

當使用這個懲罰損失函數(公式18)的時候,權重最終的梯度可以使用公式20和16計算:


3.4在Matlab中的加速

 在一個子采樣和卷積層相互交替的網絡中主要的計算瓶頸是:

        1:在前饋中:下采樣卷積層的輸出圖

        2:在BP中:更高子采樣層delta的上采樣去匹配更低卷積層輸出圖的尺寸

        3:sigmoid的應用和他的偏導

當然在前饋和BP階段中卷積的計算也是瓶頸,但是假設這個2D卷積程序是高效執行的,那么這部分也就沒什么可以優化的了。

        然而,還是需要去試圖使用MATLAB內建的圖像處理程序去處理上采樣和下采樣操作。對於上采樣,imresize可以做這個工作,但是會有明顯的開銷。一個更塊的替代方法是使用Kronecker積函數 kron,來處理矩陣上采用,這個可以不同數量級的加速。當在前饋中的下采樣過程中,imresize不提供關於下采樣的選擇,只是將不同的n×n塊進行求和罷了。“ 最近鄰”方法可以用塊中的一個原始像素來替換整塊像素。一個可選方法是用blkproc在每個不同的塊上進行操作,或者將im2col和colfilt組合起來。這些操作都只是計算需要的部分而沒有其他的開銷,重復的調用用戶自定義的塊-預處理函數會明顯的過多的開銷。一個更快速的方法是用矩陣來對圖像進行卷積,然后簡單的對其他條目進行標准索引(例如: y = x(1:2:end,1:2:end) ).盡管在這個案例中卷積實際計算了四次和我們需要的輸出一樣多(假設是2x的下采樣),這種方法仍然(實驗性的)比之前提到的方法要快。

        大多數作者執行sigmiod激活函數和他的偏導的時候都是使用inline函數定義的。但是在MATLAB中“inline”的定義和C中晚期不同,而且還需要大量的時間去評估,因此通常來說是用實際的代碼進行替換的。這也是對於代碼優化和可讀性之間的權衡問題。

4 實際訓練問題(不完整)

4.1 批量更新VS在線更新

批量學習VS隨機梯度下降

4.2學習率

        LeCun的隨機在線方法(diagonal approx to hessian),這值得嗎?Viren的觀點是:至少對於每層來說有不同的學習率,因為更低層的梯度更小而且更不可靠。LeCun的觀點相似於【5】中說的。

4.3損失函數的選擇

        誤差平方(MLE)VS交叉熵 (cross-entropy)。后者在很多分類任務上比前者好。

4.4檢查求導是否正確

        有限微分是當需要驗證寫的BP執行(求導)代碼是否正確的不可缺少的工具(就是UFLDL中每個任務都需要進行cost函數驗證的部分)。BP()或者求導寫的代碼不但容易犯錯而且仍然是個需要學習某些東西的網絡(這句可忽略)通過檢查寫的代碼的梯度導數是可以驗證是否寫錯了的好方法。對於一個輸入樣本來說,使用二階有限微分來驗證梯度:


還需要檢查BP代碼的梯度返回值。Epsilon應該盡可能的小,但是不要太小而引起數值精度問題。例如=10e-8,都還好。注意到使用有限微分去訓練網絡通暢是低效的(即有在基於W權重上有O(W^2)的時間復雜度);但是O(W)帶來的BP的速度優勢還是值得應對這些麻煩的。

參考文獻



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM