Pytorch 加载部分预训练参数/不对偏置项做L2正则化

在迁移学习和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用于更新网络参数,默认情况下更新所有的参数

不同层设置不同的参数

  • 不对偏置项做L2正则化(Weight decay)
bias_list = (param for name, param in model.named_parameters() if name[-4:] == 'bias')
others_list = (param for name, param in model.named_parameters() if name[-4:] != 'bias')
parameters = [{'params': bias_list, 'weight_decay': 0},                
              {'params': others_list}]
optimizer = torch.optim.SGD(parameters, lr=1e-2, momentum=0.9, weight_decay=1e-4)
  • 以较大学习率微调全连接层,较小学习率微调卷积层
model = torchvision.models.resnet18(pretrained=True)
finetuned_parameters = list(map(id, model.fc.parameters()))
conv_parameters = (p for p in model.parameters() if id(p) not in finetuned_parameters)
parameters = [{'params': conv_parameters, 'lr': 1e-3}, 
              {'params': model.fc.parameters()}]
optimizer = torch.optim.SGD(parameters, lr=1e-2, momentum=0.9, weight_decay=1e-4)
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值