卷積神經網路Lenet-5實現
原文地址:http://blog.csdn.net/hjimce/article/details/47323463
作者:hjimce
卷積神經網路演算法是n年前就有的演算法,只是近年來因為深度學習相關演算法為多層網路的訓練提供了新方法,然後現在電腦的計算能力已非當年的那種計算水平,同時現在的訓練資料很多,於是神經網路的相關演算法又重新火了起來,因此卷積神經網路就又活了起來,再開始前,我們需要明確的是網上講的卷積神經網路的相關教程一般指的是神經網路的前向傳導過程,反向傳播都是用梯度下降法進行訓練。
一、理論階段
講解這個演算法,沒有打算囉嗦太多的東西,因為什麼權值共享、區域性感受野什麼的,講那麼多,都是那些生物學的相關理論。卷積神經網路的相關博文也是一大堆,但是講的,基本上都是抄過來抄過去,就像我之前不理解從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中,我們要訓練的卷積核並不是僅僅只有一個,這些卷積核用於提取特徵,卷積核個數越多,提取的特徵越多,理論上來說精度也會更高,然而卷積核一堆,意味著我們要訓練的引數的個數越多。在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顯示其中的一張圖片:
[python] view plain copy
- <span style="font-size:18px;">import cPickle
- import gzip
- import numpy as np
- import matplotlib.pyplot as plt
- f = gzip.open('mnist.pkl.gz', 'rb')
- train_set, valid_set, test_set = cPickle.load(f)
- f.close()
- tx,ty=train_set;
- #檢視訓練樣本
- print np.shape(tx)#可以看到tx大小為(50000,28*28)的二維矩陣
- print np.shape(ty)#可以看到ty大小為(50000,1)的矩陣
- #圖片顯示
- A=tx[8].reshape(28,28)#第八個訓練樣本
- Y=ty[8]
- print Y
- plt.imshow(A,cmap='gray')#顯示手寫字型圖片</span>
在上面的程式碼中我顯示的是第8張圖片,可以看到如下結果:
第八個樣本是數字1。
2、LeNet-5實現
首先你要知道mnist.pkl.gz這個庫給我們的圖片的大小是28*28的,因此我們可以第一步選擇5*5的卷積核進行卷積得到24*24,同時我們希望C1層得到20張特徵圖,等等,具體的程式碼實現如下;
[python] view plain copy
- import os
- import sys
- import timeit
- import numpy
- import theano
- import theano.tensor as T
- from theano.tensor.signal import downsample
- from theano.tensor.nnet import conv
- from logistic_sgd import LogisticRegression, load_data
- from mlp import HiddenLayer
- #卷積神經網路的一層,包含:卷積+下采樣兩個步驟
- #演算法的過程是:卷積-》下采樣-》啟用函式
- class LeNetConvPoolLayer(object):
- #image_shape是輸入資料的相關引數設定 filter_shape本層的相關引數設定
- def __init__(self, rng, input, filter_shape, image_shape, poolsize=(2, 2)):
- """
- :type rng: numpy.random.RandomState
- :param rng: a random number generator used to initialize weights
- 3、input: 輸入特徵圖資料,也就是n幅特徵圖片
- 4、引數 filter_shape: (number of filters, num input feature maps,
- filter height, filter width)
- num of filters:是卷積核的個數,有多少個卷積核,那麼本層的out feature maps的個數
- 也將生成多少個。num input feature maps:輸入特徵圖的個數。
- 然後接著filter height, filter width是卷積核的寬高,比如5*5,9*9……
- filter_shape是列表,因此我們可以用filter_shape[0]獲取卷積核個數
- 5、引數 image_shape: (batch size, num input feature maps,
- image height, image width),
- batch size:批量訓練樣本個數 ,num input feature maps:輸入特徵圖的個數
- image height, image width分別是輸入的feature map圖片的大小。
- image_shape是一個列表型別,所以可以直接用索引,訪問上面的4個引數,索引下標從
- 0~3。比如image_shape[2]=image_heigth image_shape[3]=num input feature maps
- 6、引數 poolsize: 池化下采樣的的塊大小,一般為(2,2)
- """
- assert image_shape[1] == filter_shape[1]#判斷輸入特徵圖的個數是否一致,如果不一致是錯誤的
- self.input = input
-
相關推薦
卷積神經網路Lenet-5實現
原文地址:http://blog.csdn.net/hjimce/article/details/47323463 作者:hjimce 卷積神經網路演算法是n年前就有的演算法,只是近年來因為深度學習相關演算法為多層網路的訓練提供了新方法,然後現在電腦
深度學習(四)卷積神經網路Lenet-5實現
卷積神經網路Lenet-5實現 作者:hjimce 卷積神經網路演算法是n年前就有的演算法,只是近年來因為深度學習相關演算法為多層網路的訓練提供了新方法,然後現在電腦的計算能力已非當年的那種計算水平,同時現在的訓練資料很多,於是神經網路的相關演算法
06《基於卷積神經網路LeNet-5的車牌字元識別研究》學習總結
一、本篇介紹 二、本文主要內容(知識點) 1、概要 2、卷積神經網路介紹 1.卷積層 2.次抽樣層 3、LeNet-5介
深度學習 CNN卷積神經網路 LeNet-5詳解
卷積神經網路( Convolutional Neural Network, CNN): 是一種常見的深度學習架構,受生物自然視覺認知機制(動物視覺皮層細胞負責檢測光學訊號)啟發而來,是一種特殊的多層前饋神經網路。它的人工神經元可以響應一部分覆蓋範圍
TensorFlow+實戰Google深度學習框架學習筆記(12)------Mnist識別和卷積神經網路LeNet
一、卷積神經網路的簡述 卷積神經網路將一個影象變窄變長。原本【長和寬較大,高較小】變成【長和寬較小,高增加】 卷積過程需要用到卷積核【二維的滑動視窗】【過濾器】,每個卷積核由n*m(長*寬)個小格組成,每個小格都有自己的權重值, 長寬變窄:過濾器的長寬決定的 高度變高:過濾器的個數決定的 &nb
卷積神經網路的tensorflow實現
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/happyhorizion/article/details/77894047 卷積神經網路概述 一般一個卷積神經網路由多個卷積層構成,在卷基層內部通常會有如下幾個操作: 1
deeplearning.ai 第四課第一週, 卷積神經網路的tensorflow實現
1、載入需要模組和函式: import math import numpy as np import h5py import matplotlib.pyplot as plt import scipy from PIL import Image from
deeplearning.ai 第四課第一週,step by step 卷積神經網路的python實現
1、填充零的padding函式實現 # GRADED FUNCTION: zero_pad def zero_pad(X, pad): """ Pad with zeros all images of the dataset X. The
基於卷積神經網路和tensorflow實現的人臉識別
以前在學習卷積神經網路的時候,發現了很多很有趣的demo,有一次發現了上面這個人臉識別的例子,不過當時還看不懂,經過一段時間之後決定試試能不能將上面的例子改一下,調以調參什麼的,於是就有了這篇文章。本以為我的程式碼和原文沒有什麼太大的區別,應該不會出現什麼錯誤,但是實際自己上
卷積神經網路CNN:Tensorflow實現(以及對卷積特徵的視覺化)
本文主要是實現了一個簡單的卷積神經網路,並對卷積過程中的提取特徵進行了視覺化. 卷積神經網路最早是為了解決影象識別的問題,現在也用在時間序列資料和文字資料處理當中,卷積神經網路對於資料特徵的提取不用額外進行,在對網路的訓練的過程當中,網路會自動提
深度學習筆記:卷積神經網路的Tensorflow實現
在上一講中,我們學習瞭如何利用 numpy 手動搭建卷積神經網路。但在實際的影象識別中,使用 numpy 去手寫 CNN 未免有些吃力不討好。在 DNN 的學習中,我們也是在手動搭建之後利用 Tensorflow 去重新實現一遍,一來為了能夠對神經網路的傳播機制能夠理
卷積神經網路之tensorflow實現
tensorflow中集成了很多庫和函式,卷積神經網路的實現變得十分簡單,這節講述如何利用tensorflow實現一個兩個卷積層的神經網路,用於對手寫數字的識別。 程式碼如下: # -*- coding:utf-8 -*- #功能:使用卷積神經網路實現對手寫數字的識別
CNN卷積神經網路推導和實現
對於第一和第二個問題,我們考慮的是如何用Matlab內建的影象處理函式去實現上取樣和下采樣的操作。對於上取樣,imresize函式可以搞定,但需要很大的開銷。一個比較快速的版本是使用Kronecker乘積函式kron。通過一個全一矩陣ones來和我們需要上取樣的矩陣進行Kronecker乘積,就可以實現上取樣
經典卷積神經網路演算法(5):ResNet
1 引言¶ 神經網路演算法有時候又被稱為深度學習,究其原因就是因為神經網路模型可以通過新增網路層數來擴充套件網路的深度以獲得更優越的效能。以CNN網路為例,卷積層數越多,模型越能夠提取到更高層次的特徵,資訊更加豐富。所以,我們不禁要
機器學習與深度學習系列連載: 第二部分 深度學習(十二)卷積神經網路 3 經典的模型(LeNet-5,AlexNet ,VGGNet,GoogLeNet,ResNet)
卷積神經網路 3 經典的模型 經典的卷積神經網路模型是我們學習CNN的利器,不光是學習原理、架構、而且經典模型的超引數、引數,都是我們做遷移學習最好的源材料之一。 1. LeNet-5 [LeCun et al., 1998] 我們還是從CNN之父,LeCun大神在98年提出的模
機器學習筆記(十三):TensorFlow實戰五(經典卷積神經網路: LeNet -5 )
1 - 引言 之前我們介紹了一下卷積神經網路的基本結構——卷積層和池化層。通過這兩個結構我們可以任意的構建各種各樣的卷積神經網路模型,不同結構的網路模型也有不同的效果。但是怎樣的神經網路模型具有比較好的效果呢? 下圖展示了CNN的發展歷程。 經過人們不斷的嘗試,誕生了許多有
關於LeNet-5卷積神經網路 S2層與C3層連線的引數計算的思考???
關於LeNet-5卷積神經網路 S2層與C3層連線的引數計算的思考??? 首先圖1是LeNet-5的整體網路結構圖 圖1 LeNet-5結構 該神經網路共有7層(不計輸入層),輸入影象大小為32×32。 層編號特點:英文字母+數字 &n
深度學習 --- 卷積神經網路CNN(LeNet-5網路學習演算法詳解)
上一節我們詳細探討了LeNet-5網路的架構,但是還沒有解釋該網路是如何進行學習的,如何更新權值的,本節將接著上一節進一步CNN的學習機制和權值更新過程,這裡請大家一定要對CNN網路有一個清晰的認識,知道每一層是做什麼的,為什麼這樣設定。原因在哪等。大家在學習的過程中需要多問自己幾個為什麼,這樣
深度學習 --- 卷積神經網路CNN(LeNet-5網路詳解)
卷積神經網路(Convolutional Neural Network,CNN)是一種前饋型的神經網路,其在大型影象處理方面有出色的表現,目前已經被大範圍使用到影象分類、定位等領域中。相比於其他神經網路結構,卷積神經網路需要的引數相對較少,使的其能夠廣泛應用。 本節打算先介紹背景和簡單的基本
TensorFlow學習筆記(5)--實現卷積神經網路(MNIST資料集)
這裡使用TensorFlow實現一個簡單的卷積神經網路,使用的是MNIST資料集。網路結構為:資料輸入層–卷積層1–池化層1–卷積層2–池化層2–全連線層1–全連線層2(輸出層),這是一個簡單但非常有代表性的卷積神經網路。 import tensorflow