卷積神經網絡是如何工作的(譯文)


卷積神經網絡是如何工作的(譯文)

原文:http://brohrer.github.io/how_convolutional_neural_networks_work.html

 

 

十有八九,當你聽到有關深度學習又有新的技術突破時候,總能看到卷積神經網絡的影子。卷積神經網絡(CNNsConvNets)是深度神經網絡領域中的重頭戲,它們在某些圖像識別領域的精度甚至超過了人類。CNNs人激動的方法之一

另一個讓人興奮的一點是,CNNs很容易理解,至少當你將他們分解成一些基本部分以后,它們更加容易理解。下面詳細介紹。

 

X's and O's

一個簡單的栗子:判斷一張圖片是X還是O。如

 

 

一個理想的解決方案是保存一個XO的圖片,然后與新圖片進行比較,哪個相似度高就分類為哪個。然而計算機比較實在,計算機看到的圖片只是一個二維像素矩陣(設想下大的棋盤),每個二維位置上有個數字,假設,白色為1,黑色為-1如下圖。當比較的時候,一些像素不同,就會造成整個匹配不同。我們想要的效果是:不論XO的圖像如何變化,如平移、縮放、旋轉或畸變等,都可以正確識別。CNNs可以解決這個問題。

 

Features(特征)

CNNs比較兩幅圖像的方法逐部分進行的,這些部分被稱為特征。相比於全圖逐像素的匹配比較,CNNs通過尋找兩張圖片中大致相同位置上的的粗糙特征匹配,可以更好的反映其相似度。如圖所示,局部的特征相似部位。

 

 

 

每一個特征都可以看成一個小圖片,特征匹配,就是這些特征小圖的匹配。一個X字符圖片,里面的對角線特征和交叉特征是幾乎所有X字符都具有的,每個X的中心是一個交叉特征,而四個手臂都是對角線特征(方向不同而已)。如下圖

 

Convolution(卷積)

給定一張圖片,CNNs並不知道提取哪個區域的特征,於是嘗試尋找圖片中的所有可能的位置。在計算這些特征的時候,我們用的是一個濾波器(filter,卷積模板)。這種數學計算方法,我們用的是卷積,這是卷積神經網絡名字的來歷

卷積的計算原理會使很多人覺得頭疼。為了計算圖像某個區域與已知特征之間的匹配關系,可以將已知特征矩陣(卷積模板)內的每個像素值與對應圖像中的像素值進行乘法運算,然后將每個像素的計算結果相加,再除以特征矩陣(卷積模板)中總的像素個數。假設像素都是白的(上面圖中的案例),也就是1,那么乘積還是1,都是-1,乘積也是1,只有當不匹配的時候,才是-1。如果特征與圖像中對應位置的特征都一樣,那么最終的計算結果會得到1(案例結果)。反之小於1。

 

繼續這個計算過程,讓特征矩陣(卷積模板)與所有可能的圖像區域進行卷積運算。最終通過每一次卷積操作得到的值會構成一個新的二維矩陣,這個矩陣是圖像中找到的特征的映射圖,值越接近1,說明特征越匹配,越接近-1,說明更接近負的特征(相片的底片原理),接近0,說明不存在任何匹配關系。

接着,將其他特征矩陣(實例圖中的其他對角線特征、交叉特征等)與圖像進行相同的操作,最終得到幾個特征圖,每個特征圖對應一個卷積模板。這些操作可以在CNNs的卷積層完成。

 

很容易理解CNNs是進行了無所顧忌的(貪婪的進行全部像素的卷積運算)運算來保持其識別能力的,盡管我們可以很簡單的將CNN寫在紙上,很快的將其加法、乘法、除法的數量寫出來。用數學語言描述,就是卷積網絡的計算復雜度與圖像的像素數目、卷積模板的像素數目以及卷積模板的個數具有線性比例關系。現在的計算芯片CPUGPU等)可以輕松的解決大規模卷積計算問題,這也是CNNs最近才火起的原因。

 

 

 

Pooling(下采樣)

