1. 程式人生 > >深度學習1——深度學習(四)卷積神經網路入門學習(1)

深度學習1——深度學習(四)卷積神經網路入門學習(1)

卷積神經網路入門學(1)

轉載自:hjimce的專欄 - 部落格頻道 - CSDN.NET

原文地址http://blog.csdn.NET/hjimce/article/details/47323463

作者:hjimce

卷積神經網路演算法是n年前就有的演算法,只是近年來因為深度學習相關演算法為多層網路的訓練提供了新方法,然後現在電腦的計算能力已非當年的那種計算水平,同時現在的訓練資料很多,於是神經網路的相關演算法又重新火了起來因此卷積神經網路就又活了起來。

在開始前,我們需要明確的是網上講的卷積神經網路的相關教程一般指的是神經網路的前向傳導過程,反向傳播都是用梯度下降法進行訓練,大部分深度學習庫,都已經把反向求導的功能給封裝好了,如果想要深入學習反向求導,就需要自己慢慢學了。

因為卷積神經網路的經典模型是:Lenet-5實現,只要理解了這個的前向傳導過程,基本上就OK了,因此我們後面主要講解Lenet-5的實現。

一、理論階段

作為CNN的入門文章,沒有打算囉嗦太多的東西,因為什麼權值共享、區域性感受野什麼的,講那麼多,都是那些生物學的相關理論,看了那些玩意,大部分初學者已經煩了。卷積神經網路的相關博文也是一大堆,但是講的,基本上都是抄過來抄過去,就像我之前不理解從S2層到C3層是怎麼實現的,網上看了一大堆教程,沒有一個解答這個問題的。我的個人感覺整個過程,就只有S2到C3是最難理解的。接著我將用最淺顯易懂的方式進行講解。

1、卷積

卷積的概念這個我想只要學過影象處理的人都懂的概念了,這個不解釋。我們知道對於給定的一幅影象來說,給定一個卷積核,卷積就是根據卷積視窗,進行畫素的加權求和。


卷積神經網路與我們之前所學到的影象的卷積的區別,我的理解是:我們之前學影象處理遇到卷積,一般來說,這個卷積核是已知的,比如各種邊緣檢測運算元、高斯模糊等這些,都是已經知道卷積核,然後再與影象進行卷積運算。然而深度學習中的卷積神經網路卷積核是未知的,我們訓練一個神經網路,就是要訓練得出這些卷積核,而這些卷積核就相當於我們學單層感知器的時候的那些引數W,因此你可以把這些待學習的卷積核看成是神經網路的訓練引數W。

2、池化

剛開始學習CNN的時候,看到這個詞,好像高大上的樣子,於是查了很多資料,理論一大堆,但是實踐、演算法實現卻都沒講到,也不懂池化要怎麼實現?其實所謂的池化,就是圖片下采樣。這個時候,你會發現CNN每一層的構建跟影象高斯金字塔的構建有點類似,因此你如果已經懂得了影象金字塔融合的相關演算法,那麼就變的容易理解了。在高斯金子塔構建中,每一層通過卷積,然後卷積後進行下采樣,而CNN也是同樣的過程。廢話不多說,這裡就講一下,CNN的池化:

CNN的池化(影象下采樣)方法很多:Mean pooling(均值取樣)、Max pooling(最大值取樣)、Overlapping (重疊取樣)、L2 pooling(均方取樣)、Local Contrast Normalization(歸一化取樣)、Stochasticpooling(隨即取樣)、Def-pooling(形變約束取樣)。其中最經典的是最大池化,因此我就解釋一下最大池化的實現:


原圖片

為了簡單起見,我用上面的圖片作為例子,假設上面的圖片大小是4*4的,如上圖所示,然後圖片中每個畫素點的值是上面各個格子中的數值。然後我要對這張4*4的圖片進行池化,池化的大小為(2,2),跨步為2,那麼採用最大池化也就是對上面4*4的圖片進行分塊,每個塊的大小為2*2,然後統計每個塊的最大值,作為下采樣後圖片的畫素值,具體計算如下圖所示:


