7.2 Finetune 模型微調

Finetune(微調)是深度學習模型訓練中常用的方法。Finetune的理論可從遷移學習(Transfer Learning)中學習。

遷移學習

Transfer Learning是機器學習的分支,主要研究源域(source domain)所學到的知識,如何遷移到目標域(target domain)

如《A Survey on Transfer Learning》中的圖所示:

<<AI人工智慧 PyTorch自學>> 7.2 Finet

 

為什麼要這樣做呢?這是因為在target domain中,資料量較少,可學習提取的知識不足以完成任務,所以需要進行遷移學習,這樣在target domain中可以學得快,學得好。

例如一個人學會了騎自行車,再去學騎電動車就很快,又比如一個人學會了C語言,再去學python就會比較快。

transfer learning是一個較大的領域,這裡只討論神經網路的finetune,如何理解模型的finetune它也是遷移學習呢?

我們知道,神經網路中最重要的東西就是權值參數,訓練模型就是在更新參數,這些參數就是模型學習到知識。

之前對alexnet的卷積核進行了視覺化,可以理解卷積核學習到的圖像邊緣,色彩資訊就是alexnet所學習到的知識。

在圖像任務中,這些知識是可以共用,可以遷移到其它任務中去,因此,大家常常採用在imagenet上訓練好的模型進行finetune,進行transfer learning

Finetune常用的兩種方法

通常,會將模型劃分為兩個部分

  1. feature extractor: fc層之前的部分認為是一個feature extractor
  2. classifier: fc層認為是classifier

基於此,finetune大體有兩種方法:

  1. feature extractor部分的參數固定,凍結,不進行訓練,僅訓練classifier
  2. feature extractor設置較小的學習率,classifier設置較大的學習率

下面通過一個實例講解兩種方法

方法一:凍結 feature extractor

原理是通過設置paramtersrequires_gradFalse,讓它們不進行權重更新即可。

for param in resnet18_ft.parameters():
    param.requires_grad = True

完整代碼中,每個epoch都列印了第一個卷積層權重,觀察它們是否有變化。

經過25epoch訓練,性能指標如下圖所示。

<<AI人工智慧 PyTorch自學>> 7.2 Finet

方法二:不同層不同學習率

原理是通過優化器的參數組管理,不同參數組可以設置不同的學習率。

因此第一步需要將不同的參數從模型中識別、提取出來,分別定義為不同參數組,這裡通過記憶體位址進行區分。

 # 返回的是該層所有參數的記憶體位址
fc_params_id = list(map(id, resnet18_ft.fc.parameters()))
#遍歷model的參數,只要不是需要ignore的,就保留,返回filter物件,在optimizer.py中的add_param_group中有
base_params = filter(lambda p: id(p) not in fc_params_id, resnet18_ft.parameters())
 
optimizer = optim.SGD([
    {'params': base_params, 'lr': LR},  # 0
    {'params': resnet18_ft.fc.parameters(), 'lr': LR*2}], momentum=0.9)

通過代碼看到最後的全連接層學習率比前面的特徵提取部分大10倍,如果對optimizer的參數組概念不瞭解,請回看第五章

小結

Finetune的代碼實現非常簡單,不過需要大家對nn.Moduleoptimizer的基礎概念熟悉,建議回顧第四章與第五章的基礎知識。

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 HCHUNGW 的頭像
    HCHUNGW

    HCHUNGW的部落格

    HCHUNGW 發表在 痞客邦 留言(0) 人氣()