在前面的兩篇博客中,咱們介紹了DNN(深度神經網絡)並使用keras實現了一個簡單的DNN。在這篇博客中將介紹CNN(卷積神經網絡),而後在下一篇博客中將使用keras構建一個簡單的CNN,對cifar10
數據集進行分類預測。html
咱們能夠想一個例子,假如咱們如今須要對人進行識別分類,根據咱們人類的思惟,咱們確定是比較他的👀是否是同樣的,👃是否是同樣大小,是否是雙(or 三)下巴。換句話來講,咱們的判斷標準是一個可視的範圍。git
CNN就是受到了人類視覺神經系統的啓發,使用卷積核來代替人類中的視野,這樣既可以下降計算量,又可以有效的保留圖像的特徵,同時對圖片的處理更加的高效。咱們能夠想想前面介紹的DNN網絡,它是將一個一個的像素點進行計算的,毋庸置疑,這樣必然會帶來參數的膨脹,好比說cifar-10中一張32*32*3的圖像,第一個隱藏層的中的單個神經元就有\(32 \times 32 \times 3 = 3072\)個權重,彷佛挺小的,可是若是圖片的像素再大一點,則參數會飛速猛增,同時參數增長的同時就會致使過擬合。github
下圖是我使用DNN網絡去訓練cifar-10獲得的結果,能夠明顯的看到過擬合:算法
而CNN就是將DNN中複雜的問題簡單化(實際上更復雜,可是參數簡單化了)。這裏借用Easyai的幾張圖和幾段話:網絡
在下面的場景中,有⚪是1,不然就是0,⚪的位置不一樣,產生的數據也就不一樣,可是從視覺的角度上面來講,兩張圖的內容是差很少的,只在於⚪的位置的不一樣罷了。ide
而 CNN 解決了這個問題,他用相似視覺的方式保留了圖像的特徵,當圖像作翻轉,旋轉或者變換位置時,它也能有效的識別出來是相似的圖像。函數
下面是一張來自cs231n中一張識別汽車的圖,使用的是CNN網絡,裏面包含了CNN網絡的網絡層:spa
在上圖中的CNN網絡中,網絡層有一下類型:3d
能夠很明顯的看到,CNN網絡與DNN網絡有類似,也有不一樣。在CNN網絡中,使用了卷積層和池化層,最後才使用全鏈接層,而卷積層就是CNN的核心。可是在DNN網絡中所有都是全鏈接層。code
下面將對這幾層進行介紹,其中參考了YouTube上How Convolutional Neural Networks work這個視頻。該視頻有條件的建議去看一看,講的仍是蠻形象生動的。
咱們以識別一張照片是X
仍是O
做爲咱們的識別目的:
咱們如何識別一張新的圖片是X
仍是O
,確定是拿該照片與已有的標準X
和O
照片進行對比,哪個類似度高,則就認爲新的照片是屬於哪個類別。對比對於人類來講很簡單,可是,對於計算機來講,應該怎麼對比呢?
計算機能夠進行遍歷圖片的每個像素點的像素值,而後與標準圖片的像素值進行比較,可是毋庸置疑,這樣確定是不行的,好比說在下圖中計算機就認爲只有中間的是同樣的,其它四個角都不一樣,所以可能會得出這張圖片不是X
這個結論。
可是咱們確定是但願無論在平移,旋轉,仍是變形的狀況下,CNN模型均可以識別出來。
so,咱們將比較範圍由像素點擴大到某一個範圍,在CNN模型中,會比較兩張圖片的的各個局部,這些局部稱之爲特徵(features)。
每個feature都是一張小圖,也就是更小的二維矩陣。這些特徵會捕捉圖片中的共同要素。以X
圖片爲例,它最重要的特徵就是對角線和中間的交叉。也就是說,任何叉叉的線條或中心點應該都會符合這些特徵。
那麼如何判斷一張圖片中是否有相符合的特徵,而後符合的特徵有多少個,這裏咱們使用數學的方法卷積(convolution)進行操做,這個也就是CNN名字的由來。
下面我仍是將以識別X
做爲例子來說解一下如何進行進行卷積。卷積的目的是爲了計算特徵與圖片局部的相符程度。
計算的步驟以下:
若是咱們將這個\(3 \times 3\)的特徵矩陣沿着該圖片以stide = 1(也就是每次滑動一格),能夠獲得一個\(7 \times 7\)的矩陣,最終獲得的結果以下圖所示:
很容易理解,卷積以後的結果越接近1,則至關與對應位置與特徵feature越接近。分別與三個特徵進行卷積的結果以下所示,獲得了feature map:
這裏是一張來自cs231n的一張卷積示意圖:
不過這裏與上面不一樣的是,它並無取平均值,同時加上了一個偏置\(b\),同時最後的結果是三個的的卷積的和。而且加上了一個padding(也就是外面那一層灰色取0的地方)
設輸入的爲\(W_1 \times H_1 \times D_1\),卷積核的大小是\(F \times F\),卷積核的數量是\(K\),padding的大小是\(P\),stride步爲\(S\),輸出的矩陣的大小是\(W_2 \times H_2 \times D_2\),則:
整流線性單位函數(Rectified Linear Unit, ReLU),又稱修正線性單元, 是一種人工神經網絡中經常使用的激勵函數(activation function),一般指代以斜坡函數及其變種爲表明的非線性函數。數學表達式爲:
Relu激勵層的工做流程以下所示:
將卷積層的輸出經過激勵層後的結果以下:
這一層仍是蠻簡單的,可能你們會發現,在深度神經網絡中,sigmoid激活函數就不多使用了,這是由於sigmoid函數過小了,在多層神經網絡下會出現」梯度消失「現象。
池化層就更加的簡單了,池化層能夠大幅度的下降數據的維度。池化層多種,下面介紹兩種簡單經常使用的:
average pooling
):計算圖像區域的平均值做爲該區域池化後的值。max pooling
):選圖像區域的最大值做爲該區域池化後的值。那麼池化是怎麼操做的呢,下面是最大池化進行操做的示意圖:
池化層也就是從必定的範圍(也就是池化層的大小)中選出一個(或者計算出一個)值做爲這個區域範圍的表明。
對全部的feature map都進行池化,最後的結果以下:
由於最大池化(max-pooling)保留了每個小塊內的最大值,因此它至關於保留了這一塊最佳的匹配結果(由於值越接近1表示匹配越好)。這也就意味着它不會具體關注窗口內究竟是哪個地方匹配了,而只關注是否是有某個地方匹配上了。這也就可以看出,CNN可以發現圖像中是否具備某種特徵,而不用在乎到底在哪裏具備這種特徵。這也就可以幫助解決以前提到的計算機逐一像素匹配的死板作法。
設輸入的爲\(W_1 \times H_1 \times D_1\),池化層的大小是\(F \times F\),stride步爲\(S\),輸出的矩陣的大小是\(W_2 \times H_2 \times D_2\),則:
咱們將前面所講的卷積層,激勵層,池化層進行結合,所得:
加大網絡的層數就獲得了深度神經網絡:
經過前面得卷積,池化操做,咱們成功得將數據進行了降維,獲得降維後的數據後,咱們在將其放入全鏈接層中,就能夠獲得最終得結果。
仍是以上面識別X爲例子:
咱們稱之這一層爲全鏈接層。
固然全鏈接層也能夠有多個:
綜上,全部得結構咱們能夠表達爲:
同時咱們能夠與CS231n的圖片做比較,二者是同樣的。
這一篇博客主要是介紹了每一層的功能,以及每一層工做的原理,可是並無對其數學公式繼續寧推導,若是想更多的瞭解CNN的前向和反向傳播算法,能夠去參考這一篇博客。
在下一篇博客中,將介紹使用CNN對cifar-10(也多是cifar-100)進行訓練預測。