1 CNN的前生今世
1.1 大腦
作為人類,我們不斷地通過眼睛來觀察和分析周圍的世界,我們不需要刻意的“努力”思考,就可以對所看到的一切做出預測,并對它們采取行動。當我們看到某些東西時,我們會根據我們過去學到的東西來标記每個對象。為了說明這些情況,請看下面這張圖片:
你可能會想到“這是一個快樂的小男孩站在椅子上”。或者也許你認為他看起來像是在尖叫,即将在他面前攻擊這塊蛋糕。這就是我們整天下意識地做的事情。我們看到事物,然後标記,進行預測和識别行為。但是我們怎麼做到這些的呢?我們怎麼能解釋我們看到的一切?
大自然花費了5億多年的時間來創建一個系統來實現這一目标。眼睛和大腦之間的合作,稱為主要視覺通路,是我們理解周圍世界的原因。
雖然視力從眼睛開始,但我們所看到的實際解釋發生在大腦的初級視覺皮層中。當您看到一個物體時,您眼中的光感受器會通過視神經将信号發送到正在處理輸入的主視覺皮層。在初級視覺皮層,使眼睛看到的東西的感覺。
所有這一切對我們來說都很自然。我們幾乎沒有想到我們能夠識别我們生活中看到的所有物體和人物的特殊性。神經元和大腦連接的深層複雜層次結構在記憶和标記物體的過程中起着重要作用。
想想我們如何學習例如傘是什麼。或鴨子,燈,蠟燭或書。一開始,我們的父母或家人告訴我們直接環境中物體的名稱。我們通過給我們的例子了解到。慢慢地,但我們開始在我們的環境中越來越多地認識到某些事情。它們變得如此普遍,以至于下次我們看到它們時,我們會立即知道這個物體的名稱是什麼。他們成為我們世界的模型一部分。
1.2 卷積神經網絡的曆史
與孩子學會識别物體的方式類似,我們需要在能夠概括輸入并對之前從未見過的圖像進行預測之前,展示數百萬張圖片的算法。
計算機以與我們不同的方式“看到”東西的。他們的世界隻包括數字。每個圖像都可以表示為二維數字數組,稱為像素。
但是它們以不同的方式感知圖像,這一事實并不意味着我們無法訓練他們的識别模式,就像我們一樣如何識别圖像。我們隻需要以不同的方式思考圖像是什麼。
為了“教會”一種算法如何識别圖像中的對象,我們使用特定類型的人工神經網絡:卷積神經網絡(CNN)。他們的名字源于網絡中最重要的一個操作:卷積。卷積神經網絡受到大腦的啟發。DH Hubel和TN Wiesel在20世紀50年代和60年代對哺乳動物大腦的研究提出了哺乳動物如何在視覺上感知世界的新模型。他們表明貓和猴的視覺皮層包括在其直接環境中專門響應神經元的神經元。
在他們的論文中,他們描述了大腦中兩種基本類型的視覺神經元細胞,每種細胞以不同的方式起作用:簡單細胞(S細胞)和複合細胞(C細胞)。
例如,當簡單單元格将基本形狀識别為固定區域和特定角度的線條時,它們就會激活。複雜細胞具有較大的感受野,其輸出對野外的特定位置不敏感。
複雜細胞繼續對某種刺激做出反應,即使它在視網膜上的絕對位置發生變化。在這種情況下,複雜指的是更靈活。
在視覺中,單個感覺神經元的感受區域是視網膜的特定區域,其中某些東西将影響該神經元的發射(即,将激活神經元)。每個感覺神經元細胞都有相似的感受野,它們的田地覆蓋着。
此外,層級【hierarchy 】的概念在大腦中起着重要作用。信息按順序存儲在模式序列中。的新皮層,它是大腦的最外層,以分層方式存儲信息。它存儲在皮質柱中,或者在新皮層中均勻組織的神經元分組。
1980年,一位名為Fukushima的研究員提出了一種分層神經網絡模型。他稱之為新認知。該模型的靈感來自簡單和複雜細胞的概念。neocognitron能夠通過了解物體的形狀來識别模式。
後來,1998年,卷心神經網絡被Bengio,Le Cun,Bottou和Haffner引入。他們的第一個卷積神經網絡稱為LeNet-5,能夠對手寫數字中的數字進行分類。
2 卷積神經網絡
卷積神經網絡(Convolutional Neural Network)簡稱CNN,CNN是所有深度學習課程、書籍必教的模型,CNN在影像識别方面的為例特别強大,許多影像識别的模型也都是以CNN的架構為基礎去做延伸。另外值得一提的是CNN模型也是少數參考人的大腦視覺組織來建立的深度學習模型,學會CNN之後,對于學習其他深度學習的模型也很有幫助,本文主要講述了CNN的原理以及使用CNN來達成99%正确度的手寫字體識别。 CNN的概念圖如下:
從上面三張圖片我們可以看出,CNN架構簡單來說就是:圖片經過各兩次的Convolution, Pooling, Fully Connected就是CNN的架構了,因此隻要搞懂Convolution, Pooling, Fully Connected三個部分的内容就可以完全掌握了CNN!2.1 Convolution Layer卷積層
卷積運算就是将原始圖片的與特定的Feature Detector(filter)做卷積運算(符号⊗),卷積運算就是将下圖兩個3x3的矩陣作相乘後再相加,以下圖為例0 *0 0*0 0*1 0*1 1 *0 0*0 0*0 0*1 0*1 =0
每次移動一步,我們可以一次做完整張表的計算,如下:
下面的動圖更好地解釋了計算過程:
中間的Feature Detector(Filter)會随機産生好幾種(ex:16種),Feature Detector的目的就是幫助我們萃取出圖片當中的一些特征(ex:形狀),就像人的大腦在判斷這個圖片是什麼東西也是根據形狀來推測
利用Feature Detector萃取出物體的邊界
使用Relu函數去掉負值,更能淬煉出物體的形狀
我們在輸入上進行了多次卷積,其中每個操作使用不同的過濾器。這導緻不同的特征映射。最後,我們将所有這些特征圖放在一起,作為卷積層的最終輸出。
就像任何其他神經網絡一樣,我們使用激活函數使輸出非線性。在卷積神經網絡的情況下,卷積的輸出将通過激活函數。這可能是ReLU激活功能
這裡還有一個概念就是步長,Stride是每次卷積濾波器移動的步長。步幅大小通常為1,意味着濾鏡逐個像素地滑動。通過增加步幅大小,您的濾波器在輸入上滑動的間隔更大,因此單元之間的重疊更少。
下面的動畫顯示步幅大小為1。
由于feature map的大小始終小于輸入,我們必須做一些事情來防止我們的要素圖縮小。這是我們使用填充的地方。添加一層零值像素以使用零環繞輸入,這樣我們的要素圖就不會縮小。除了在執行卷積後保持空間大小不變,填充還可以提高性能并确保内核和步幅大小适合輸入。
可視化卷積層的一種好方法如下所示,最後我們以一張動圖解釋下卷積層到底做了什麼
2.2 Pooling Layer 池化層
在卷積層之後,通常在CNN層之間添加池化層。池化的功能是不斷降低維數,以減少網絡中的參數和計算次數。這縮短了訓練時間并控制過度拟合。
最常見的池類型是max pooling,它在每個窗口中占用最大值。需要事先指定這些窗口大小。這會降低特征圖的大小,同時保留重要信息。
Max Pooling主要的好處是當圖片整個平移幾個Pixel的話對判斷上完全不會造成影響,以及有很好的抗雜訊功能。
2.3 Fully Connected Layer 全連接層
基本上全連接層的部分就是将之前的結果平坦化之後接到最基本的神經網絡了
3 利用CNN識别MNIST手寫字體
下面這部分主要是關于如何使用tensorflow實現CNN以及手寫字體識别的應用
# CNN 代碼 def convolutional(x,keep_prob): def conv2d(x,W): return tf.nn.conv2d(x,W,[1,1,1,1],padding='SAME') def max_pool_2x2(x): return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME') def weight_variable(shape): initial=tf.truncated_normal(shape,stddev=0.1) return tf.Variable(initial) def bias_variable(shape): initial=tf.constant(0.1,shape=shape) return tf.Variable(initial) x_image=tf.reshape(x,[-1,28,28,1]) W_conv1=weight_variable([5,5,1,32]) b_conv1=bias_variable([32]) h_conv1=tf.nn.relu(conv2d(x_image,W_conv1) b_conv1) h_pool1=max_pool_2x2(h_conv1) W_conv2 = weight_variable([5, 5, 32, 64]) b_conv2 = bias_variable([64]) h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) b_conv2) h_pool2 = max_pool_2x2(h_conv2) # full_connetion W_fc1=weight_variable([7*7*64,1024]) b_fc1=bias_variable([1024]) h_pool2_flat=tf.reshape(h_pool2,[-1,7*7*64]) h_fc1=tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1) b_fc1) # dropout 随機扔掉一些值,防止過拟合 h_fc1_drop=tf.nn.dropout(h_fc1,keep_prob) W_fc2=weight_variable([1024,10]) b_fc2=bias_variable([10]) y=tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2) b_fc2) return y,[W_conv1,b_conv1,W_conv2,b_conv2,W_fc1,b_fc1,W_fc2,b_fc2] 複制代碼
大家稍微對tensorflow的代碼有些基礎,理解上面這部分基本上沒有難度,并且基本也是按照我們前面概念圖中的邏輯順序實現的。
最終按照慕課網上的學習資料TensorFlow與Flask結合打造手寫體數字識别,實現了一遍CNN,比較曲折的地方是前端,以及如何将訓練的模型與flask整合,最後項目效果如下:
歡迎大家到GitHub fork和star,項目傳送門--->TensorFlow-MNIST-WEBAPP4 總結
最後說自己的兩點感觸吧:
- CNN在各種場景已經應用很成熟,網上資料特别多,原先自己也是略知一二,但是從來沒有總結整理過,還是整理完之後心裡比較踏實一些。
- 切記理論加實踐,實現一遍更踏實。
5 參考資料
- [資料分析&機器學習] 第5.1講: 卷積神經網絡介紹(Convolutional Neural Network)
- An Intuitive Explanation of Convolutional Neural Networks – the data science blog
- Convolutional Neural Network (CNN) | Skymind
- Convolutional Neural Networks (LeNet) — DeepLearning 0.1 documentation
- CS231n Convolutional Neural Networks for Visual Recognition
- 卷積神經網絡(CNN)學習筆記1:基礎入門 | Jey Zhang
- Deep Learning(深度學習)學習筆記整理系列之(七) - CSDN博客
參考文獻:K碼農-http://kmanong.top/kmn/qxw/form/home?top_cate=28
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!