1. 程式人生 > >[透析] 卷積神經網絡CNN究竟是怎樣一步一步工作的?(轉)

[透析] 卷積神經網絡CNN究竟是怎樣一步一步工作的?(轉)

caff 素數 aec near chris line 旋轉 均值 水平

  • 視頻地址:https://www.youtube.com/embed/FmpDIaiMIeA 轉載:http://www.jianshu.com/p/fe428f0b32c1
  • 文檔參閱:pdf [2MB] & ppt [6MB] & Web View & GitBook
  • 補充知識:深度學習 — 反向傳播理論推導

技術分享

當你聽到說深度學習打破了某項新技術障礙,那麽十有八九就會涉及到卷積神經網絡。它們也被稱作CNNs或著ConvNets,是深層神經網絡領域的主力。它們已經學會對圖像進行分類,在某些情況下甚至超過了人類。如果有一個方法證明了這種假設,那就是CNN。特別酷的一點就是,當你將它們分解為基本模塊時,它們很容易被理解。這裏有一個視頻,很詳細地討論了關於這些圖像問題。

技術分享
LeNet-5 技術分享
Classfication

先驗工作

  • 【icml09 - Convolutional Deep Belief Networks.pdf】
技術分享 技術分享 技術分享
  • 【Playing Atari with Deep Reinforcement Learning】
技術分享 技術分享
  • 【Robot Learning Manipulation Action Plans】
技術分享 技術分享 技術分享

A toy ConvNet:X’s and O’s

識別一幅圖片是包含有字母"X"還是字母"O"?

為了幫助指導你理解卷積神經網絡,我們講采用一個非常簡化的例子:確定一幅圖像是包含有"X"還是"O"?

技術分享

這個例子足夠說明CNN背後的原理,同時它足夠簡單,能夠避免陷入不必要的細節。在CNN中有這樣一個問題,就是每次給你一張圖,你需要判斷它是否含有"X"或者"O"。並且假設必須兩者選其一,不是"X"就是"O"。理想的情況就像下面這個樣子:

技術分享
標準的"X"和"O",字母位於圖像的正中央,並且比例合適,無變形

對於計算機來說,只要圖像稍稍有一點變化,不是標準的,那麽要解決這個問題還是不是那麽容易的:

技術分享

計算機要解決上面這個問題,一個比較天真的做法就是先保存一張"X"和"O"的標準圖像(就像前面給出的例子),然後將其他的新給出的圖像來和這兩張標準圖像進行對比,看看到底和哪一張圖更匹配,就判斷為哪個字母。但是這麽做的話,其實是非常不可靠的,因為計算機還是比較死板的。在計算機的“視覺”中,一幅圖看起來就像是一個二維的像素數組(可以想象成一個棋盤),每一個位置對應一個數字。在我們這個例子當中,像素值"1"代表白色,像素值"-1"代表黑色。

技術分享

當比較兩幅圖的時候,如果有任何一個像素值不匹配,那麽這兩幅圖就不匹配,至少對於計算機來說是這樣的。
對於這個例子,計算機認為上述兩幅圖中的白色像素除了中間的3*3的小方格裏面是相同的,其他四個角上都不同:

技術分享

因此,從表面上看,計算機判別右邊那幅圖不是"X",兩幅圖不同,得出結論:

技術分享

但是這麽做,顯得太不合理了。理想的情況下,我們希望,對於那些僅僅只是做了一些像平移,縮放,旋轉,微變形等簡單變換的圖像,計算機仍然能夠識別出圖中的"X"和"O"。就像下面這些情況,我們希望計算機依然能夠很快並且很準的識別出來:

技術分享

這也就是CNN出現所要解決的問題。

Features

技術分享

對於CNN來說,它是一塊一塊地來進行比對。它拿來比對的這個“小塊”我們稱之為Features(特征)。在兩幅圖中大致相同的位置找到一些粗糙的特征進行匹配,CNN能夠更好的看到兩幅圖的相似性,相比起傳統的整幅圖逐一比對的方法。

每一個feature就像是一個小圖(就是一個比較小的有值的二維數組)。不同的Feature匹配圖像中不同的特征。在字母"X"的例子中,那些由對角線和交叉線組成的features基本上能夠識別出大多數"X"所具有的重要特征。

