caffe的finetuning是如何更新網路參數的?

大家好,一直很困惑caffe在做fine-tuning時,有兩個問題:

1.如果將imagenet訓練得到的網路最後的softmax層的輸出由1000改為20,那麼用自己的數據進行訓練後,之前net中的卷積層,全連接層的參數是否會發生更新?

2.假設fine-tune時網路參數發生變化,我不想讓某些特定層的參數在fine-tuning的時候發生變化,是否可以將這些層的學習率置0?

謝謝!


1、會更新,finetune的過程相當於繼續訓練,跟直接訓練的區別是初始化的時候:

a. 直接訓練是按照網路定義指定的方式初始化(如高斯隨機初始化)

b. finetune是用你已經有的參數文件來初始化(就是之前訓練好的caffemodel)

2、嗯,這個問題有兩種情況:比如有4個全連接層A-&>B-&>C-&>D

a. 你希望C層的參數不會改變,C前面的AB層的參數也不會改變,這種情況也就是D層的梯度不往前反向傳播到D層的輸入blob(也就是C層的輸出blob 沒有得到梯度),你可以通過設置D層的propagate_down為false來做到。

propagate_down的數量與輸入blob的數量相同,假如你某個層有2個輸入blob,那麼你應該在該layer的Param裡面寫上兩行:

propagate_down : 0 # 第1個輸入blob不會得到反向傳播的梯度

propagate_down : 0 # 第2個輸入blob不會得到反向傳播的梯度

這樣的話,你這個layer的梯度就不會反向傳播啦,前面的所有layer的參數也就不會改變了

b. 你希望C層的參數不會改變,但是C前面的AB層的參數會改變,這種情況,只是固定了C層的參數,C層得到的梯度依然會反向傳播給前面的B層。只需要將對應的參數blob的學習率調整為0:

你在layer裡面加上param { lr_mult: 0 }就可以了,比如全連接層裡面:

layer {

type: "InnerProduct"

param { # 對應第1個參數blob的配置,也就是全連接層的參數矩陣的配置

lr_mult: 0 # 學習率為0,其他參數可以看caffe.proto裡面的ParamSpec這個類型

}

param { # 對應第2個參數blob的配置,也就是全連接層的偏置項的配置

lr_mult: 0 # 學習率為0

}

}

不知道這樣說你能不能理解...


樓上關於finetuning如何freeze的方法已經說得很清楚了,這邊在補充自己最近關於freeze的體會。

做freeze操作時,通常還會根據數據集在不同情況進行有選擇的性的finetune。

如small datasets時,可以freeze前面conv layer-&> fc4086來提取cnn在imagenet上的多類泛化特徵來輔助作為分類的feature,再對如這邊revise的fc-20-&>softmax進行training。

以此類推,如果是medium datasets則freeze到一半的conv。個人理解這樣做的很大原因在於lower level layer具有更強泛化的basic feature,同時記得考量你的數據來選擇。

如下圖總結:

順便再引自cs231n lecture11的話「more data = retain more of the network(or all of it)"

以及learning rate 的tips:

「use only ~1/10th of the original learning rate in finetuning top layer,and ~1/100th on intermedia layers」


推薦閱讀:

caffe 每個樣本對應多個label?
CNN全連接層隱層結點數(output_dim)的設定有什麼講究嗎?
Ubuntu這麼難安裝嗎?

TAG:Caffe深度學習框架 |