也就是說我們最後得到下采樣後的圖片為:


這就是所謂的最大池化。當然以後你還會遇到各種池化方法,比如均值池化,也就是對每個塊求取平均值作為下采樣的新畫素值。還有重疊取樣的池化,我上面這個例子是沒有重疊的取樣的,也就是每個塊之間沒有相互重疊的部分,上面我說的跨步為2,就是為了使得分塊都非重疊,等等,這些以後再跟大家解釋池化常用方法。這裡就先記住最大池化就好了,因為這個目前是最常用的。

3、feature maps 

這個單詞國人把它翻譯成特徵圖,挺起來很專業的名詞。那麼什麼叫特徵圖呢?特徵圖其實說白了就是CNN中的每張圖片,都可以稱之為特徵圖張。在CNN中,我們要訓練的卷積核並不是僅僅只有一個,這些卷積核用於提取特徵,卷積核個數越多,提取的特徵越多,理論上來說精度也會更高,然而卷積核一堆,意味著我們要訓練的引數的個數越多。在LeNet-5經典結構中,第一層卷積核選擇了6個,而在AlexNet中,第一層卷積核就選擇了96個,具體多少個合適,還有待學習。

回到特徵圖概念,CNN的每一個卷積層我們都要人為的選取合適的卷積核個數,及卷積核大小。每個卷積核與圖片進行卷積,就可以得到一張特徵圖了,比如LeNet-5經典結構中,第一層卷積核選擇了6個,我們可以得到6個特徵圖,這些特徵圖也就是下一層網路的輸入了。我們也可以把輸入圖片看成一張特徵圖,作為第一層網路的輸入。

4、CNN的經典結構

對於剛入門CNN的人來說,我們首先需要現在的一些經典結構:

(1)LeNet-5。這個是n多年前就有的一個CNN的經典結構,主要是用於手寫字型的識別,也是剛入門需要學習熟悉的一個網路,我的這篇博文主要就是要講這個網路


(2)AlexNet。


在imagenet上的影象分類challenge上大神Alex提出的alexnet網路結構模型贏得了2012屆的冠軍,振奮人心,利用CNN實現了圖片分類,別人用傳統的機器學習演算法調參跳到半死也就那樣,Alex利用CNN精度遠超傳統的網路。

其它的還有什麼《Network In Network》,GoogLeNet、Deconvolution Network,在以後的學習中我們會遇到。比如利用Deconvolution Network反捲積網路實現圖片的去模糊,牛逼哄哄。

    OK,理論階段就囉嗦到這裡就好了,接著就講解 LeNet-5, LeNet-5是用於手寫字型的識別的一個經典CNN:


LeNet-5結構

輸入:32*32的手寫字型圖片,這些手寫字型包含0~9數字,也就是相當於10個類別的圖片

輸出:分類結果,0~9之間的一個數

因此我們可以知道,這是一個多分類問題,總共有十個類,因此神經網路的最後輸出層必然是SoftMax問題,然後神經元的個數是10個。LeNet-5結構:

輸入層:32*32的圖片,也就是相當於1024個神經元

C1層:paper作者,選擇6個特徵卷積核,然後卷積核大小選擇5*5,這樣我們可以得到6個特徵圖,然後每個特徵圖的大小為32-5+1=28,也就是神經元的個數由1024減小到了28*28=784。

S2層:這就是下采樣層,也就是使用最大池化進行下采樣,池化的size,選擇(2,2),也就是相當於對C1層28*28的圖片,進行分塊,每個塊的大小為2*2,這樣我們可以得到14*14個塊,然後我們統計每個塊中,最大的值作為下采樣的新畫素,因此我們可以得到S1結果為:14*14大小的圖片,共有6個這樣的圖片。

