caffe的finetuning是如何更新網路參數的?
01-23
大家好,一直很困惑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深度學習框架 |