caffe 學習系列之finetuning
在安裝好caffe之後,下一步自然就是執行一些demo 來玩下。
在caffe 的官網的notebook 中已經介紹瞭如何對caffe 提供的demo 的資料集進行finetuning, 這裡就不過多的介紹了。caffe finetuning 的demo
這一篇主要是介紹如何用caffe提供的model 來訓練我們自己的資料集。
我用的系統是mac osx 10.11 EI, 主要實現的工具是使用terminal 終端和caffe c++ 的命令列介面
- 資料集是大概16000張照片,主要是對這些照片的9中照片做影象的分類。(因為這是我的一個課程作業,老師提供了大概3000張左右的照片給我們預測,預測結果在課程網站上面直接顯示出來,所以我沒有從訓練集選擇30%的照片作為測試集來驗證。如果想要自己訓練並且測試的話,可以寫一個小程式自己生成訓練集和測試集。)
我把我的測試集放到百度雲了
連結:
有興趣的同學可以去下載下來玩一玩。
資料集包括了16000張照片 和 包含他們檔案位置和label 的train.txt
2.選擇的model 是caffe 提供的googlenet, 它是2014 ilvsrc 影象分類比賽的冠軍。裝好caffe之後,可以在命令列進入caffe的根目錄之後輸入:
python scripts/download_model_binary.py models/bvlc_reference_googlenet
然後會下載一個大概50M 左右的googlenet.caffemodel 下載完成之後可以在 models/bvlc_googlenet/ 的資料夾中看到 以下檔案:
train_val.prototxt
quick_solver.prototxt
solver.prototxt
deploy.protoxt
bvlc_googlenet.caffemodel
readme.md
3.在model 下載完成之後,下一步是要使用caffe tools中的convert_imagenet 把我們的資料集轉成LMDB 格式。(在caffe中資料預設是通過LMDB 格式來存取的,所以要轉格式。)當然,caffe 的框架也有提供其他的格式存取,不過入門的話還是用LMDB 比較方便。
轉格式的程式碼如下:
進入caffe 根目錄
GLOG_logtostderr=1 ./build/tools/convert_imageset \
/這裡寫的是照片根目錄的路徑 \
/這裡寫的是train.txt 的路徑 \
/這裡寫的是生成的train_lmdb 存的路徑 \
要注意的是:在命令列輸入命令的時候,每個路徑之間是用空格隔開的,要是想要換行可以輸入 \
如果報錯的話 看它提示的error,一般就是找不到照片的檔名或者存train_lmdb 的路徑出錯。 第一個問題在train.txt 的照片檔案寫檔案的絕對路徑,第二個問題就要看原來的路徑下面是不是已經存在一個這樣的lmdb檔案夾了,如果有就把它刪除就可以了。
轉成lmdb 格式之後,下一步是生成mean.binaryproto
使用下面這個命令
./build_release/tools/compute_image_mean /path/to/train_lmdb /path/to/train_mean.binaryproto
兩個檔名:一個是train_lmdb 的路徑,一個是生成的mean.binaryproto 的路徑
4.在資料格式準備完成之後,我們就是要修改原來的solver 或者quick_solver 的檔案來進行訓練了。
我們來看下solver.prototxt
net: "models/bvlc_googlenet/train_val.prototxt" # 這個是caffemodel 在的路徑,預設是相對路徑,也可以改成絕對路徑
#test_iter: 1000 # 要是有測試集的話就可以用這個
#test_interval: 4000 # 也可以直接用全部訓練集訓練,然後輸出正確率
#test_initialization: false # 這樣就不需要用到這個了
display: 40 # 這裡是每隔40個迴圈就顯示一次結果
average_loss: 40
base_lr: 0.01 # 這個是基本的學習率
lr_policy: "step"
# 這個是每過一定數量的迴圈之後就降低學習率,可以改成"fixed" 把學習率固定下來
stepsize: 320000 # 這個就設定下降學習率的step size
gamma: 0.96 # 下降是 * gamma
max_iter: 10000000 # 迴圈的次數
momentum: 0.9 # 衝量,一般都是0.9
weight_decay: 0.0002
snapshot: 40000
snapshot_prefix: "models/bvlc_googlenet/bvlc_googlenet"
solver_mode: GPU
然後我們還要設定train_val.prototxt:
由於這個比較長,所以我就只貼要修改的地方了:
layer {
name: "data"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN # 還有一個data layer 這裡是TEST 的,可以把那個layer註釋掉,我沒有使用到它
}
transform_param { # 這裡也可以放mean.binaryproto
mirror: true
crop_size: 224
mean_value: 104
mean_value: 117
mean_value: 123
}
data_param {
source: "/path/to/train_lmdb" # 這裡是要改的地方
batch_size: 16
backend: LMDB
}
}
layer {
name: "fc8_flickr" # 這裡原來是fc8, 但是我們要改成我們自己名字,這樣就不會報錯啦
type: "InnerProduct"
bottom: "fc7"
top: "fc8_flickr" # 這裡也要改
# lr_mult is set to higher than for other layers, because this layer is starting from random while the others are already trained
param {
lr_mult: 10
decay_mult: 1
}
param {
lr_mult: 20
decay_mult: 0
}
inner_product_param {
num_output: 9 # 這裡我只分9類,所以就num_output 就是9
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "loss3/loss3"
type: "SoftmaxWithLoss"
bottom: "fc8_flickr"
bottom: "label"
top: "loss3/loss3"
loss_weight: 1
}
layer {
name: "loss3/top-1"
type: "Accuracy"
bottom: "fc8_flickr"
bottom: "label"
top: "loss3/top-1"
include {
phase: TRAIN # 這裡改成train 每次都可以輸出正確率了
}
}
在修改完solver 和train_val 之後,就可以嘗試train了
進入caffe 根目錄
./build/tools/caffe train -solver /path/to solver -weights /path/to/yourname.caffemodel
要是訓練到一半退出了,caffe會儲存一個snapshot,我們可以重新恢復訓練
./build/tools/caffe train -solver /path/to solver -snapshot /path/to/yourname.solverstate
下一篇將會介紹caffe 的python介面 和視覺化測試