技術分享

這些features很有可能就是匹配任何含有字母"X"的圖中字母X的四個角和它的中心。那麽具體到底是怎麽匹配的呢?如下:

技術分享 技術分享 技術分享 技術分享 技術分享

看到這裏是不是有了一點頭目呢。但其實這只是第一步,你知道了這些Features是怎麽在原圖上面進行匹配的。但是你還不知道在這裏面究竟進行的是怎樣的數學計算,比如這個下面3*3的小塊到底幹了什麽?

技術分享

接下來就跟進介紹裏面的數學操作,也就是我們常說的“卷積”操作。

卷積(Convolution)

技術分享
Convolution 技術分享

當給你一張新的圖時,CNN並不能準確地知道這些features到底要匹配原圖的哪些部分,所以它會在原圖中每一個可能的位置進行嘗試。這樣在原始整幅圖上每一個位置進行匹配計算,我們相當於把這個feature變成了一個過濾器。這個我們用來匹配的過程就被稱為卷積操作,這也就是卷積神經網絡名字的由來。

這個卷積操作背後的數學知識其實非常的簡單。要計算一個feature和其在原圖上對應的某一小塊的結果,只需要簡單地將兩個小塊內對應位置的像素值進行乘法運算,然後將整個小塊內乘法運算的結果累加起來,最後再除以小塊內像素點總個數即可。如果兩個像素點都是白色(也就是值均為1),那麽1*1 = 1,如果均為黑色,那麽(-1)*(-1) = 1。不管哪種情況,每一對能夠匹配上的像素,其相乘結果為1。類似地,任何不匹配的像素相乘結果為-1。如果一個feature(比如n*n)內部所有的像素都和原圖中對應一小塊(n*n)匹配上了,那麽它們對應像素值相乘再累加就等於n^2,然後除以像素點總個數n^2,結果就是1。同理,如果每一個像素都不匹配,那麽結果就是-1。具體過程如下:

技術分享 技術分享 技術分享 技術分享 技術分享 技術分享 技術分享 技術分享 技術分享 技術分享

對於中間部分,也是一樣的操作:

技術分享 技術分享 技術分享 技術分享

最後整張圖算完,大概就像下面這個樣子:

技術分享

然後換用其他feature進行同樣的操作,最後得到的結果就是這樣了:

技術分享

為了完成我們的卷積,我們不斷地重復著上述過程,將feature和圖中每一塊進行卷積操作。最後通過每一個feature的卷積操作,我們會得到一個新的二維數組。這也可以理解為對原始圖像進行過濾的結果,我們稱之為feature map,它是每一個feature從原始圖像中提取出來的“特征”。其中的值,越接近為1表示對應位置和feature的匹配越完整,越是接近-1,表示對應位置和feature的反面匹配越完整,而值接近0的表示對應位置沒有任何匹配或者說沒有什麽關聯。

技術分享

這樣我們的原始圖,經過不同feature的卷積操作就變成了一系列的feature map。我們可以很方便,直觀地將這整個操作視為一個單獨的處理過程。在CNN中,我們稱之為卷積層(convolution layer),這樣你可能很快就會想到後面肯定還有其他的layer。沒錯,後面會提到。我們可以將卷積層看成下面這個樣子:

技術分享

因此可想而知,CNN其實做的操作也沒什麽復雜的。但是盡管我們能夠以這一點篇幅就描述了CNN的工作,其內部的加法,乘法和除法操作的次數其實會增加地很快。從數學的角度來說,它們會隨著圖像的大小,每一個filter的大小和filter的數目呈線性增長。由於有這麽多因素的影響,很容易使得這個問題的計算量變得相當的龐大,這也難怪很多微處理器制造商現在都在生產制造專業的芯片來跟上CNN計算的需求。

池化(Pooling)

技術分享
Pooling

CNN中使用的另一個有效的工具被稱為“池化(Pooling)”。池化可以將一幅大的圖像縮小,同時又保留其中的重要信息。池化背後的數學頂多也就是小學二年級水平。它就是將輸入圖像進行縮小,減少像素信息,只保留重要信息。通常情況下,池化都是2*2大小,比如對於max-pooling來說,就是取輸入圖像中2*2大小的塊中的最大值,作為結果的像素值,相當於將原始圖像縮小了4倍。(註:同理,對於average-pooling來說,就是取2*2大小塊的平均值作為結果的像素值。)

