PyTorch 更新模型参数以及并固定该部分参数(二)

简介

在进行这部分时,会存在一些疑惑,针对以下疑惑进行解答。

问题一:实际上在固定参数的时候,大家会有疑惑,既然使用这种方式固定冻结网络参数是否存在固定的高层网络,但是低层网络的参数不会更新呢?

:实际上固定网络参数只是让需要固定的层的参数不再自己保留梯度,但是梯度值仍会计算,即进行方向传播时仍然会可以进行低层网络参数的更新。required_grad属性只是控制是否保留梯度而已,但仍然会计算该梯度值

问题二:是否只将需要训练层的参数传播到优化器里optimter就可以实现,不需要进行固定部分呢?

:实际上不固定里边的梯度属性required_grad的话,需要固定部分的参数是一直在进行变化的,虽然没有参与参数的更新。

大家在学习pytorch时,可能想利用pytorch进行fine-tune,但是又烦恼于参数的加载问题。下面我将讲诉我的使用心得。

Step1: 加载预训练模型,并去除需要再次训练的层

注意:需要重新训练的层的名字要和之前的不同。

model=resnet()#自己构建的模型,以resnet为例
model_dict = model.state_dict()
pretrained_dict = torch.load('xxx.pkl')
pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
model_dict.update(pretrained_dict)
model.load_state_dict(model_dict)

Step2: 固定部分参数

#k是可训练参数的名字,v是包含可训练参数的一个实体
#可以先print(k),找到自己想进行调整的层,并将该层的名字加入到if语句中:
for k,v in model.named_parameters():
    if k!='xxx.weight' and k!='xxx.bias' :
        v.requires_grad=False#固定参数

Step3:训练部分参数

#将要训练的参数放入优化器

optimizer2=torch.optim.Adam(params=[model.xxx.weight,model.xxx.bias],lr=learning_rate,betas=(0.9,0.999),weight_decay=1e-5)

Step4:检查部分参数是否固定

debug之后,程序正常运行,最好检查一下网络的参数是否真的被固定了,如何没固定,网络的状态接近于重新训练,可能会导致网络性能不稳定,也没办法得到想要得到的性能提升。

for k,v in model.named_parameters():
    if k!='xxx.weight' and k!='xxx.bias' :
            print(v.requires_grad)#理想状态下,所有值都是False

需要注意的是,操作失误最大的影响是,loss函数几乎不会发生变化,一直处于最开始的状态,这很可能是因为所有参数都被固定了。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch是一个流行的机器学习框架,它允许用户在Python中创建和训练神经网络。在深度学习中,有时需要冻结神经网络的一些层或权重以允许其他层进行学习。这种技术在迁移学习、预训练网络和批标准化中经常使用。PYTORCH中有两种方法可以确定要冻结和解冻的网络层。以下是两种方法的详细解释。 1、方法一:requires_grad属性 在PyTorch中,可以通过设置requires_grad属性为False来固定网络权重。 以下是一个简单的示例: ``` import torch model = torch.models.resnet50(pretrained = True) # 冻结网络的前5个卷积层 for param in model.parameters(): if param.requires_grad and param in model.layer1.parameters(): param.requires_grad = False if param.requires_grad and param in model.layer2.parameters(): param.requires_grad = False if param.requires_grad and param in model.layer3.parameters(): param.requires_grad = False if param.requires_grad and param in model.layer4.parameters(): param.requires_grad = False if param.requires_grad and param in model.avgpool.parameters(): param.requires_grad = False ``` 在这个例子中,我们使用resnet50预训练模型,并冻结前5个卷积层。这是通过迭代模型参数并设置requires_grad属性来完成的。设置requires_grad属性为False将禁用梯度计算,从而可以固定参数。 2、方法:requires_grad_()方法 PyTorch还提供了一个方便的方法,可以直接调用requires_grad_()方法来冻结或解冻网络层。该方法将引用一个新的张量,该张量允许用户直接在张量上设置新值。 以下是一个简单的示例: ``` import torch model = torch.models.resnet50(pretrained = True) # 冻结网络的前5个卷积层 for param in model.parameters(): param.requires_grad_(False) if param.requires_grad and param in model.avgpool.parameters(): param.requires_grad_(True) ``` 在这个例子中,我们使用resnet50预训练模型,并冻结前5个卷积层。这是通过使用requires_grad_()方法来完成的。requires_grad_()方法将返回一个新的张量,并设置requires_grad属性为True或False。在这种情况下,我们将requires_grad属性设置为False以冻结前5个卷积层,并将avgpool层的requires_grad属性设置为True以允许其进行训练。 总之,这两种方法都是有效的冻结神经网络层或参数的方法,用户可以根据自己的需要选择其中一种方法,以提高模型的学习效率和准确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值