PyTorch參數初始化和Finetune

前言

這篇文章算是論壇PyTorch Forums關於參數初始化和finetune的總結,也是我在寫代碼中用的算是「最佳實踐」吧。最後希望大家沒事多逛逛論壇,有很多高質量的回答。

參數初始化

參數的初始化其實就是對參數賦值。而我們需要學習的參數其實都是Variable,它其實是對Tensor的封裝,同時提供了data,grad等借口,這就意味著我們可以直接對這些參數進行操作賦值了。這就是PyTorch簡潔高效所在。

所以我們可以進行如下操作進行初始化,當然其實有其他的方法,但是這種方法是PyTorch作者所推崇的:

def weight_init(m):n# 使用isinstance來判斷m屬於什麼類型n if isinstance(m, nn.Conv2d):n n = m.kernel_size[0] * m.kernel_size[1] * m.out_channelsn m.weight.data.normal_(0, math.sqrt(2. / n))n elif isinstance(m, nn.BatchNorm2d):n# m中的weight,bias其實都是Variable,為了能學習參數以及後向傳播n m.weight.data.fill_(1)n m.bias.data.zero_()n

Finetune

往往在載入了預訓練模型的參數之後,我們需要finetune模型,可以使用不同的方式finetune。

局部微調

有時候我們載入了訓練模型後,只想調節最後的幾層,其他層不訓練。其實不訓練也就意味著不進行梯度計算,PyTorch中提供的requires_grad使得對訓練的控制變得非常簡單。

model = torchvision.models.resnet18(pretrained=True)nfor param in model.parameters():n param.requires_grad = Falsen# 替換最後的全連接層, 改為訓練100類n# 新構造的模塊的參數默認requires_grad為Truenmodel.fc = nn.Linear(512, 100)nn# 只優化最後的分類層noptimizer = optim.SGD(model.fc.parameters(), lr=1e-2, momentum=0.9)n

全局微調

有時候我們需要對全局都進行finetune,只不過我們希望改換過的層和其他層的學習速率不一樣,這時候我們可以把其他層和新層在optimizer中單獨賦予不同的學習速率。比如:

ignored_params = list(map(id, model.fc.parameters()))nbase_params = filter(lambda p: id(p) not in ignored_params,n model.parameters())nnoptimizer = torch.optim.SGD([n {params: base_params},n {params: model.fc.parameters(), lr: 1e-2}n ], lr=1e-3, momentum=0.9)n

其中base_params使用1e-3來訓練,model.fc.parameters使用1e-2來訓練,momentum是二者共有的。


推薦閱讀:

如何用pytorch構建自己的數據
Conda command not found
知乎「看山杯」 奪冠記
如何有效地閱讀PyTorch的源代碼?
深度學習入門該用PyTorch還是Keras?熱門公開課換框架背後的學問

TAG:深度学习DeepLearning | PyTorch |