對於本文的這個例子,池化操作具體如下:

技術分享 技術分享 技術分享

不足的外面補"0":

技術分享 技術分享

經過最大池化操作(比如2*2大小)之後,一幅圖就縮小為原來的四分之一了:

技術分享

然後對所有的feature map執行同樣的操作,得到如下結果:

技術分享

因為最大池化(max-pooling)保留了每一個小塊內的最大值,所以它相當於保留了這一塊最佳的匹配結果(因為值越接近1表示匹配越好)。這也就意味著它不會具體關註窗口內到底是哪一個地方匹配了,而只關註是不是有某個地方匹配上了。這也就能夠看出,CNN能夠發現圖像中是否具有某種特征,而不用在意到底在哪裏具有這種特征。這也就能夠幫助解決之前提到的計算機逐一像素匹配的死板做法。

當對所有的feature map執行池化操作之後,相當於一系列輸入的大圖變成了一系列小圖。同樣地,我們可以將這整個操作看作是一個操作,這也就是CNN中的池化層(pooling layer),如下:

技術分享

通過加入池化層,可以很大程度上減少計算量,降低機器負載。

Normalization

技術分享

激活函數Relu (Rectified Linear Units)

這是一個很小但是很重要的操作,叫做Relu(Rectified Linear Units),或者修正線性單元。它的數學公式也很簡單:

技術分享

對於輸入的負值,輸出全為0,對於正值,原樣輸出。關於其功能,更多詳見 這裏。

下面我們看一下本文的離例子中relu激活函數具體操作:

技術分享 技術分享 技術分享

最後,對整幅圖操作之後,結果如下:

技術分享

同樣地,在CNN中,我們這一系列操作視為一個操作,那麽就得到Relu Layer,如下:

技術分享

Deep Learning

最後,我們將上面所提到的卷積,池化,激活放在一起,就是下面這個樣子:

技術分享

然後,我們加大網絡的深度,增加更多的層,就得到深度神經網絡了:

技術分享

然後在不同的層,我們進行可視化,就可以看到本文開頭提到的先驗知識裏面的結果了:

技術分享

全連接層(Fully connected layers)

技術分享 技術分享 技術分享 技術分享 技術分享 技術分享 技術分享 技術分享

根據結果判定為"X":

技術分享

在這個過程中,我們定義這一系列操作為”全連接層“(Fully connected layers):

技術分享

全連接層也能夠有很多個,如下:

技術分享

【綜合上述所有結構】

技術分享

這一整個過程,從前到後,被稱作”前向傳播“,得到一組輸出,然後通過反向傳播來不斷糾正錯誤,進行學習。

反向傳播 (Backpropagation)

此處數學原理可以參見:深度學習 —— 反向傳播理論推導.

技術分享 技術分享 技術分享 技術分享 技術分享 技術分享 技術分享

Gradient Descent Optimizer

技術分享 技術分享

Hyperparameters

技術分享

Application

技術分享
Images 技術分享
Soung 技術分享
Text 技術分享 技術分享

Learn more

技術分享

If you‘d like to dig deeper into deep learning, check out my Demystifying Deep Learning post. I also recommend the notes from the Stanford CS 231 course by Justin Johnson and Andrej Karpathy that provided inspiration for this post, as well as the writings of Christopher Olah, an exceptionally clear writer on the subject of neural networks.

If you are one who loves to learn by doing, there are a number of popular deep learning tools available. Try them all! And then tell us what you think.
Caffe
CNTK
Deeplearning4j
TensorFlow
Theano
Torch
Many others

I hope you‘ve enjoyed our walk through the neighborhood of Convolutional Neural Networks. Feel free to start up a conversation.

技術分享
Brandon Rohrer

本文重點在前面的具體操作部分,所以後面的部分沒有細說,只是帶過了,如有必要,後期會逐漸完善,謝謝!

Reference:

    • http://brohrer.github.io/how_convolutional_neural_networks_work.html
    • 深度學習 —— 反向傳播理論推導

[透析] 卷積神經網絡CNN究竟是怎樣一步一步工作的?(轉)