微調CaffeNet用於車顏色識別
說明:主要思想是微調使用ImageNet預訓練的CaffeNet模型引數,用來對車顏色進行識別。為了不和其他檔案混亂,我們在examples下新建資料夾finetune_myself。
1.計算影象均值
caffenet需要影象均值檔案,所以先計算均值檔案。在finetune_myself下新建資料夾Image_mean,從imagenet中拷貝make_imagenet_mean.sh到finetune_myself下,更名為make_image_mean.sh(為了和imagenet區分),然後修改指令碼如下:
EXAMPLE=examples/finetune_myself #該路徑下為訓練影象的lmdb檔案 DATA=examples/finetune_myself/Image_mean #該路徑為生成的均值檔案儲存的地方 TOOLS=build/tools $TOOLS/compute_image_mean $EXAMPLE/car_train_lmdb \ #這裡的lmdb和自己的對應 $DATA/image_mean.binaryproto #生成的均值檔名字,這裡為了區分改一下名字
這樣,生成的均值檔案儲存在finetune_myself下的Image_mean資料夾裡,名字為image_mean.binaryproto。
2.準備caffenet模型
在finetune_myself下新建資料夾,命名為models,將caffenet的train_val.prototxt、solver.prototxt和deploy.prototxt複製到此models資料夾裡,然後,對模型進行修改。假設我們的訓練集類別是m,那麼fc8層的num_output需要修改成m,又由於finetune時用到的權重是根據層名匹配的,而fc8的num_output已經修改,該層的引數必須重新學習,所以我們把該層的名字也進行修改,如改為fc8_myself。具體修改如下。
對train_val.prototxt的修改:
(1) mean_file路徑:"examples/finetune_myself/Image_mean/image_mean.binaryproto"
訓練和測試階段的data層均要修改。
(2)假設訓練集和測試集的lmdb檔案在finetune_myself下,所以訓練階段的的data層:
data_param {
source:"examples/finetune_myself/car_train_lmdb"
batch_size: 50 #這裡自己可以修改合適的batch大小
backend:LMDB
}
同理,TEST階段的data層也作同樣的修改。即:
data_param{
source: "examples/finetune_myself/car_test_lmdb"
batch_size:50
backend:LMDB
}
(3)修改fc8層和相關層
將層名改為fc8_myself(當然其他也行),並修改權重的lr_mult=10,bias的lr_mult=20,目的是讓非微調層學習更快。num_output修改為類別數。具體如下:
layer {
name: "fc8_myself"
type: "InnerProduct"
bottom: "fc7"
top: "fc8_myself"
param {
lr_mult: 10
decay_mult: 1
}
param {
lr_mult: 20
decay_mult: 0
}
inner_product_param {
num_output: 8 #根據類別修改,我做的實驗為8類
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}
與fc8相關的層也要修改:
layer {
name:"accuracy"
type:"Accuracy"
bottom: "fc8_myself"
bottom:"label"
top:"accuracy"
include {
phase: TEST
}
}
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "fc8_myself"
bottom: "label"
top: "loss"
}
對solver.prototxt的修改:
主要是net:"examples/finetune_myself/models/train_val.prototxt",
該路徑改為train_val.Prototxt的路徑。
還有
snapshot_prefix:"examples/finetune_myself/models/caffenet"
此路徑是訓練過程得到的caffemodel和solverstate儲存路徑,按自己想儲存的路徑更改。
對deploy.prototxt的修改:
網路的名字name要與train_val.prototxt相同。然後修改fc8層和相關層:
layer {
name: "fc8_myself"
type: "InnerProduct"
bottom: "fc7"
top: "fc8_myself"
inner_product_param {
num_output: 8 #根據類別數改
}
}
layer {
name:"prob"
type:"Softmax"
bottom: "fc8_myself"
top:"prob"
}
這樣,模型就改好了。
3.準備預訓練好的caffenet模型引數
finetune_myself下新建資料夾pre_train_models,執行
./scripts/download_model_binary.py examples/finetune_myself/pre_train_models
即將檔案下載在pre_train_models中。
4.開始訓練
./build/tools/caffe train –solver examples/finetune_myself/models/solver.ptototxt –weights examples/finetune_myself/pre_train_models/bvlc_reference_caffenet
5.結果
訓練結果:
精度還是挺高的。
測試:
./build/examples/cpp_classification/classification.bin **/**/deploy.prototxt **/***/models_iter_100000.caffemodel **/**/image_mean.binaryproto **/**/labels.txt **/**/car.jpg
這些路徑按自己的設定,labels是標籤,比如你的train.txt中白色標籤是0,紅色標籤是1,那麼labels中第一行是white,第二行是red,其他的也是這樣按順序排。
結果:
white - "0.9963"
gray - "0.0036"
green - "0.0001"
輸出前三個預測結果