C3層:卷積層,這一層我們選擇卷積核的大小依舊為5*5,據此我們可以得到新的圖片大小為14-5+1=10,然後我們希望可以得到16張特徵圖。那麼問題來了?這一層是最難理解的,我們知道S2包含:6張14*14大小的圖片,我們希望這一層得到的結果是:16張10*10的圖片。這16張圖片的每一張,是通過S2的6張圖片進行加權組合得到的,具體是怎麼組合的呢?問題如下圖所示:


為了解釋這個問題,我們先從簡單的開始,我現在假設輸入6特徵圖的大小是5*5的,分別用6個5*5的卷積核進行卷積,得到6個卷積結果圖片大小為1*1,如下圖所示:


    為了簡便起見,我這裡先做一些標號的定義:我們假設輸入第i個特徵圖的各個畫素值為x1i,x2i……x25i,因為每個特徵圖有25個畫素。因此第I個特徵圖經過5*5的圖片卷積後,得到的卷積結果圖片的畫素值Pi可以表示成:


這個是卷積公式,不解釋。因此對於上面的P1~P6的計算方法,這個就是直接根據公式。然後我們把P1~P6相加起來,也就是:

P=P1+P2+……P6

把上面的Pi的計算公式,代入上式,那麼我們可以得到:

P=WX

其中X就是輸入的那6張5*5特徵圖片的各個畫素點值,而W就是我們需要學習的引數,也就相當於6個5*5的卷積核,當然它包含著6*(5*5)個引數。因此我們的輸出特徵圖就是:

Out=f(P+b)

這個就是從S2到C3的計算方法,其中b表示偏置項,f為啟用函式。

我們迴歸到原來的問題:有6張輸入14*14的特徵圖片,我們希望用5*5的卷積核,然後最後我們希望得到一張10*10的輸出特徵圖片?

根據上面的過程,也就是其實我們用5*5的卷積核去卷積每一張輸入的特徵圖,當然每張特徵圖的卷積核引數是不一樣的,也就是不共享,因此我們就相當於需要6*(5*5)個引數。對每一張輸入特徵圖進行卷積後,我們得到6張10*10,新圖片,這個時候,我們把這6張圖片相加在一起,然後加一個偏置項b,然後用啟用函式進行對映,就可以得到一張10*10的輸出特徵圖了。

    而我們希望得到16張10*10的輸出特徵圖,因此我們就需要卷積引數個數為16*(6*(5*5))=16*6*(5*5)個引數。總之,C3層每個圖片是通過S2圖片進行卷積後,然後相加,並且加上偏置b,最後在進行啟用函式對映得到的結果。

S4層:下采樣層,比較簡單,也是知己對C3的16張10*10的圖片進行最大池化,池化塊的大小為2*2。因此最後S4層為16張大小為5*5的圖片。至此我們的神經元個數已經減少為:16*5*5=400。

C5層:我們繼續用5*5的卷積核進行卷積,然後我們希望得到120個特徵圖。這樣C5層圖片的大小為5-5+1=1,也就是相當於1個神經元,120個特徵圖,因此最後只剩下120個神經元了。這個時候,神經元的個數已經夠少的了,後面我們就可以直接利用全連線神經網路,進行這120個神經元的後續處理,後面具體要怎麼搞,只要懂多層感知器的都懂了,不解釋。

上面的結構,只是一種參考,在現實使用中,每一層特徵圖需要多少個,卷積核大小選擇,還有池化的時候取樣率要多少,等這些都是變化的,這就是所謂的CNN調參,我們需要學會靈活多變。

比如我們可以把上面的結構改為:C1層卷積核大小為7*7,然後把C3層卷積核大小改為3*3等,然後特徵圖的個數也是自己選,說不定得到手寫字型識別的精度比上面那個還高,這也是有可能的,總之一句話:需要學會靈活多變,需要學會CNN的調參。

二、實戰階段

1、訓練資料獲取

