一般來(lái)說(shuō)我們通常都是需要在一些特定的領(lǐng)域里來(lái)識(shí)別分類(lèi),比如服裝類(lèi)、標(biāo)志等等,但是深度學(xué)習(xí)中數(shù)據(jù)集的準(zhǔn)備一直是最令人頭疼的一件事。我們很難拿到大量的數(shù)據(jù)。在這種情況下重新訓(xùn)練的一個(gè)新的網(wǎng)絡(luò)是比較復(fù)雜,且參數(shù)也不好調(diào)整,因此數(shù)據(jù)集為圖像時(shí),通過(guò)fine-tuning微調(diào)是一個(gè)比較理想的選擇。Fine-tuning的整體思路就是,ImageNet是一個(gè)千萬(wàn)級(jí)的圖像數(shù)據(jù)庫(kù),現(xiàn)已經(jīng)在ImageNet上訓(xùn)練了一個(gè)很牛的網(wǎng)絡(luò),我們可以把pretrain的網(wǎng)絡(luò)拿過(guò)來(lái),然后只重新訓(xùn)練最后幾層。意思就是以前需要分成1000類(lèi),現(xiàn)在只需要識(shí)別是狗還是貓,或者衣服是上衣還是褲子。故就只需要把最后一層softmax從40961000的分類(lèi)器變成40922的分類(lèi)器。微調(diào)網(wǎng)絡(luò)需要一個(gè)已初始化的模型參數(shù)文件,這里不同于用某某網(wǎng)絡(luò)訓(xùn)練自己的數(shù)據(jù)集方法。后者在訓(xùn)練過(guò)程中,這些參數(shù)都被隨機(jī)的初始化。而fine-tuning是在已訓(xùn)練好的參數(shù)的基礎(chǔ)上,根據(jù)我們的分類(lèi)識(shí)別任務(wù)進(jìn)行特定的微調(diào)??偠灾?,fine-tuning這種策略目前在應(yīng)用中是非常好使的。接下來(lái)介紹一下fine-tuning流程以及簡(jiǎn)單介紹一下該如何調(diào)參。
fine-tuning流程
對(duì)網(wǎng)絡(luò)進(jìn)行微調(diào)的整個(gè)流程可以分為以下幾步:
- 準(zhǔn)備數(shù)據(jù)集(包括訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù))
- 計(jì)算數(shù)據(jù)集的均值文件,因?yàn)槟硞€(gè)特定領(lǐng)域的圖像均值文件會(huì)跟ImageNet上的數(shù)據(jù)均值不太一樣
- 修改網(wǎng)絡(luò)最后一層的輸出類(lèi)別數(shù),以及最后一層網(wǎng)絡(luò)的名稱(chēng),加大最后一層的參數(shù)學(xué)習(xí)速率
- 調(diào)整solver的配置參數(shù)
- 加載預(yù)訓(xùn)練模型的參數(shù),啟動(dòng)訓(xùn)練
1. 準(zhǔn)備數(shù)據(jù)集(建立與下載)
前面幾篇筆記已經(jīng)有所介紹了,就是下載數(shù)據(jù)然后轉(zhuǎn)成LMDB格式。
2. 計(jì)算數(shù)據(jù)集的均值文件
3. 調(diào)整網(wǎng)絡(luò)參數(shù)
參照caffe上的例程,可以使用CaffeNet,復(fù)制caffenet的train_val.prototxt到自己的目錄下,或者復(fù)制官網(wǎng)給出的例子——Fine-tuning CaffeNet for Style Recognition on “Flickr Style” Data,下載完之后,模型會(huì)放在models的finetune_flickr_style中,可以參考里面的那些文件,適當(dāng)修改一些地方即可。個(gè)人建議:不管訓(xùn)練什么模型,最好自己新建一個(gè)目錄,然后把所有需要的文件拷貝到該目錄下,然后根據(jù)自己的需求更改。本文是在examples/下新建了一個(gè)blog_img目錄。該文件需要修改的地方如下:train_val.prototxt(1)修改source和meanfile
name: "BlogNet" #這里的名字可修改可不修改,根據(jù)自己的意愿
layer {
name: "data"
type: "ImageData"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
mirror: true
crop_size: 227
mean_file: "data/blog_img/train_mean.binaryproto" #這里是第二步求得的均值文件所在的地方
}
image_data_param {
source: "data/blog_img/train_lmdb" #訓(xùn)練集所在的地方
batch_size: 512 #可根據(jù)自己內(nèi)存情況調(diào)整,最好是8的倍數(shù)
new_height: 256 #在finetuning的時(shí)候,新問(wèn)題的圖像大小不同于pretraining的圖像大小時(shí),只能縮放到同樣的大小
new_width: 256
}
}
layer {
name: "data"
type: "ImageData"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
mirror: false
crop_size: 227
mean_file: "data/blog_img/test_mean.binaryproto "
}
image_data_param {
source: "data/blog_img/test_lmdb" #測(cè)試集所在的地方
batch_size: 128
new_height: 256
new_width: 256
}
}
(2)修改輸出層fc8
layer {
name: "fc8_bogimg" #修改名字,這樣預(yù)訓(xùn)練模型賦值時(shí)會(huì)因?yàn)槊植黄ヅ鋸亩匦掠?xùn)練,也就達(dá)到了適應(yīng)新任務(wù)的目的
type: "InnerProduct"
bottom: "fc7"
top: "fc8_blogimg"
# 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 #調(diào)整學(xué)習(xí)率,因?yàn)樽詈笠粚邮侵匦聦W(xué)習(xí)的,因此需要比其他層更快的學(xué)習(xí)速率,因此將weight和bias都增加10倍,其他層為1或2,如果
decay_mult: 1 #數(shù)據(jù)集過(guò)小,可以將其他層的學(xué)習(xí)率置為0,只訓(xùn)練最后一層
}
param {
lr_mult: 20 #上同
decay_mult: 0
}
inner_product_param {
num_output: 5 #修改為你想識(shí)別的類(lèi)別數(shù)
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "accuracy"
type: "Accuracy"
bottom: "fc8_blogimg" #別忘了還有這里的名字(fc8層的名字)
bottom: "label"
top: "accuracy"
include {
phase: TEST
}
}
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "fc8_blogimg" #別忘了還有這里的名字(fc8層的名字)
bottom: "label"
top: "loss"
}
solver.prototxt
微調(diào),顧名思義微微調(diào)整,所以一般來(lái)說(shuō),相比較于用某網(wǎng)絡(luò)結(jié)構(gòu)直接訓(xùn)練自己的數(shù)據(jù)集來(lái)說(shuō),學(xué)習(xí)速率、步長(zhǎng)、迭代次數(shù)都減小。修改地方如下:
net: "examples/blog_img/train_val.prototxt"
test_iter: 100
test_interval: 1000
# lr for fine-tuning should be lower than when starting from scratch
base_lr: 0.001
lr_policy: "step"
gamma: 0.1
# stepsize should also be lower, as we're closer to being done
stepsize: 5000
display: 100
max_iter: 10000
momentum: 0.9
weight_decay: 0.0005
snapshot: 5000
snapshot_prefix: "examples/blog_img/img_type"
# uncomment the following to default to CPU mode solving
solver_mode: GPU
- 開(kāi)始訓(xùn)練
./build/tools/caffe train -solver examples/blog_img/solver.prototxt -weights models/bvlc_reference_caffenet /bvlc_reference_caffenet .caffemodel -gpu 0
預(yù)測(cè)效果
