版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
./一、CNN卷積神經(jīng)網(wǎng)絡原理簡介本文主要是詳細地解讀CNN的實現(xiàn)代碼。如果你沒學習過CNN,在此推薦周曉藝師兄的博文:DeepLearning〔深度學習學習筆記整理系列之〔七,以及UFLDL上的卷積特征提取、池化CNN的最大特點就是稀疏連接〔局部感受和權(quán)值共享,如下面兩圖所示,左為稀疏連接,右為權(quán)值共享。稀疏連接和權(quán)值共享可以減少所要訓練的參數(shù),減少計算復雜度。至于CNN的結(jié)構(gòu),以經(jīng)典的LeNet5來說明:這個圖真是無處不在,一談CNN,必說LeNet5,這圖來自于這篇論文:Gradient-BasedLearningAppliedtoDocumentRecognition,論文很長,第7頁那里開始講LeNet5這個結(jié)構(gòu),建議看看那部分。我這里簡單說一下,LeNet5這張圖從左到右,先是input,這是輸入層,即輸入的圖片。input-layer到C1這部分就是一個卷積層〔convolution運算,C1到S2是一個子采樣層〔pooling運算,關(guān)于卷積和子采樣的具體過程可以參考下圖:然后,S2到C3又是卷積,C3到S4又是子采樣,可以發(fā)現(xiàn),卷積和子采樣都是成對出現(xiàn)的,卷積后面一般跟著子采樣。S4到C5之間是全連接的,這就相當于一個MLP的隱含層了〔如果你不清楚MLP,參考《DeepLearningtutorial〔3MLP多層感知機原理簡介+代碼詳解》。C5到F6同樣是全連接,也是相當于一個MLP的隱含層。最后從F6到輸出output,其實就是一個分類器,這一層就叫分類層。ok,CNN的基本結(jié)構(gòu)大概就是這樣,由輸入、卷積層、子采樣層、全連接層、分類層、輸出這些基本"構(gòu)件"組成,一般根據(jù)具體的應用或者問題,去確定要多少卷積層和子采樣層、采用什么分類器。當確定好了結(jié)構(gòu)以后,如何求解層與層之間的連接參數(shù)?一般采用向前傳播〔FP+向后傳播〔BP的方法來訓練。具體可參考上面給出的鏈接。二、CNN卷積神經(jīng)網(wǎng)絡代碼詳細解讀〔基于python+theano代碼來自于深度學習教程:ConvolutionalNeuralNetworks<LeNet>,這個代碼實現(xiàn)的是一個簡化了的LeNet5,具體如下:沒有實現(xiàn)location-specificgainandbiasparameters用的是maxpooling,而不是average_pooling分類器用的是softmax,LeNet5用的是rbfLeNet5第二層并不是全連接的,本程序?qū)崿F(xiàn)的是全連接另外,代碼里將卷積層和子采用層合在一起,定義為"LeNetConvPoolLayer"〔卷積采樣層,這好理解,因為它們總是成對出現(xiàn)。但是有個地方需要注意,代碼中將卷積后的輸出直接作為子采樣層的輸入,而沒有加偏置b再通過sigmoid函數(shù)進行映射,即沒有了下圖中fx后面的bx以及sigmoid映射,也即直接由fx得到Cx。最后,代碼中第一個卷積層用的卷積核有20個,第二個卷積層用50個,而不是上面那張LeNet5圖中所示的6個和16個。了解了這些,下面看代碼:〔1導入必要的模塊[python]viewplaincopyimport
cPickle
import
gzip
import
os
import
sys
import
time
import
numpy
import
theano
import
theano.tensor
as
T
from
theano.tensor.signal
import
downsample
from
theano.tensor.nnet
import
conv
〔2定義CNN的基本"構(gòu)件"CNN的基本構(gòu)件包括卷積采樣層、隱含層、分類器,如下定義LeNetConvPoolLayer〔卷積+采樣層見代碼注釋:[python]viewplaincopy"""卷積+下采樣合成一個層LeNetConvPoolLayerrng:隨機數(shù)生成器,用于初始化Winput:4維的向量,filter_shape:<number
of
filters,
num
input
feature
maps,filter
height,
filter
width>image_shape:<batch
size,
num
input
feature
maps,image
height,
image
width>poolsize:
<#rows,
#cols>"""class
LeNetConvPoolLayer<object>:
def
__init__<self,
rng,
input,
filter_shape,
image_shape,
poolsize=<2,
2>>:
#assert
condition,condition為True,則繼續(xù)往下執(zhí)行,condition為False,中斷程序#image_shape[1]和filter_shape[1]都是num
input
feature
maps,它們必須是一樣的。assert
image_shape[1]
==
filter_shape[1]
self.input
=
input
#每個隱層神經(jīng)元〔即像素與上一層的連接數(shù)為num
input
feature
maps
*
filter
height
*
filter
width。#可以用d<filter_shape[1:]>來求得
fan_in
=
d<filter_shape[1:]>
#lower
layer上每個神經(jīng)元獲得的梯度來自于:"num
output
feature
maps
*
filter
height
*
filter
width"
/pooling
size
fan_out
=
<filter_shape[0]
*
d<filter_shape[2:]>
/
d<poolsize>>
#以上求得fan_in、fan_out
,將它們代入公式,以此來隨機初始化W,W就是線性卷積核
W_bound
=
numpy.sqrt<6.
/
<fan_in
+
fan_out>>
self.W
=
theano.shared<
numpy.asarray<
rng.uniform<low=-W_bound,
high=W_bound,
size=filter_shape>,
dtype=theano.config.floatX
>,
borrow=True
>
#
the
bias
is
a
1D
tensor
--
one
bias
per
output
feature
map#偏置b是一維向量,每個輸出圖的特征圖都對應一個偏置,#而輸出的特征圖的個數(shù)由filter個數(shù)決定,因此用filter_shape[0]即number
of
filters來初始化
b_values
=
numpy.zeros<<filter_shape[0],>,
dtype=theano.config.floatX>
self.b
=
theano.shared<value=b_values,
borrow=True>
#將輸入圖像與filter卷積,conv.conv2d函數(shù)#卷積完沒有加b再通過sigmoid,這里是一處簡化。
conv_out
=
conv.conv2d<
input=input,
filters=self.W,
filter_shape=filter_shape,
image_shape=image_shape
>
#maxpooling,最大子采樣過程
pooled_out
=
downsample.max_pool_2d<
input=conv_out,
ds=poolsize,
ignore_border=True
>
#加偏置,再通過tanh映射,得到卷積+子采樣層的最終輸出#因為b是一維向量,這里用維度轉(zhuǎn)換函數(shù)dimshuffle將其reshape。比如b是<10,>,#則b.dimshuffle<'x',
0,
'x',
'x'>>將其reshape為<1,10,1,1>self.output
=
T.tanh<pooled_out
+
self.b.dimshuffle<'x',
0,
'x',
'x'>>
#卷積+采樣層的參數(shù)self.params
=
[self.W,
self.b]
定義隱含層HiddenLayer這個跟上一篇文章《DeepLearningtutorial〔3MLP多層感知機原理簡介+代碼詳解》中的HiddenLayer是一致的,直接拿過來:[python]viewplaincopy"""注釋:這是定義隱藏層的類,首先明確:隱藏層的輸入即input,輸出即隱藏層的神經(jīng)元個數(shù)。輸入層與隱藏層是全連接的。假設輸入是n_in維的向量〔也可以說時n_in個神經(jīng)元,隱藏層有n_out個神經(jīng)元,則因為是全連接,一共有n_in*n_out個權(quán)重,故W大小時<n_in,n_out>,n_in行n_out列,每一列對應隱藏層的每一個神經(jīng)元的連接權(quán)重。b是偏置,隱藏層有n_out個神經(jīng)元,故b時n_out維向量。rng即隨機數(shù)生成器,,用于初始化W。input訓練模型所用到的所有輸入,并不是MLP的輸入層,MLP的輸入層的神經(jīng)元個數(shù)時n_in,而這里的參數(shù)input大小是〔n_example,n_in,每一行一個樣本,即每一行作為MLP的輸入層。activation:激活函數(shù),這里定義為函數(shù)tanh"""class
HiddenLayer<object>:
def
__init__<self,
rng,
input,
n_in,
n_out,
W=None,
b=None,
activation=T.tanh>:
self.input
=
input
#類HiddenLayer的input即所傳遞進來的input"""
注釋:
代碼要兼容GPU,則必須使用
dtype=theano.config.floatX,并且定義為theano.shared
另外,W的初始化有個規(guī)則:如果使用tanh函數(shù),則在-sqrt<6./<n_in+n_hidden>>到sqrt<6./<n_in+n_hidden>>之間均勻
抽取數(shù)值來初始化W,若時sigmoid函數(shù),則以上再乘4倍。
"""#如果W未初始化,則根據(jù)上述方法初始化。#加入這個判斷的原因是:有時候我們可以用訓練好的參數(shù)來初始化W,見我的上一篇文章。if
W
isNone:
W_values
=
numpy.asarray<
rng.uniform<
low=-numpy.sqrt<6.
/
<n_in
+
n_out>>,
high=numpy.sqrt<6.
/
<n_in
+
n_out>>,
size=<n_in,
n_out>
>,
dtype=theano.config.floatX
>
if
activation
==
theano.tensor.nnet.sigmoid:
W_values
*=
4
W
=
theano.shared<value=W_values,
name='W',
borrow=True>
if
b
isNone:
b_values
=
numpy.zeros<<n_out,>,
dtype=theano.config.floatX>
b
=
theano.shared<value=b_values,
name='b',
borrow=True>
#用上面定義的W、b來初始化類HiddenLayer的W、bself.W
=
W
self.b
=
b
#隱含層的輸出
lin_output
=
T.dot<input,
self.W>
+
self.b
self.output
=
<
lin_output
if
activation
isNoneelse
activation<lin_output>
>
#隱含層的參數(shù)self.params
=
[self.W,
self.b]
定義分類器〔Softmax回歸采用Softmax,這跟《DeepLearningtutorial〔1Softmax回歸原理簡介+代碼詳解》中的LogisticRegression是一樣的,直接拿過來:[python]viewplaincopy"""定義分類層LogisticRegression,也即Softmax回歸在deeplearning
tutorial中,直接將LogisticRegression視為Softmax,而我們所認識的二類別的邏輯回歸就是當n_out=2時的LogisticRegression"""#參數(shù)說明:#input,大小就是<n_example,n_in>,其中n_example是一個batch的大小,#因為我們訓練時用的是Minibatch
SGD,因此input這樣定義#n_in,即上一層<隱含層>的輸出#n_out,輸出的類別數(shù)
class
LogisticRegression<object>:
def
__init__<self,
input,
n_in,
n_out>:
#W大小是n_in行n_out列,b為n_out維向量。即:每個輸出對應W的一列以及b的一個元素。
self.W
=
theano.shared<
value=numpy.zeros<
<n_in,
n_out>,
dtype=theano.config.floatX
>,
name='W',
borrow=True
>
self.b
=
theano.shared<
value=numpy.zeros<
<n_out,>,
dtype=theano.config.floatX
>,
name='b',
borrow=True
>
#input是<n_example,n_in>,W是〔n_in,n_out,點乘得到<n_example,n_out>,加上偏置b,#再作為的輸入,得到p_y_given_x#故p_y_given_x每一行代表每一個樣本被估計為各類別的概率
#PS:b是n_out維向量,與<n_example,n_out>矩陣相加,內(nèi)部其實是先復制n_example個b,#然后<n_example,n_out>矩陣的每一行都加bself.p_y_given_x
=
T.nnet.softmax<T.dot<input,
self.W>
+
self.b>
#argmax返回最大值下標,因為本例數(shù)據(jù)集是MNIST,下標剛好就是類別。axis=1表示按行操作。self.y_pred
=
T.argmax<self.p_y_given_x,
axis=1>
#params,LogisticRegression的參數(shù)
self.params
=
[self.W,
self.b]
到這里,CNN的基本"構(gòu)件"都有了,下面要用這些"構(gòu)件"組裝成LeNet5〔當然,是簡化的,上面已經(jīng)說了,具體來說,就是組裝成:LeNet5=input+LeNetConvPoolLayer_1+LeNetConvPoolLayer_2+HiddenLayer+LogisticRegression+output。然后將其應用于MNIST數(shù)據(jù)集,用BP算法去解這個模型,得到最優(yōu)的參數(shù)。〔3加載MNIST數(shù)據(jù)集〔[python]viewplaincopy"""加載MNIST數(shù)據(jù)集load_data<>"""def
load_data<dataset>:
#
dataset是數(shù)據(jù)集的路徑,程序首先檢測該路徑下有沒有MNIST數(shù)據(jù)集,沒有的話就下載MNIST數(shù)據(jù)集#這一部分就不解釋了,與softmax回歸算法無關(guān)。
data_dir,
data_file
=
os.path.split<dataset>
if
data_dir
==
""
andnot
os.path.isfile<dataset>:
#
Check
if
dataset
is
in
the
data
directory.
new_path
=
os.path.join<
os.path.split<__file__>[0],
"..",
"data",
dataset
>
if
os.path.isfile<new_path>
or
data_file
==
'mnist.pkl.gz':
dataset
=
new_path
if
<not
os.path.isfile<dataset>>
and
data_file
==
'mnist.pkl.gz':
import
urllib
origin
=
<
'http://www.iro.umontreal.ca/~lisa/deep/data/mnist/mnist.pkl.gz'
>
print'Downloading
data
from
%s'
%
origin
urllib.urlretrieve<origin,
dataset>
print'...
loading
data'#以上是檢測并下載數(shù)據(jù)集,不是本文重點。下面才是load_data的開始#從"mnist.pkl.gz"里加載train_set,
valid_set,
test_set,它們都是包括label的#主要用到python里的gzip.open<>函數(shù),以及
cPickle.load<>。#‘rb’表示以二進制可讀的方式打開文件
f
=
gzip.open<dataset,
'rb'>
train_set,
valid_set,
test_set
=
cPickle.load<f>
f.close<>
#將數(shù)據(jù)設置成shared
variables,主要時為了GPU加速,只有shared
variables才能存到GPU
memory中#GPU里數(shù)據(jù)類型只能是float。而data_y是類別,所以最后又轉(zhuǎn)換為int返回def
shared_dataset<data_xy,
borrow=True>:
data_x,
data_y
=
data_xy
shared_x
=
theano.shared<numpy.asarray<data_x,
dtype=theano.config.floatX>,
borrow=borrow>
shared_y
=
theano.shared<numpy.asarray<data_y,
dtype=theano.config.floatX>,
borrow=borrow>
return
shared_x,
T.cast<shared_y,
'int32'>
test_set_x,
test_set_y
=
shared_dataset<test_set>
valid_set_x,
valid_set_y
=
shared_dataset<valid_set>
train_set_x,
train_set_y
=
shared_dataset<train_set>
rval
=
[<train_set_x,
train_set_y>,
<valid_set_x,
valid_set_y>,
<test_set_x,
test_set_y>]
return
rval
〔4實現(xiàn)LeNet5并測試[python]viewplaincopy"""實現(xiàn)LeNet5LeNet5有兩個卷積層,第一個卷積層有20個卷積核,第二個卷積層有50個卷積核"""def
evaluate_lenet5<learning_rate=0.1,
n_epochs=200,
dataset='mnist.pkl.gz',
nkerns=[20,
50],
batch_size=500>:
"""
learning_rate:學習速率,隨機梯度前的系數(shù)。
n_epochs訓練步數(shù),每一步都會遍歷所有batch,即所有樣本
batch_size,這里設置為500,即每遍歷完500個樣本,才計算梯度并更新參數(shù)
nkerns=[20,
50],每一個LeNetConvPoolLayer卷積核的個數(shù),第一個LeNetConvPoolLayer有
20個卷積核,第二個有50個
"""
rng
=
numpy.random.RandomState<23455>
#加載數(shù)據(jù)
datasets
=
load_data<dataset>
train_set_x,
train_set_y
=
datasets[0]
valid_set_x,
valid_set_y
=
datasets[1]
test_set_x,
test_set_y
=
datasets[2]
#
計算batch的個數(shù)
n_train_batches
=
train_set_x.get_value<borrow=True>.shape[0]
n_valid_batches
=
valid_set_x.get_value<borrow=True>.shape[0]
n_test_batches
=
test_set_x.get_value<borrow=True>.shape[0]
n_train_batches
/=
batch_size
n_valid_batches
/=
batch_size
n_test_batches
/=
batch_size
#定義幾個變量,index表示batch下標,x表示輸入的訓練數(shù)據(jù),y對應其標簽
index
=
T.lscalar<>
x
=
T.matrix<'x'>
y
=
T.ivector<'y'>
#######################
BUILD
ACTUAL
MODEL
#######################print'...
building
the
model'#我們加載進來的batch大小的數(shù)據(jù)是<batch_size,
28
*
28>,但是LeNetConvPoolLayer的輸入是四維的,所以要reshape
layer0_input
=
x.reshape<<batch_size,
1,
28,
28>>
#
layer0即第一個LeNetConvPoolLayer層#輸入的單張圖片<28,28>,經(jīng)過conv得到<28-5+1
,
28-5+1>
=
<24,
24>,#經(jīng)過maxpooling得到<24/2,
24/2>
=
<12,
12>#因為每個batch有batch_size張圖,第一個LeNetConvPoolLayer層有nkerns[0]個卷積核,#故layer0輸出為<batch_size,
nkerns[0],
12,
12>
layer0
=
LeNetConvPoolLayer<
rng,
input=layer0_input,
image_shape=<batch_size,
1,
28,
28>,
filter_shape=<nkerns[0],
1,
5,
5>,
poolsize=<2,
2>
>
#layer1即第二個LeNetConvPoolLayer層#輸入是layer0的輸出,每張?zhí)卣鲌D為<12,12>,經(jīng)過conv得到<12-5+1,
12-5+1>
=
<8,
8>,#經(jīng)過maxpooling得到<8/2,
8/2>
=
<4,
4>#因為每個batch有batch_size張圖〔特征圖,第二個LeNetConvPoolLayer層有nkerns[1]個卷積核#,故layer1輸出為<batch_size,
nkerns[1],
4,
4>
layer1
=
LeNetConvPoolLayer<
rng,
input=layer0.output,
image_shape=<batch_size,
nkerns[0],
12,
12>,#輸入nkerns[0]張?zhí)卣鲌D,即layer0輸出nkerns[0]張?zhí)卣鲌D
filter_shape=<nkerns[1],
nkerns[0],
5,
5>,
poolsize=<2,
2>
>
#前面定義好了兩個LeNetConvPoolLayer〔layer0和layer1,layer1后面接layer2,這是一個全連接層,相當于MLP里面的隱含層#故可以用MLP中定義的HiddenLayer來初始化layer2,layer2的輸入是二維的<batch_size,
num_pixels>
,#故要將上層中同一張圖經(jīng)不同卷積核卷積出來的特征圖合并為一維向量,#也就是將layer1的輸出<batch_size,
nkerns[1],
4,
4>flatten為<batch_size,
nkerns[1]*4*4>=<500,800>,作為layer2的輸入。#<500,800>表示有500個樣本,每一行代表一個樣本。layer2的輸出大小是<batch_size,n_out>=<500,500>
layer2_input
=
layer1.output.flatten<2>
layer2
=
HiddenLayer<
rng,
input=layer2_input,
n_in=nkerns[1]
*
4
*
4,
n_out=500,
activation=T.tanh
>
#最后一層layer3是分類層,用的是邏輯回歸中定義的LogisticRegression,#layer3的輸入是layer2的輸出<500,500>,layer3的輸出就是<batch_size,n_out>=<500,10>
layer3
=
LogisticRegression<input=layer2.output,
n_in=500,
n_out=10>
#代價函數(shù)NLL
cost
=
layer3.negative_log_likelihood<y>
#
test_model計算測試誤差,x、y根據(jù)給定的index具體化,然后調(diào)用layer3,#layer3又會逐層地調(diào)用layer2、layer1、layer0,故test_model其實就是整個CNN結(jié)構(gòu),#test_model的輸入是x、y,輸出是layer3.errors<y>的輸出,即誤差。
test_model
=
theano.function<
[index],
layer3.errors<y>,
givens={
x:
test_set_x[index
*
batch_size:
<index
+
1>
*
batch_size],
y:
test_set_y[index
*
batch_size:
<index
+
1>
*
batch_size]
}
>
#validate_model,驗證模型,分析同上。
validate_model
=
theano.function<
[index],
layer3.errors<y>,
givens={
x:
valid_set_x[index
*
batch_size:
<index
+
1>
*
batch_size],
y:
valid_set_y[index
*
batch_size:
<index
+
1>
*
batch_size]
}
>
#下面是train_model,涉及到優(yōu)化算法即SGD,需要計算梯度、更新參數(shù)#參數(shù)集
params
=
layer3.params
+
layer2.params
+
layer1.params
+
layer0.params
#對各個參數(shù)的梯度
grads
=
T.grad<cost,
params>
#因為參數(shù)太多,在updates規(guī)則里面一個一個具體地寫出來是很麻煩的,所以下面用了一個for..in..,自動生成規(guī)則對<param_i,
param_i
-
learning_rate
*
grad_i>
updates
=
[
<param_i,
param_i
-
learning_rate
*
grad_i>
for
param_i,
grad_i
in
zip<params,
grads>
]
#train_model,代碼分析同test_model。train_model里比test_model、validation_model多出updates規(guī)則
train_model
=
theano.function<
[index],
cost,
updates=updates,
givens={
x:
train_set_x[index
*
batch_size:
<index
+
1>
*
batch_size],
y:
train_set_y[index
*
batch_size:
<index
+
1>
*
batch_size]
}
>
################
開始訓練
################print'...
training'
patience
=
10000
patience_increase
=
2
improvement_threshold
=
0.995
validation_frequency
=
min<n_train_batches,
patience
/
2>
#這樣設置validation_frequency可以保證每一次epoch都會在驗證集上測試。
best_validation_loss
=
numpy.inf
#最好的驗證集上的loss,最好即最小
best_iter
=
0#最好的迭代次數(shù),以batch為單位。比如best_iter=10000,說明在訓練完第10000個batch時,達到best_validation_loss
test_score
=
0.
start_time
=
time.clock<>
epoch
=
0
done_looping
=
False#下面就是訓練過程了,while循環(huán)控制的時步數(shù)epoch,一個epoch會遍歷所有的batch,即所有的圖片。#for循環(huán)是遍歷一個個batch,一次一個batch地訓練。for循環(huán)體里會用train_model<minibatch_index>去訓練模型,#train_model里面的updatas會更新各個參數(shù)。#for循環(huán)里面會累加訓練過的batch數(shù)iter,當iter是validation_frequency倍數(shù)時則會在驗證集上測試,#如果驗證集的損失this_validation_loss小于之前最佳的損失best_validation_loss,#則更新best_validation_loss和best_iter,同時在testset上測試。#如果驗證集的損失this_validation_loss小于best_validation_loss*improvement_threshold時則更新patience。#當達到最大步數(shù)n_epoch時,或者patience<iter時,結(jié)束訓練while
<epoch
<
n_epochs>
and
<not
done_looping>:
epoch
=
epoch
+
1for
minibatch_index
in
xrange<n_train_batches>:
iter
=
<epoch
-
1>
*
n_train_batches
+
minibatch_index
if
iter
%
100
==
0:
print'training
@
iter
=
',
iter
cost_ij
=
train_model<minibatch_index>
#cost_ij
沒什么用,后面都沒有用到,只是為了調(diào)用train_model,而train_model有返回值if
<iter
+
1>
%
validation_frequency
==
0:
#
compute
zero-one
loss
on
validation
set
validation_losses
=
[validate_model<i>
for
i
in
xrange<n_valid_batches>]
this_validation_loss
=
numpy.mean<validation_losses>
print<'epoch
%i,
minibatch
%i/%i,
validation
error
%f
%%'
%
<epoch,
minibatch_index
+
1,
n_train_batches,
this_validation_loss
*
100.>>
if
this_validation_loss
<
best_validation_loss:
if
this_validation_loss
<
best_validation_loss
*
\
improvement_threshold:
patience
=
max<patience,
iter
*
patience_increase>
best_validation_loss
=
this_validation_loss
best_iter
=
iter
test_losses
=
[
test_model<i>
for
i
in
xrange<n_test_batches>
]
test_score
=
numpy.mean<test_losses>
print<<'
epoch
%i,
minibatch
%i/%i,
test
error
of
''best
model
%f
%%'>
%
<epoch,
minibatch_index
+
1,
n_train_batches,
test_score
*
100.>>
if
patience
<=
iter:
done_looping
=
Truebreak
end_time
=
time.clock<>
print<'Optimization
complete.'>
print<'Best
validation
score
of
%f
%%
obtained
at
iteration
%i,
''with
test
performance
%f
%%'
%
<best_validation_loss
*
100.,
best_iter
+
1,
test_score
*
100.>>
>>
sys.stderr,
<'The
code
for
file
'
+
os.path.split<__file__>[1]
+
'
ran
for
%.2fm'
%
<<end_time
-
start_time>
/
60.>>
/tutorial/contents.htmlimporttheanofromtheanoimporttensorasTfromimportconv2dimportnumpyrng=numpy.random.RandomState<23455>#instantiate4Dtensorforinputinput=T.tensor4<name='input'>#initializesharedvariableforweights.w_shp=<2,3,9,9>w_bound=numpy.sqrt<3*9*9>W=theano.shared<numpy.asarray<rng.uniform<low=-1.0/w_bound,high=1.0/w_bound,size=w_shp>,dtype=input.dtype>,name='W'>#initializesharedvariableforbias<1Dtensor>withrandomvalues#IMPORTANT:biasesareusuallyinitializedtozero.Howeverinthis#particularapplication,wesimplyapplytheconvolutionallayerto#animagewithoutlearningtheparameters.Wethereforeinitialize#themtorandomvaluesto"simulate"learning.b_shp=<2,>b=theano.shared<numpy.asarray<rng.uniform<low=-.5,high=.5,size=b_shp>,dtype=input.dtype>,name='b'>#buildsymbolicexpressionthatcomputestheconvolutionofinputwithfiltersinwconv_out=conv2d<input,W>#buildsymbolicexpressiontoaddbiasandapplyactivationfunction,i.e.produceneuralnetlayeroutput#Afewwordson``dimshuffle``:#``dimshuffle``isapowerfultoolinreshapingatensor;#whatitallowsyoutodoistoshuffledimensionaround#butalsotoinsertnewonesalongwhichthetensorwillbe#broadcastable;#dimshuffle<'x',2,'x',0,1>#Thiswillworkon3dtensorswithnobroadcastable#dimensions.Thefirstdimensionwillbebroadcastable,#thenwewillhavethethirddimensionoftheinputtensoras#thesecondoftheresultingtensor,etc.Ifthetensorhas#shape<20,30,40>,theresultingtensorwillhavedimensions#<1,40,1,20,30>.<AxBxCtensorismappedto1xCx1xAxBtensor>#Moreexamples:#dimshuffle<'x'>->makea0d<scalar>intoa1dvector#dimshuffle<0,1>->identity#dimshuffle<1,0>->invertsthefirstandseconddimensions#dimshuffle<'x',0>->makearowoutofa1dvector<Nto1xN>#dimshuffle<0,'x'>->makeacolumnoutofa1dvector<NtoNx1>#dimshuffle<2,0,1>->AxBxCtoCxAxB#dimshuffle<0,'x',1>->AxBtoAx1xB#dimshuffle<1,'x',0>->AxBtoBx1xAoutput=T.nnet.sigmoid<conv_out+b.dimshuffle<'x',0,'x','x'>>#createtheanofunctiontocomputefilteredimagesf=theano.function<[input],output>fromimportpoolinput=T.dtensor4<'input'>maxpool_shape=<2,2>pool_out=pool.pool_2d<input,maxpool_shape,ignore_border=True>f=theano.function<[input],pool_out>invals=numpy.random.RandomState<1>.rand<3,2,5,5>print'Withignore_bordersettoTrue:'print'invals[0,0,:,:]=\n',invals[0,0,:,:]print'output[0,0,:,:]=\n',f<invals>[0,0,:,:]pool_out=pool.pool_2d<input,maxpool_shape,ignore_border=False>f=theano.function<[input],pool_out>print'Withignore_bordersettoFalse:'print'invals[1,0,:,:]=\n',invals[1,0,:,:]print'output[1,0,:,:]=\n',f<invals>[1,0,:,:]請注意,術(shù)語"卷積"可以對應于不同的數(shù)學運算:,這是幾乎所有的最近發(fā)表的卷積模型最常用的一個。在該操作中,每個輸出特征映射通過不同的2d濾波器連接到每個輸入特征映射,其值是通過相應濾波器的所有輸入的單個卷積的和。在原來的LeNet模型的卷積:在這項工作中,每個輸出特征映射只能連接到輸入特征映射的一個子集。用于信號處理的卷積:,它只適用于單通道輸入。在這里,我們使用的第一個操作,所以這個模型略有不同,從原來的LeNet研究。使用2的原因之一。將減少所需的計算量,但現(xiàn)代硬件使其具有完全連接模式的快速性。另一個原因是稍微減少自由參數(shù)的數(shù)量,但是我們還有其他的正則化技術(shù)。classLeNetConvPoolLayer<object>:"""PoolLayerofaconvolutionalnetwork"""def__init__<self,rng,input,filter_shape,image_shape,poolsize=<2,2>>:"""AllocateaLeNetConvPoolLayerwithsharedvariableinternalparameters.:paramrng:arandomnumbergeneratorusedtoinitializeweights:paraminput:symbolicimagetensor,ofshapeimage_shape:typefilter_shape:tupleorlistoflength4:paramfilter_shape:<numberoffilters,numinputfeaturemaps,filterheight,filterwidth>:typeimage_shape:tupleorlistoflength4:paramimage_shape:<batchsize,numinputfeaturemaps,imageheight,imagewidth>:typepoolsize:tupleorlistoflength2:parampoolsize:thedownsampling<pooling>factor<#rows,#cols>"""assertimage_shape[1]==filter_shape[1]self.input=input#thereare"numinputfeaturemaps*filterheight*filterwidth"#inputstoeachhiddenunitfan_in=d<filter_shape[1:]>#eachunitinthelowerlayerreceivesagradientfrom:#"numoutputfeaturemaps*filterheight*filterwidth"/#poolingsizefan_out=<filter_shape[0]*d<filter_shape[2:]>//d<poolsize>>#initializeweightswithrandomweightsW_bound=numpy.sqrt<6./<fan_in+fan_out>>self.W=theano.shared<numpy.asarray<rng.uniform<low=-W_bound,high=W_bound,size=filter_shape>,dtype=theano.config.floatX>,borrow=True>#thebiasisa1Dtensor--onebiasperoutputfeaturemapb_values=numpy.zeros<<filter_shape[0],>,dtype=theano.config.floatX>self.b=theano.shared<value=b_values,borrow=True>#convolveinputfeaturemapswithfiltersconv_out=conv2d<input=input,filters=self.W,filter_shape=filter_shape,input_shape=image_shape>#pooleachfeaturemapindividually,usingmaxpoolingpooled_out=pool.pool_2d<input=conv_out,ds=poolsize,ignore_border=True>#addthebiasterm.Sincethebiasisavector<1Darray>,wefirst#reshapeittoatensorofshape<1,n_filters,1,1>.Eachbiaswill#thusbebroadcastedacrossmini-batchesandfeaturemap#width&heightself.output=T.tanh<pooled_out+self.b.dimshuffle<'x',0,'x','x'>>#storeparametersofthislayerself.params=[self.W,self.b]#keeptrackofmodelinputself.input=input注意,在初始化權(quán)重值時,扇入取決于接收字段的大小和輸入特征映射的數(shù)量。最后,利用Logistic回歸和多層感知器的分類MNIST數(shù)字隱含定義類定義的回歸類,我們可以實例化網(wǎng)絡如下。x=T.matrix<'x'>#thedataispresentedasrasterizedimagesy=T.ivector<'y'>#thelabelsarepresentedas1Dvectorof#[int]labels#######################BUILDACTUALMODEL#######################print<'...buildingthemodel'>#Reshapematrixofrasterizedimagesofshape<batch_size,28*28>#toa4Dtensor,compatiblewithourLeNetConvPoolLayer#<28,28>isthesizeofMNISTimages.layer0_input=x.reshape<<batch_size,1,28,28>>#Constructthefirstconvolutionalpoolinglayer:#filteringreducestheimagesizeto<2
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 企業(yè)產(chǎn)品研發(fā)戰(zhàn)略規(guī)劃實施辦法
- 商業(yè)街區(qū)草坪鋪設與維護合同
- 皮革城食堂招投標方案
- 小學安保人員招聘合同書
- 寫字樓租賃合同附辦公設備清單
- 城市綠化景觀設計提升合同
- 賓館電梯改造項目招標模板
- 宿州市物業(yè)消防安全管理
- 2024年還建房及附屬設施聯(lián)合開發(fā)合同
- 超市地坪改造施工合同
- 腦卒中偏癱患者早期康復護理現(xiàn)狀(一)
- 模特的基礎訓練
- 急救技術(shù)-洗胃術(shù) (2)
- 藥品招商流程
- 混凝土配合比檢測報告
- 100道遞等式計算(能巧算得要巧算)
- 【2019年整理】園林景觀設計費取費標準
- 完整word版,ETS5使用教程
- 《血流動力學監(jiān)測》PPT課件.ppt
- 2018年秋季人教版十一冊數(shù)學第7、8單元測試卷
- 學生作業(yè)提交與批閱系統(tǒng)的設計與實現(xiàn)探討
評論
0/150
提交評論