在theano學習庫中有手寫字型的庫,可以從網上下載到,名為:mnist.pkl.gz的手寫字型庫,裡面包含了三個部分的資料,訓練資料集train_set:50000個訓練樣本,驗證集valid_set,我們可以用如下的程式碼讀取這些資料,然後用plot顯示其中的一張圖片:

  1. <span style="font-size:18px;">import cPickle  
  2. import gzip  
  3. import numpy as np  
  4. import matplotlib.pyplot as plt  
  5. f = gzip.open('mnist.pkl.gz''rb')  
  6. train_set, valid_set, test_set = cPickle.load(f)  
  7. f.close()  
  8. tx,ty=train_set;  
  9. #檢視訓練樣本
  10. print np.shape(tx)#可以看到tx大小為(50000,28*28)的二維矩陣
  11. print np.shape(ty)#可以看到ty大小為(50000,1)的矩陣
  12. #圖片顯示
  13. A=tx[8].reshape(28,28)#第八個訓練樣本
  14. Y=ty[8]  
  15. print Y  
  16. plt.imshow(A,cmap='gray')#顯示手寫字型圖片</span>

在上面的程式碼中我顯示的是第8張圖片,可以看到如下結果:


第八個樣本是數字1。

2、LeNet-5實現

首先你要知道mnist.pkl.gz這個庫給我們的圖片的大小是28*28的,因此我們可以第一步選擇5*5的卷積核進行卷積得到24*24,同時我們希望C1層得到20張特徵圖,等等,具體的程式碼實現如下;

  1. import os  
  2. import sys  
  3. import timeit  
  4. import numpy  
  5. import theano  
  6. import theano.tensor as T  
  7. from theano.tensor.signal import downsample  
  8. from theano.tensor.nnet import conv  
  9. from logistic_sgd import LogisticRegression, load_data  
  10. from mlp import HiddenLayer  
  11. #卷積神經網路的一層,包含:卷積+下采樣兩個步驟
  12. #演算法的過程是:卷積-》下采樣-》啟用函式
  13. class LeNetConvPoolLayer(object):  
  14.     #image_shape是輸入資料的相關引數設定  filter_shape本層的相關引數設定
  15.     def __init__(self, rng, input, filter_shape, image_shape, poolsize=(22)):  
  16.         """ 
  17.         :type rng: numpy.random.RandomState 
  18.         :param rng: a random number generator used to initialize weights 
  19.         3、input: 輸入特徵圖資料,也就是n幅特徵圖片 
  20.         4、引數 filter_shape: (number of filters, num input feature maps, 
  21.                               filter height, filter width) 
  22.         num of filters:是卷積核的個數,有多少個卷積核,那麼本層的out feature maps的個數 
  23.         也將生成多少個。num input feature maps:輸入特徵圖的個數。 
  24.         然後接著filter height, filter width是卷積核的寬高,比如5*5,9*9…… 
  25.         filter_shape是列表,因此我們可以用filter_shape[0]獲取卷積核個數 
  26.         5、引數 image_shape: (batch size, num input feature maps, 
  27.                              image height, image width), 
  28.          batch size:批量訓練樣本個數 ,num input feature maps:輸入特徵圖的個數 
  29.          image height, image width分別是輸入的feature map圖片的大小。 
  30.          image_shape是一個列表型別,所以可以直接用索引,訪問上面的4個引數,索引下標從 
  31.          0~3。比如image_shape[2]=image_heigth  image_shape[3]=num input feature maps 
  32.         6、引數 poolsize: 池化下采樣的的塊大小,一般為(2,2) 
  33.         """
  34.         assert image_shape[1] == filter_shape[1]#判斷輸入特徵圖的個數是否一致,如果不一致是錯誤的
  35.         self.input = input  
  36.         # fan_in=num input feature maps *filter height*filter width 
  37.         #numpy.prod(x)函式為計算x各個元素的乘積
  38.         #也就是說fan_in就相當於每個即將輸出的feature  map所需要連結引數權值的個數
  39.         fan_in = numpy.prod(filter_shape[1:])  
  40.         # fan_out=num output feature maps * filter height * filter width
  41.         fan_out = (filter_shape[0] * numpy.prod(filter_shape[2:]) /  
  42.                    numpy.prod(poolsize))  
  43.         # 把引數初始化到[-a,a]之間的數,其中a=sqrt(6./(fan_in + fan_out)),然後引數採用均勻取樣
  44.         #權值需要多少個?卷積核個數*輸入特徵圖個數*卷積核寬*卷積核高?這樣沒有包含取樣層的連結權值個數
  45. 相關推薦

    深度學習神經網路入門學習(1)

    卷積神經網路入門學(1)作者:hjimce卷積神經網路演算法是n年前就有的演算法,只是近年來因為深度學習相關演算法為多層網路的訓練提供了新方法,然後現在電腦的計算能力已非當年的那種計算水平,同時現在的訓練資料很多,於是神經網路的相關演算法又重新火了起來,因此卷積神經網路就又活

    深度學習1——深度學習神經網路入門學習(1)

    卷積神經網路入門學(1) 轉載自:hjimce的專欄 - 部落格頻道 - CSDN.NET 原文地址:http://blog.csdn.NET/hjimce/article/details/47323463 作者:hjimce 卷積

    深度學習神經網路Lenet-5實現

    卷積神經網路Lenet-5實現 作者:hjimce 卷積神經網路演算法是n年前就有的演算法,只是近年來因為深度學習相關演算法為多層網路的訓練提供了新方法,然後現在電腦的計算能力已非當年的那種計算水平,同時現在的訓練資料很多,於是神經網路的相關演算法

    機器學習筆記神經網路CNN

    1.前言: 卷積神經網路在計算視覺領域的表現十分出色,與普通的BP神經網路一樣,CNN同樣由神經元組成。其實卷積神經網路是卷積+神經網路,基本上由三部分組成:卷積層,pooling層,全連線層。 2.CNN:卷積層 卷積是一個訊號領域的概念,我們這裡提

    Deep learning with Theano 官方中文教程翻譯—— 神經網路CNN

    供大家相互交流和學習,本人水平有限,若有各種大小錯誤,還請巨牛大牛小牛微牛們立馬拍磚,這樣才能共同進步!若引用譯文請註明出處http://www.cnblogs.com/charleshuang/。 文章中的程式碼截圖不是很清晰,可以去上面的原文網址去檢視。 1、動機    卷積神經網路(CNN

    機器學習深度學習系列連載: 第二部分 深度學習神經網路 1 Convolutional Neural Networks

    卷積神經網路 Convolutional Neural Networks 卷積神經網路其實早在80年代,就被神經網路泰斗Lecun 提出[LeNet-5, LeCun 1980],但是由於當時的資料量、計算力等問題,沒有得到廣泛使用。 卷積神經網路的靈感來自50年代的諾貝爾生物學獎

    深度學習進階--神經網路深度置信網路以及自動編碼初識補昨天部落格更新

    總結一下昨天的學習過程 (注:這幾天老不在狀態,貌似進入了學習激情的瓶頸期,動力以及平靜心嚴重失控,Python3.X與Python2.X之間的程式碼除錯,尤其是環境配置搞得頭昏腦脹) 昨天瞭解接觸的內容 CNN卷積神經網路的基本原理以及在CPU中測試以及程式碼除錯(又是失

    斯坦福大學深度學習公開課cs231n學習筆記10神經網路

    前記:20世紀60年代,Hubel和Wiesel在研究貓腦皮層中用於區域性敏感和方向選擇的神經元時,發現其獨特的網路結構可以有效地降低反饋神經網路的複雜性,繼而提出了卷積神經網路(Convolutio

    2017CS231n李飛飛深度視覺識別筆記——神經網路

    第五講 卷積神經網路課時1 歷史    在上一章中,我們討論了神經網路的有關知識以及線性評分函式的執行例項,通過堆疊線性層來實現完整的神經網路。    接下來,我們將討論卷積神經網路,以下是1998年L

    deep learning tutorial 翻譯theano學習指南4翻譯- 神經網路

    from theano.tensor.nnet import conv rng = numpy.random.RandomState(23455) # instantiate 4D tensor for input input = T.tensor4(name='input') # initializ

    人工智慧實踐:TensorFlow筆記學習—— 神經網路基礎

    大綱7.1 卷積神經網路7.2  lenet5程式碼講解目標掌握卷積神經網路的搭建方法7.1 卷積神經網路全連線 NN:每個神經元與前後相鄰層的每一個神經元都有連線關係,輸入是特徵,輸出為預測的結果。引數個數:(前層X後層+後層)  一張解析度僅僅是28x28的黑白影象,就有

    # [cs231n 神經網路 ][1]

    標籤(空格分隔): 神經網路 0.回顧 cs231n (一)影象分類識別講了KNN cs231n (二)講了線性分類器:SVM和SoftMax cs231n (三)優化問題及方法 cs231n (四)反向傳播 cs231n (五)神經網路 part 1:

    CNN神經網路dropout

    第一篇文章介紹了卷積神經網路的資料輸入形式和權值的初始化:CNN)卷積神經網路(一) 第二篇文章介紹了卷積操作,常用的啟用函式(CNN)卷積神經網路(二) 第三篇介紹了卷積神經網路的池化層,視覺化理解以及用數學的角度理解卷積操作:(CNN)卷積神經網路(三)

    TensorFlow訓練MNIST資料集3 —— 神經網路

      前面兩篇隨筆實現的單層神經網路 和多層神經網路, 在MNIST測試集上的正確率分別約為90%和96%。在換用多層神經網路後,正確率已有很大的提升。這次將採用卷積神經網路繼續進行測試。 1、模型基本結構   如下圖所示,本次採用的模型共有8層(包含dropout層)。其中卷積層和池化層各有兩層。   在

    TensorFlow實踐10——神經網路模型LeNet5

    (一)前 言 卷積神經網路(Convoltional Neural Networks, CNN)是一類包含卷積或相關計算且具有深度結構的前饋神經網路(Feedforward Neural Networks),是深度學習(deep learning)的代表演

    TensorFlow神經網路下與電腦”猜拳“

    想法來源於學習DeepLearning.ai的卷積神經網路的作業,想利用手勢識別完成一個可以和電腦進行“猜拳遊戲”。 參考資料: 【1】TensorFlow和樹莓派完成的猜拳遊戲* 【2】手勢識別模型 【3】攝像頭手寫數字識別 第一步:前期準備 1.

    DeepLearning.ai學習筆記神經網絡 -- week2深度神經網絡 實例探究

    過濾 common 經典 上一個 問題 inline 最壞情況 ali method 一、為什麽要進行實例探究? 通過他人的實例可以更好的理解如何構建卷積神經網絡,本周課程主要會介紹如下網絡 LeNet-5 AlexNet VGG ResNet (有152層) Incep

    深度學習介紹操作

    接下來介紹一下,CNNs是如何利用空間結構減少需要學習的引數數目的 如果我們有一張1000x1000畫素的影象,有1百萬個隱層神經元,那麼他們全連線的話(每個隱層神經元都與影象的每一個畫素點相連),這樣就有1000x1000x1000000=10^12個連線,

    機器學習深度學習系列連載: 第二部分 深度學習十二神經網路 3 經典的模型LeNet-5,AlexNet ,VGGNet,GoogLeNet,ResNet

    卷積神經網路 3 經典的模型 經典的卷積神經網路模型是我們學習CNN的利器,不光是學習原理、架構、而且經典模型的超引數、引數,都是我們做遷移學習最好的源材料之一。 1. LeNet-5 [LeCun et al., 1998] 我們還是從CNN之父,LeCun大神在98年提出的模

    機器學習深度學習系列連載: 第二部分 深度學習十一神經網路 2 Why CNN for Image?

    卷積神經網路 2 Why CNN 為什麼處理圖片要用CNN? 原因是: 一個神經元無法看到整張圖片 能夠聯絡到小的區域,並且引數更少 圖片壓縮畫素不改變圖片內容 1. CNN 的特點 卷積: 一些卷積核遠遠小於圖片大小; 同樣的pat