【轉】微調Finetuning


原文鏈接:https://blog.csdn.net/julialove102123/article/details/78510147

模型的微調   

  使用別人訓練好的網絡模型進行訓練,前提是必須和別人用同一個網絡,因為參數是根據網絡而來的。當然最后一層是可以修改的,因為我們的數據可能並沒有1000類,而只有幾類。把最后一層的輸出類別和層的名稱改一下就可以了。用別人的參數、修改后的網絡和自己的數據進行訓練,使得參數適應自己的數據,這樣一個過程,通常稱之為微調(fine tuning). 

微調時候網絡參數是否更新  

  更新,finetune的過程相當於繼續訓練,跟直接訓練的區別是初始化的時候: 
   a. 直接訓練是按照網絡定義指定的方式初始化(如高斯隨機初始化) 

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

 

caffe命令全解析


  http://www.cnblogs.com/denny402/p/5076285.html


第二部分:微調參數調整示例

各類模型finetune示例


Caffe finetune Resnet-50

http://blog.csdn.net/tangwenbo124/article/details/56070322

Caffe finetune googlenet

http://blog.csdn.net/sinat_30071459/article/details/51679995

Caffe finetune FCN

http://blog.csdn.net/zy3381/article/details/50458331

Caffe finetune Alexnet

                 這里寫圖片描述

  • 參數調整注意

  • 首先修改名字,這樣預訓練模型賦值的時候這里就會因為名字不匹配從而重新訓練,也就達成了我們適應新任務的目的;
  • 調整學習速率,因為最后一層是重新學習,因此需要有更快的學習速率相比較其他層,因此我們將,weight和bias的學習速率加快10倍,目的是讓非微調層學習更快;
  • finetune時將最后的全連接層的名字全部修改,需要根據自己數據集的類別數重新設置fc8層的output數;
  • 數據集的類別號從0開始,中間要連續,否則會造成意外的錯誤
  • 數據集記得打亂,不然很可能不收斂;
  • 如果出現不收斂的問題,可以把solver里的lr設的小一點,一般從0.01開始,如果出現loss=nan了就不斷往小調整;
  • 可以把accuracy和loss的曲線畫出來,方便設定stepsize,一般在accuracy和loss都趨於平緩的時候就可以減小lr了;
  • finetune時應該用自己的數據集生成的均值文件(是否正確?);

第三部分:fine-tune的選擇經驗

  在fine-tune時,究竟該選擇哪種方式的Transfer Learning?需要考慮的因素有許多,其中最重要的兩條是新數據庫的規模和它與預訓練數據庫的相似程度,根據這兩條因素的不同配置,存在四種場景: 
   
  新數據庫小,和預訓練數據庫相似。因為數據庫比較小,fine-tune的話可能會產生過擬合,比較好的做法是用預訓練的網絡作為特征提取器,然后訓練線性分類器用在新的任務上。 
  新數據庫比較大,和預訓練數據庫相似。這種情況下,不用擔心過擬合,可以放心地微調整個網絡。 
  新數據庫小,和預訓練數據庫不相似。這時,既不能微調,用預訓練網絡去掉最后一層作為特征提取器也不合適,可行的方案是用預訓練網絡的前面幾層的激活值作為特征,然后訓練線性分類器。 
  新數據庫大,和預訓練數據庫不相似。這時可以從頭開始訓練,也可以在預訓練的基礎上進行微調。

 
   http://blog.csdn.net/julialove102123/article/details/78350619
   
  綜述:做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,同時記得考量你的數據來選擇。


第四部分:如何針對上述不同的方式進行網絡參數固定

比如有4個全連接層A->B->C->D: 

  a. 你希望C層的參數不會改變,C前面的AB層的參數也不會改變,這種情況也就是D層的梯度不往前反向傳播到D層的輸入blob(也就是C層的輸出blob 沒有得到梯度),你可以通過設置D層的lr_mult: 0,layer的梯度就不會反向傳播啦,前面的所有layer的參數也就不會改變了。 
  b. 你希望C層的參數不會改變,但是C前面的AB層的參數會改變,這種情況,只是固定了C層的參數,C層得到的梯度依然會反向傳播給前面的B層。只需要將對應的參數blob的學習率調整為0: 

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

[python] view plain copy
  1. layer {  
  2.     type: "InnerProduct"  
  3.     param { # 對應第1個參數blob的配置,也就是全連接層的參數矩陣的配置  
  4.          lr_mult: # 學習率為0,其他參數可以看caffe.proto里面的ParamSpec這個類型  
  5.     }  
  6.     param { # 對應第2個參數blob的配置,也就是全連接層的偏置項的配置  
  7.         lr_mult: # 學習率為0  
  8.     }  
  9. }  