除了卷積層,另一個有力工具是pooling層,pooling是一種在保留圖像大部分重要信息的基礎上縮小圖像的方法。其背后的數學原理很簡單(小學二年級水平?),包括一個滑動窗口(n*n)遍歷整幅圖像,然后取這窗口中所有像素的最大(max pooling)或平均(average pooling)或隨機(random pooling)等等值。下圖是max pooling。一般在實際操作中,2x23x3pooling 窗口並且以2個像素為步長的pooling 操作效果最佳。

按照2x2pooling窗口,最終得到的圖像是原圖的四分之一。由於pooling是窗口的最大值,所以它保留了窗口中的最佳特征。這意味着關心pooling窗口中特征吻合在哪個很精確的像素級位置,只要待測特征與窗口中某個位置的特征吻合即可。這樣的結果使得CNNs可以發現圖像中是否存在某一特征而不用關心它具體在哪。這就解決了計算機比較實在的問題(讓計算機不要精確的知道特征在哪,如果精確的知道特征在哪個位置,那泛化能力很弱)

Pooling操作是在圖像或者圖像集合上進行的,所以輸出后的結果圖像數目沒有變化,只是像素數目減少了。這樣就減少了數據量,比如一個8M的圖像,pooling操作后就成了2M大小,易於后面的計算操作。

 

Rectified Linear Units (ReLU)

 

ReLU操作即一種激活函數這個CNNs組成成員很小但很重要。其背后的數學原理也很簡單:當一個輸入值為負數,經過ReLU函數后輸出為0

 

這個操作使得CNN可以保持數學上的健壯性,學習的值范圍從0到無窮大(只在單側抑制,具有稀疏性,興奮邊界很寬等)。這就像是CNNs大車的車軸潤滑劑,簡單而不華麗,但缺少它大車將無法走的更遠。

ReLU層的輸出和輸入同尺寸大小,只是所有的負數變成了0

 

 

 

Deep learning(深度學習)

通過前面,可以發現,每一層的輸入與輸出非常相似(都是二維矩陣),正是因為如此,我們可以像搭建樂高積木一樣將它們堆疊起來。一幅原始圖像,經過卷積濾波、ReLU矯正和pooling操作,可以得到一系列的縮小后的特征圖像。這個過程可以一直重復下去,這樣就會得到更多和更復雜的特征圖,並且圖像變得更小,數據得到更大的壓縮。

 

這樣的結構,使得低特征提取層可以提取圖像的簡單特征,比如邊緣,亮度信息等局部特征,如下左圖。更高的特征提取層將逐步提取圖像的高級特征,比如形狀和圖案,這樣逐漸容易分辨。比如,在CNN人臉識別中,最高層的特征就和人臉很相近了,如下右圖

 

 

Fully connected layers(全連接層)

 

CNNs的一個利器是全連接層,它將圖像的高級特征圖轉化為投票數,在我們的栗子中,就是投票識別XO。全連接層是傳統神經網絡的主要組成層,輸入的不是二維矩陣,而是每個元素同等重要的一個單列,每個值擁有自己的投票權利,是X還是O。但這不公平,因為有些值相比其它值更能反映這個圖像是X,有些更能反映它是O,而這些有突出表現的值就應該有更高的投票權利。這些所謂的投票權利,就是特征值和類別之間的權值,或者說是連接能力。當一個原始圖像進入CNN后,從低層一直到全連接層,一個所謂的投票就開始了,最終的輸出類別就是得票數最高的那個類別。

 

 

犀利的全連接層自然也可以堆疊了(輸出和輸入相似,都是一個值列表)。實際情況下,經常幾個全連接層連接在一起,中間的算是投票給隱含層的類別。這樣,每個額外的層讓網絡學到了豐富且復雜的聯合特征,這樣使得網絡的預測精度更高。

 

 

Backpropagation(后向傳播)

 

到這里,故事很完美,但卻有些疑問:特征從哪來?我們如何在全連接層中找到的這些權值?手動的?肯定不是,否則CNNs將不會這么火。其實是后向傳播方法幫助我們實現了這些操作。

