pytorch load state dict_PyTorch 学习笔记(五):Finetune和各层定制学习率
本文截取自《PyTorch 模型訓(xùn)練實(shí)用教程》,獲取全文pdf請(qǐng)點(diǎn)擊:https://github.com/tensor-yu/PyTorch_Tutorial
@[toc]
我們知道一個(gè)良好的權(quán)值初始化,可以使收斂速度加快,甚至可以獲得更好的精度。而在實(shí)際應(yīng)用中,我們通常采用一個(gè)已經(jīng)訓(xùn)練模型的模型的權(quán)值參數(shù)作為我們模型的初始化參數(shù),也稱之為Finetune,更寬泛的稱之為遷移學(xué)習(xí)。遷移學(xué)習(xí)中的Finetune技術(shù),本質(zhì)上就是讓我們新構(gòu)建的模型,擁有一個(gè)較好的權(quán)值初始值。
finetune權(quán)值初始化三步曲,finetune就相當(dāng)于給模型進(jìn)行初始化,其流程共用三步:
第一步:保存模型,擁有一個(gè)預(yù)訓(xùn)練模型; 第二步:加載模型,把預(yù)訓(xùn)練模型中的權(quán)值取出來; 第三步:初始化,將權(quán)值對(duì)應(yīng)的“放”到新模型中
一、Finetune之權(quán)值初始化
在進(jìn)行finetune之前我們需要擁有一個(gè)模型或者是模型參數(shù),因此需要了解如何保存模型。官方文檔中介紹了兩種保存模型的方法,一種是保存整個(gè)模型,另外一種是僅保存模型參數(shù)(官方推薦用這種方法),這里采用官方推薦的方法。
第一步:保存模型參數(shù)
若擁有模型參數(shù),可跳過這一步。 假設(shè)創(chuàng)建了一個(gè)net = Net(),并且經(jīng)過訓(xùn)練,通過以下方式保存: torch.save(net.state_dict(), 'net_params.pkl')第二步:加載模型
進(jìn)行三步曲中的第二步,加載模型,這里只是加載模型的參數(shù): pretrained_dict = torch.load('net_params.pkl')第三步:初始化
進(jìn)行三步曲中的第三步,將取到的權(quán)值,對(duì)應(yīng)的放到新模型中: 首先我們創(chuàng)建新模型,并且獲取新模型的參數(shù)字典net_state_dict: net = Net() # 創(chuàng)建net net_state_dict = net.state_dict() # 獲取已創(chuàng)建net的state_dict接著將pretrained_dict里不屬于net_state_dict的鍵剔除掉: pretrained_dict_1 = {k: v for k, v in pretrained_dict.items() if k in net_state_dict}然后,用預(yù)訓(xùn)練模型的參數(shù)字典 對(duì) 新模型的參數(shù)字典net_state_dict 進(jìn)行更新: net_state_dict.update(pretrained_dict_1)最后,將更新了參數(shù)的字典 “放”回到網(wǎng)絡(luò)中: net.load_state_dict(net_state_dict)這樣,利用預(yù)訓(xùn)練模型參數(shù)對(duì)新模型的權(quán)值進(jìn)行初始化過程就做完了。
采用finetune的訓(xùn)練過程中,有時(shí)候希望前面層的學(xué)習(xí)率低一些,改變不要太大,而后面的全連接層的學(xué)習(xí)率相對(duì)大一些。這時(shí)就需要對(duì)不同的層設(shè)置不同的學(xué)習(xí)率,下面就介紹如何為不同層配置不同的學(xué)習(xí)率。
二、不同層設(shè)置不同的學(xué)習(xí)率
在利用pre-trained model的參數(shù)做初始化之后,我們可能想讓fc層更新相對(duì)快一些,而希望前面的權(quán)值更新小一些,這就可以通過為不同的層設(shè)置不同的學(xué)習(xí)率來達(dá)到此目的。
為不同層設(shè)置不同的學(xué)習(xí)率,主要通過優(yōu)化器對(duì)多個(gè)參數(shù)組進(jìn)行設(shè)置不同的參數(shù)。所以,只需要將原始的參數(shù)組,劃分成兩個(gè),甚至更多的參數(shù)組,然后分別進(jìn)行設(shè)置學(xué)習(xí)率。 這里將原始參數(shù)“切分”成fc3層參數(shù)和其余參數(shù),為fc3層設(shè)置更大的學(xué)習(xí)率。
請(qǐng)看代碼:
ignored_params = list(map(id, net.fc3.parameters())) # 返回的是parameters的 內(nèi)存地址 base_params = filter(lambda p: id(p) not in ignored_params, net.parameters()) optimizer = optim.SGD([ {'params': base_params}, {'params': net.fc3.parameters(), 'lr': 0.001*10}], 0.001, momentum=0.9, weight_decay=1e-4)第一行+ 第二行的意思就是,將fc3層的參數(shù)net.fc3.parameters()從原始參數(shù)net.parameters()中剝離出來 base_params就是剝離了fc3層的參數(shù)的其余參數(shù),然后在優(yōu)化器中為fc3層的參數(shù)單獨(dú)設(shè)定學(xué)習(xí)率。
optimizer = optim.SGD(......)這里的意思就是 base_params中的層,用 0.001, momentum=0.9, weight_decay=1e-4 fc3層設(shè)定學(xué)習(xí)率為: 0.001*10
完整代碼位于 https://github.com/tensor-yu/PyTorch_Tutorial/blob/master/Code/2_model/2_finetune.py
補(bǔ)充:
挑選出特定的層的機(jī)制是利用內(nèi)存地址作為過濾條件,將需要單獨(dú)設(shè)定的那部分參數(shù),從總的參數(shù)中剔除。 base_params 是一個(gè)list,每個(gè)元素是一個(gè)Parameter 類 net.fc3.parameters() 是一個(gè)
ignored_params = list(map(id, net.fc3.parameters())) net.fc3.parameters() 是一個(gè) 所以迭代的返回其中的parameter,這里有weight 和 bias 最終返回weight和bias所在內(nèi)存的地址
轉(zhuǎn)載請(qǐng)注明出處:https://blog.csdn.net/u011995719/article/details/85107310
總結(jié)
以上是生活随笔為你收集整理的pytorch load state dict_PyTorch 学习笔记(五):Finetune和各层定制学习率的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux的路径怎么写(linux的路径
- 下一篇: opengl如何画出一个球_OpenGL