Pytorch 加载部分预训练参数

在迁移学习和Fine-tune中,我们需要经常加载预训练好的模型参数,这样的效果一般较好,省时省力。

了解模型的模块参数访问

在pytorch中,可以通过命令model.named_parameters()访问模型的参数名称和对应的参数值。

for name, param in model.named_parameters():
    print(name)
    print(param.requires_grad)

也可以通过命令model.parameters()只访问模型参数值,在optim()函数中经常可以看到。

optimizer = optim.SGD(params=model.parameters, lr=1e-3)

部分冻结模型的参数,例如FC层

  • 方法1:把冻结的变量设置为var.requires_grad=False,optimize函数只更新var.requires_grad=True的变量;
  • 方法2:optimize函数的参数params设置为需要更新的参数,当params=model.parameters()表示更新整个模型参数;当params=model.fc.parameters()表示只更新整个模型fc层参数;
  • 建议把不需要更新的变量参数的requires_grad=False,这样可以节约时间。
from torchvision import models
from torch import nn
from torch import optim

# pretrained 设置为 True,会自动下载模型 所对应权重,并加载到模型中
model = models.resnet18(pretrained=True) 
model.fc= nn.Linear(in_features=1000, out_features=100)
# 这样就 哦了,修改后的模型除了输出层的参数是 随机初始化的,其他层都是用预训练的参数初始化的。
# 如果只想训练 最后一层的话,应该做的是:
# 1. 将其它层的参数 requires_grad 设置为 False
# 2. 构建一个 optimizer, optimizer 管理的参数只有最后一层的参数
# 3. 然后 backward, step 就可以了

# 节省大量的时间,因为多数的参数不需要计算梯度
for para in list(model.parameters())[:-2]:
    para.requires_grad=False 
# optimizer = optim.SGD(filter(lambda p: p.requires_grad, model.parameters()), lr=1e-3)
# filter(lambda p: p.requires_grad, model.parameters()),   #只更新requires_grad=True的参数

# or params:只更新的变量
optimizer = optim.SGD(params=[model.fc.weight,model.fc.bias], lr=1e-3)
  • 任意层的参数固定:可以通过model.named_parameters()访问参数名,把需要参数更新的变量写进一个list,不在list的参数的变量requires_grad=False,完成对任意层的参数固定。

模型覆盖

导入模型,把参数全部冻结,之后新加的层和模块的变量都是的requires_grad=True.

model = torchvision.models.resnet18(pretrained=True)
for param in model.parameters():
    param.requires_grad = False
    
# Parameters of newly constructed modules have requires_grad=True by default
model.fc = nn.Linear(512, 100)
optimizer = optim.SGD(model.fc.parameters(), lr=1e-2, momentum=0.9) #optimizer用于更新网络参数,默认情况下更新所有的参数

你可能感兴趣的:(pytorch)