為了應用后向傳播方法,我們必須准備大量的已知標簽的圖像,就像是大量的已知是X字符圖片和是O的圖片,而准備數據則需要很大的耐心。我們用這些數據和一個未訓練的神經網絡(未訓練的意思是,每個特征模板的像素值和全連接層的權值都是隨機數)。然后將這些圖像去輸入未訓練的神經網絡。

每個圖像經過CNN處理后都得到一個類別投票,而投票類別錯誤(本該是X,投成O)的總數,也就是誤差,是評判我們的特征模板和權值好壞的依據。接下來,通過調整特征模板和權值,降低這個誤差。調節的值(變化的值)都是正負成對的,也就是權值加一點和權值減一點兩個情況都要嘗試,然后再各自計算誤差值。如果發現這兩者中哪個誤差減少了,那就保留(增或減的)哪個值。如此過程應用在卷積層中的特征模板像素值和全連接層上的權值上,新的權值最終使得誤差略有降低。然后再應用在不同的已知標簽圖像上,再經過很多很多次迭代后,在一張圖像上的權值可能會被覆蓋丟失,但是符合整個大數據集的權值和特征將會留存(個體雖有差異、但整體大勢所趨)。只要數據足夠多,就可以得到泛化能力強的網絡模型。

 

 

當然,顯而易見的是,后向傳播運算量大,需要更高的硬件計算能力。(這也是深度學習中常用離線訓練,在線識別的原因)

 

Hyperparameters(超參數)

CNNs仍然有很多值得考慮的問題:

1)每個卷積層,需要多少特征數?每個特征圖有多少像素?

2)每個pooling層,窗口大小是多少?步長呢?

3)每個全連接層,應該有多少隱含層神經元?

 

還有更高級的架構問題需要解決:網絡中每一層的個數?如何組織?有些深度神經網絡有上千層,可以預測更多類別可能性。

CNN結構的排列組合太多太多,只有部分被測試過。CNN的發展壯大離不開社區的推動,經常得到一些令人驚喜的結果。我們嘗試了一些簡單的CNN,還有很多很多的CNN結構,比如擁有一些新的類型層,更復雜的層之間的互聯方式等等。

 

Beyond images(除圖像之外)

 

CNN不止可以分類圖像文件,還可以分類其它數據類型。只要將這種數據類型轉換為類似圖像就可以了(矩陣形式?)。例如,聲音信號,可以被切割成短的時間塊,然后將每塊分解成低音、中音、高音或更細的頻帶。這樣就可以將其看做是個二維矩陣,每一列為一個時間塊,每一行為一個頻帶。如下圖。

 

 

這樣看起來就像圖像了。CNNs對這種數據也能有很好的表現。還有像自然語言處理中的文本數據,甚至是醫葯發現中的化學數據等等。

 

沒有萬能的技術,所以也有不適合CNNs的數據類型,比如客戶數據。每一行表示一個客戶,每一列表示客戶相關信息,比如姓名,性別,地址,郵箱,購物和瀏覽歷史等。這樣的數據,行和列的位置關系不再重要。這樣的話,行可以重新排列,列也可以重新排序,而不會損失重要數據。相反地,重新排列圖像的行列將使得圖像幾乎變得雜亂無章,沒有用處。

經驗法則:如果你的數據交換行列后一樣有用,那么就不適合用CNNs。反之,如果你的問題就像是在一張圖像中尋找一些圖案,那么CNNs就是你想要的。

 

Learn more(學無止境)

繼續挖掘Deep Learning,有很多資料可以借鑒:

 

http://brohrer.github.io/deep_learning_demystified.html

http://cs231n.github.io/convolutional-networks/

http://colah.github.io/archive.html

 

還有很多優秀的框架值得動手操作:

·  Caffe

·  CNTK

·  Deeplearning4j

·  TensorFlow

·  Theano

·  Torch

·  Many others

 






免責聲明!

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



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