7.2 Finetune 模型微調
Finetune(微調)是深度學習模型訓練中常用的方法。Finetune的理論可從遷移學習(Transfer Learning)中學習。
遷移學習
Transfer Learning是機器學習的分支,主要研究源域(source domain)所學到的知識,如何遷移到目標域(target domain)中
如《A Survey on Transfer Learning》中的圖所示:
為什麼要這樣做呢?這是因為在target domain中,資料量較少,可學習提取的知識不足以完成任務,所以需要進行遷移學習,這樣在target domain中可以學得快,學得好。
例如一個人學會了騎自行車,再去學騎電動車就很快,又比如一個人學會了C語言,再去學python就會比較快。
transfer learning是一個較大的領域,這裡只討論神經網路的finetune,如何理解模型的finetune它也是遷移學習呢?
我們知道,神經網路中最重要的東西就是權值參數,訓練模型就是在更新參數,這些參數就是模型學習到知識。
之前對alexnet的卷積核進行了視覺化,可以理解卷積核學習到的圖像邊緣,色彩資訊就是alexnet所學習到的知識。
在圖像任務中,這些知識是可以共用,可以遷移到其它任務中去,因此,大家常常採用在imagenet上訓練好的模型進行finetune,進行transfer learning。
Finetune常用的兩種方法
通常,會將模型劃分為兩個部分
- feature extractor: 將fc層之前的部分認為是一個feature extractor
- classifier: fc層認為是classifier
基於此,finetune大體有兩種方法:
- 將 feature extractor部分的參數固定,凍結,不進行訓練,僅訓練classifier
- 將 feature extractor設置較小的學習率,classifier設置較大的學習率
下面通過一個實例講解兩種方法
方法一:凍結 feature extractor。
原理是通過設置paramters的requires_grad為False,讓它們不進行權重更新即可。
for param
in resnet18_ft.parameters():
param.requires_grad =
True
在完整代碼中,每個epoch都列印了第一個卷積層權重,觀察它們是否有變化。
經過25個epoch訓練,性能指標如下圖所示。
方法二:不同層不同學習率
原理是通過優化器的參數組管理,不同參數組可以設置不同的學習率。
因此第一步需要將不同的參數從模型中識別、提取出來,分別定義為不同參數組,這裡通過記憶體位址進行區分。
# 返回的是該層所有參數的記憶體位址
fc_params_id = list(map(id, resnet18_ft.fc.parameters()))
#遍歷model的參數,只要不是需要ignore的,就保留,返回filter物件,在optimizer.py中的add_param_group中有
base_params = filter(
lambdap: id(p)
not infc_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.Module和optimizer的基礎概念熟悉,建議回顧第四章與第五章的基礎知識。
留言列表