第五部分:Caffe fine-tune常見問題

一、按照網上的教程微調alexnet,為什么loss一直是87.3365?
 

  解決辦法:檢查數據集的標簽是否是從0開始,base_lr調低了一個數量級,batch_size調高一倍。 
   
  出現的原因:87.3365是個很特殊的數字,NAN經過SoftmaxWithLoss就產生了這個數字,所以就是你的FC8輸出全是NAN; 
   
  具體分析: 
  http://blog.csdn.net/jkfdqjjy/article/details/52268565?locationNum=14

二、Loss下降了,但是准確率沒有明顯變化? 

 解決辦法:訓練前首先shuffle,其次學習率是否合適。

三、Data augmentation 的技巧總結

  • Color Jittering:對顏色的數據增強:圖像亮度、飽和度、對比度變化(此處對色彩抖動的理解不知是否得當);
  • PCA Jittering:首先按照RGB三個顏色通道計算均值和標准差,再在整個訓練集上計算協方差矩陣,進行特征分解,得到特征向量和特征值,用來做PCA Jittering;
  • Random Scale:尺度變換;
  • Random Crop:采用隨機圖像差值方式,對圖像進行裁剪、縮放;包括Scale Jittering方法(VGG及ResNet模型使用)或者尺度和長寬比增強變換;
  • Horizontal/Vertical Flip:水平/垂直翻轉;
  • Shift:平移變換;
  • Rotation/Reflection:旋轉/仿射變換;
  • Noise:高斯噪聲、模糊處理;
  • Label shuffle:類別不平衡數據的增廣,參見海康威視ILSVRC2016的report另外,文中提出了一種Supervised 
  • [python] view plain copy
    1. # -*- coding: utf-8 -*-  
    2. __author__ = 'Administrator'  
    3.   
    4. # import packages  
    5. from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img  
    6.   
    7. datagen = ImageDataGenerator(  
    8.         rotation_range=0.2,  
    9.         width_shift_range=0.2,  
    10.         height_shift_range=0.2,  
    11.         shear_range=0.2,  
    12.         zoom_range=0.2,  
    13.         horizontal_flip=True,  
    14.         fill_mode='nearest')  
    15.   
    16. img = load_img('C:\Users\Administrator\Desktop\dataA\lena.jpg')  # this is a PIL image, please replace to your own file path  
    17. x = img_to_array(img)  # this is a Numpy array with shape (3, 150, 150)  
    18. x = x.reshape((1,) + x.shape)  # this is a Numpy array with shape (1, 3, 150, 150)  
    19.   
    20. # the .flow() command below generates batches of randomly transformed images  
    21. # and saves the results to the `preview/` directory  
    22.   
    23. i = 0  
    24. for batch in datagen.flow(x,  
    25.                           batch_size=1,  
    26.                           save_to_dir='C:\Users\Administrator\Desktop\dataA\pre',#生成后的圖像保存路徑  
    27.                           save_prefix='lena',  
    28.                           save_format='jpg'):  
    29.     i += 1  
    30.     if i > 20:  
    31.         break  # otherwise the generator would loop indefinitely  

四、如何通過loss曲線判斷網絡訓練的情況


  單獨的 loss 曲線能提供的信息很少的,一般會結合測試機上的 accuracy 曲線來判斷是否過擬合; 

  關鍵是要看你在測試集上的acc如何; 
  如果你的 learning_rate_policy 是 step 或者其他變化類型的話, loss 曲線可以幫助你選擇一個比較合適的 stepsize;

五、finetune_net.bin不能用之后,用新的方法做finetune會出問題,怎么解決?   

給最后那個InnerProduct層換個名字。

----------------------------------------------------------------------------------------------------------------

1. 准備新數據的數據庫(如果需要用mean file,還要准備對應的新的mean file), 具體方法和圖片轉換lmdb方式一樣。
2. 調整網絡層參數:
將來訓練的網絡配置prototxt中的數據層source換成新數據的數據庫。
調整學習率,因為最后一層是重新學習,因此需要有更快的學習速率相比較其他層,因此我們將,weight和bias的學習速率加快。
3. 修改solver參數
原來的數據是從原始數據開始訓練的,因此一般來說學習速率、步長、迭代次數都比較大,fine turning微調時,因為數據量可能減少了,所以一般來說,test_iter,base_lr,stepsize都要變小一點,其他的策略可以保持不變。
4. 重新訓練時,要指定之前的權值文件:

# caffe train --solver [新的solver文件] --weights  [舊的caffemodel]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM