Caffe網路結構實現
對於神經網路實現手寫數字識別(MNIST)網路結構通過線上視覺化工具檢視和修改:
(http://ethereon.github.io/netscope/#/editor )
一、卷積層(Convolution)
輸入為28*28的影象,經過5*5的卷積之後,得到一個(28-5+1)*(28-5+1) = 24*24的map。
每個map是不同卷積核在前一層每個map上進行卷積,並將每個對應位置上的值相加然後再加上一個偏置項。
二、池化層(Pooling)
輸入為卷積層1的輸出,大小為24*24,對每個不重疊的2*2的區域進行降取樣。對於max-pooling,選出每個區域中的最大值作為輸出。而對於mean-pooling,需計算每個區域的平均值作為輸出。最終,該層輸出一個(24/2)*(24/2)的map
三、啟用層(ReLU)
啟用函式是用來引入非線性因素的。當啟用函式輸出值是有限的時候,基於梯度的優化方法會更加穩定,因為特徵的表示受有限權值的影響更顯著;當啟用函式的輸出是無限的時候,模型的訓練會更加高效,不過在這種情況小,一般需要更小的learning rate.
Type為該層型別,可取值分別為:
1、ReLU:表示我們使用relu啟用函式,relu層支援in-place計算,這意味著該層的輸入和輸出共享一塊記憶體,以避免記憶體的消耗。
2、Sigmoid:代表使用sigmoid函式;
3、TanH:代表使用tanh函式;
4、AbsVal:計算每個輸入的絕對值f(x)=Abs(x)
5、Power對每個輸入資料進行冪運算
f(x)= (shift + scale * x) ^ power
層型別:Power
可選引數:
power: 預設為1
scale: 預設為1
shift: 預設為0
四、全連線層(InnerProduct)
50*4*4=800個輸入結點和500個輸出結點
五、softmax層
Softmax迴歸模型是logistic迴歸模型在多分類問題上的推廣,在多分類問題中,待分類的類別數量大於2,且類別之間互斥。通常情況下softmax會被用在網路中的最後一層,用來進行最後的分類和歸一化。
神經網路實現手寫數字識別(MNIST)的 prototxt 檔案原始碼:
name: "LeNet"
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
scale: 0.00390625
}
data_param {
source: "/home/gh/caffe/examples/mnist/mnist_train_lmdb"
batch_size: 64
backend: LMDB
}
}
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
scale: 0.00390625
}
data_param {
source: "/home/gh/caffe/examples/mnist/mnist_test_lmdb"
batch_size: 100
backend: LMDB
}
}
layer {
name: "conv1" #卷積層1
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1 #學習率1,和權值更新相關
}
param {
lr_mult: 2 #學習率2,和權值更新相關
}
convolution_param {
num_output: 20 #20個輸出的map
kernel_size: 5 #卷積核大小為5*5
stride: 1 #卷積步長為1
weight_filler { #權值初始化方式
type: "xavier" #預設為“constant",值全為0,很多時候我們也可以用"xavier"或者”gaussian"來進行初始化
}
bias_filler { #偏置值的初始化方式
type: "constant" #該引數的值和weight_filler類似,一般設定為"constant",值全為0
}
}
}
layer {
name: "pool1" #池化層1
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX #Pool為池化方式,預設值為MAX,可以選擇的引數有MAX、AVE、STOCHASTIC
kernel_size: 2 #池化區域的大小,也可以用kernel_h和kernel_w分別設定長和寬
stride: 2 #步長,即每次池化區域左右或上下移動的距離,一般和kernel_size相同,即為不重疊池化。也可以也可以小於kernel_size,即為重疊池化,Alexnet中就用到了重疊池化的方法
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 50
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu1"
type: "ReLU" #relu啟用函式層支援in-place計算,這意味著該層的輸入和輸出共享一塊記憶體,以避免記憶體的消耗。
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 10
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "accuracy"
type: "Accuracy"
bottom: "ip2"
bottom: "label"
top: "accuracy"
include {
phase: TEST
}
}
layer { #可以計算給出每個樣本對應的損失函式值
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
top: "loss"
}