本文轉載自:https://blog.csdn.net/fx409494616/article/details/53008971
如果要把訓練好的模型拿來測試新的圖片,那必須得要一個deploy.prototxt文件,這個文件實際上和test.prototxt文件差不多,只是頭尾不相同而已。
1. train_val.prototxt
首先,train_val.prototxt文件是網絡配置文件。該文件是在訓練的時候用的。
2.deploy.prototxt
該文件是在測試時使用的文件。
區別:
首先deploy.prototxt文件都是在train_val.prototxt文件的基礎上刪除了一些東西,所形成的。
由於兩個文件的性質,train_val.prototxt文件裏面訓練的部分都會在deploy.prototxt文件中刪除。
在train_val.prototxt文件中,開頭要加入一下訓練設置文件和準備文件。例如,transform_param中的mirror: true(開啓鏡像);crop_size: ***(圖像尺寸);mean_file: ""(求解均值的文件),還有data_param中的source:""(處理過得數據訓練集文件);batch_size: ***(訓練圖片每批次輸入圖片的數量);backend: LMDB(數據格式設置)。
然後接下來,訓練的時候還有一個測試的設置,測試和訓練模式的設置通過一個include{phase: TEST/TRAIN}來設置。接下來就是要設置TEST模塊內容。然後其他設置跟上面一樣,裏面有個batch_size可以調小一點,因爲測試的話不需要特別多的圖片數量。
而以上這一塊的內容在deploy裏表現出來的只有一個數據層的設置。只需設置name,type,top,input_param這些即可。
接下來,第一個卷積層的設置,train_val.prototxt文件中多了param(反向傳播學習率的設置),這裏需要設置兩個param一個時weight的學習率,一個時bias的學習率,其中一般bias的學習率是weight學習率的兩倍。然後就是設置convolution_param,但是在train_val裏面需要有對weight_filler的初始化和對bias_filler的初始化。
然後就是設置激活激活函數。這一塊由於沒有初始化,所以兩個文件都是一樣的。
再接下來就是池化層,由於池化就是降低分辨率,所以這兩邊是一樣的,只需要設置kernel_size,stride,pool即可。無需參數的初始化。
再下來時LRN層,該層的全稱是Local Response Normalization(局部響應值歸一化),該層的作用就是對局部輸入進行一個歸一化操作,不過現在有論文表明,這一層加不加對結果影響不是很大。但這一層的定義都是相同的。
再接下來就是"conv2"、"relu2"、"pool2"、"LRN2"這樣的循環,具體跟之前說的一樣,train_val主要多的就是參數的初始化和學習率的設置。
在第五個卷積層之後,進入了"fc6"層,該層是全連接層,這裏train_val裏面還是多兩個param學習率的設置,和weight_filler、bias_filler的初始化設置,而兩者共同的是有一個輸出向量元素個數的設置:inner_product_param。
再接下來就是激活函數RELU。
再接下來就是Dropout層,該層的目的就是爲了防止模型過擬合。這其中有一個dropout_ration的設置一般爲0.5即可。
再接下來就是"fc7",這一層跟"fc6"相同。然後就是"relu7"、"drop7"都是相同的。然後就是"fc8"也與之前相同。
再接下來就是Accuracy,這個層是用來計算網絡輸出相對目標值的準確率,它實際上並不是一個損失層,所以沒有反傳操作。但是在caffe官網中,它在損失層這一部分。所以在deploy.prototxt文件中,這一層的定義是沒有的。
再接下來train_val的最後一個層是"SoftmaxWithLoss"層,也是簡單的定義了name,type,bottom,top就完了。而這一塊的內容也不在deploy.prototxt文件中。
而在deploy.prototxt文件中直接定義了一個type:"Softmax"。
通過對CaffeNet這兩個文件的查看發現deploy.prototxt文件和train_val.prototxt文件之間的差異在很多層裏面牽扯到訓練部分的都會被刪除,然後就是反向傳播訓練部分會被刪除。
其中,這裏面有一個區別在裏頭,就是爲什麼train_val裏面的是SoftmaxWithLoss而deploy裏面的是Softmax層(兩個都是損失層,都沒有任何參數):
這裏面其實都是softmax迴歸的應用,只是在定義成Softmax時直接計算了概率forward部分,而在SoftmaxWithLoss部分時是還有backward的部分。所以這裏就出現了區別,具體的區別可以看這兩個文件的C++定義。
具體改動示例:
輸入數據層改動如下:
name: "SpecNet"
layer {
name: "spectr"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
scale: 0.00390625
}
data_param {
source: "../data/train"
batch_size: 15
backend: LMDB
}
}
layer {
name: "spectr"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
scale: 0.00390625
}
data_param {
source: "../data/valid"
batch_size: 15
backend: LMDB
}
}
# Layer 1 128x128x1
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 1
}
...
...
...
改爲:
name: "SpecNet"
layer {
name: "data"
type: "Input"
top: "data"
input_param { shape: { dim: 1 dim: 3 dim: 128 dim: 128 } }
}
# Layer 1 128x128x1
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 1
}
...
...
...
dim: 1 num,對待識別樣本進行數據增廣的數量,可自行定義。一般會進行5次crop,之後分別flip。如果該值爲10則表示一個樣本會變成10個,之後輸入到網絡進行識別。如果不進行數據增廣,可以設置成1
dim: 3 通道數,表示RGB三個通道
dim: 128 圖像的長和寬
輸出層數據改動:
# Classification Layer 6x1
layer {
name: "accuracy"
type: "Accuracy"
bottom: "ip2"
bottom: "label"
top: "accuracy"
}
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
top: "loss"
}
...
...
...
改爲:
# Classification Layer 6x1
#layer {
# name: "accuracy"
# type: "Accuracy"
# bottom: "ip2"
# bottom: "label"
# top: "accuracy"
#}
layer {
name: "prob"
type: "Softmax"
bottom: "ip2"
# bottom: "label"
top: "prob"
}
...
...
...