針對Training LeNet on MNIST with Caffe的Demo分析
1税迷、設(shè)置網(wǎng)絡(luò)文件的存儲位置
@CAFFE_ROOT/src/caffe/proto/caffe.proto
設(shè)置文件存儲在一個.proto文件里面,在這里面設(shè)置了我們所要的網(wǎng)絡(luò)特性和參數(shù)
2谦炬、定義自己的網(wǎng)絡(luò)
首先從整理的來看一下,在這個Demo里面我們定義了一下幾個Layer(用Type名代替)
Data:
layer {
name: "mnist"
type: "Data"
transform_param {
scale: 0.00390625
#為什么是0.00290625呢皮迟,這個值是1/255
#原因是普通圖片是RGB格式0~255庶喜,而Caffe里面是RBG是0~1故做此操作
}
data_param {
source: "mnist_train_lmdb"
backend: LMDB
batch_size: 64
#直譯是批量大小,也就是說一次讀入多少張圖片
}
top: "data"
top: "label"
#輸出到data和label
}
Convolution:(顧名思義就是卷積層揍庄,但是這個Blob是存的是“Data”Blob卷積運算后的)
layer {
name: "conv1"
type: "Convolution"
param { lr_mult: 1 }
param { lr_mult: 2 }
#LearnRate 1是整體同步咆蒿,2是整體2倍(此處理解的還不是很清楚
convolution_param {
num_output: 20
#這次卷積有多少個核函數(shù)
kernel_size: 5
#窗口5X5,就是這次運算取了5X5的像素點蚂子,
#什么是窗口蜡秽,我目前對窗口理解就是在圖像中取一個小塊
stride: 1
#stride步長,一次滑一個像素點
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
#偏移是常量
}
}
bottom: "data"
#數(shù)據(jù)來源(上一個Blob)是data
top: "conv1"
#輸出到conv1 Blob
}
Pooling:
layer {
name: "pool1"
type: "Pooling"
pooling_param {
kernel_size: 2
stride: 2
pool: MAX
#窗口2X2缆镣,步長2
}
bottom: "conv1"
top: "pool1"
#輸出到pool1這個Blob
}
卷積層輸出的是圖像的特征圖,然后為了解決過度擬化和計算量大的問題试浙,Pooling層對卷積層的輸出進行采樣董瞻,以達到減小特征圖分辨率的目的。
InnerProduct:(Fully Connected Layer)(InnerProduct中文是內(nèi)積)
layer {
name: "ip1"
type: "InnerProduct"
param { lr_mult: 1 }
param { lr_mult: 2 }
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
bottom: "pool2"
top: "ip1"
}
這個嘛田巴,這層以目前的理解有點像是ANN里面的分類的過程钠糊,之前的Conv和Pooling都是不停的提取特征值,而這里是真正分類的過程壹哺。
ReLU:(和tanh和sigmod激活不同另一種激活函數(shù))
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
ReLU層是激活層的一種類型抄伍,參考的AlexNet論文,可以看出和之前的激活函數(shù)不同管宵,ReLU的激活函數(shù)模仿了自然界中局部神經(jīng)元會相互抑制的特性截珍,在計算本神經(jīng)元輸出的時候會考慮到周圍的神經(jīng)元的輸出(看一眼公式就知道了)。
LossLayer:
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
}
? 這個層的目的就是對前向傳播以后的結(jié)果同預(yù)期結(jié)果做對比箩朴,看之間相差了多少岗喉,這個也是反向傳播的時候一個重要的依據(jù)。在這里它的type主要是改變損失函數(shù)炸庞,不同的損失函數(shù)有不同的效果钱床。損失函數(shù)的計算結(jié)果會直接的影響反向傳播算法中的梯度計算,所以這里算是一個調(diào)整參數(shù)的重要位置埠居。
? 在這個層中有一個不設(shè)置損失函數(shù)查牌,那就是Accuracy類型事期,這個類型就是單純的輸出測試的準確度的。
? loss層不做任何輸出纸颜,在反向傳播的開始的時候使用兽泣,原文中的最后一句話問有意思。
? “This is where all magic starts”
? 畢竟梯度計算的最開始就是這里懂衩,算出最后一層的梯度以后撞叨,之前的梯度都和下一層的的梯度相關(guān)。
3浊洞、定義Solver
Solver文件以我現(xiàn)在淺薄的理解看來是一個怎么運行網(wǎng)絡(luò)牵敷,定義怎么輸出的作用
它存放在以下位置
$CAFFE_ROOT/examples/mnist/lenet_solver.prototxt
# The train/test net protocol buffer definition
net: "examples/mnist/lenet_train_test.prototxt"
test_iter: 100
# 迭代100次,舉個例子就是網(wǎng)絡(luò)中一次讀入假設(shè)100個圖法希,100次迭代就是讀了10000個圖
test_interval: 500
# 每500次迭代用Test數(shù)據(jù)集輸出一次測試結(jié)果
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0005
#lr是LearnRate的意思枷餐,weight_decay是每次修正多少weight的意思
lr_policy: "inv"
gamma: 0.0001
power: 0.75
# 這個是learning rate policy,gamma和power是inv模式需要的參數(shù)(這個大體就是一個函數(shù)
display: 100
# Display every 100 iterations
max_iter: 10000
# The maximum number of iterations
# snapshot intermediate results
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet"
#prefix是前綴的意思
# solver mode: CPU or GPU
solver_mode: GPU
? 在這部分的base_lr,lr_policy都是調(diào)整學(xué)習(xí)速率用的苫亦,也是后期調(diào)整參數(shù)的重要位置毛肋。學(xué)習(xí)速率是再反向傳播算法中出現(xiàn)的当编,它是公式中用梯度進行調(diào)整的時候旋奢,梯度前面的參數(shù),類似y=kx+b钻心,前面的k唉匾。在公式中一般都記做α孕讳。base_lr為基礎(chǔ)學(xué)習(xí)速率,顧名思義就是最最開始的時候?qū)W習(xí)速率的值巍膘,而lr_policy就是調(diào)整學(xué)習(xí)速率的方法厂财,選擇不同的方法則下面要跟的參數(shù)就不一樣。剩下的部分峡懈,覺得大概就直接看就能看得懂璃饱。
4、訓(xùn)練和測試Model
去相應(yīng)的位置運行.sh文件即可肪康,Demo中的位置是
cd $CAFFE_ROOT
./examples/mnist/tran_lenet.sh
5荚恶、其他細節(jié)
在測試的時候,可以根據(jù)自己的顯卡顯存梅鹦,來調(diào)整batch_size的大小裆甩,來調(diào)整,
可以在運行了一段時間后使用以下代碼來查看
nvidia-smi
初次紀錄2017/3/16齐唆。學(xué)長講解后
記錄修正2017/6/10嗤栓。畢業(yè)晚會第二天