pytorch:子模型参数冻结 + BN冻结

使用场景:需要完全冻结某部分的 weight 与 BN 层
  加载预训练模型时,如果只将 para.requires_grad = False ,并不能完全冻结模型的参数,因为模型中的 BN 层并不随 loss.backward() 与 optimizer.step() 来更新,而是在模型 forward 的过程中基于动量来更新,因此需要每个 forward 之前冻结 BN 层:
完整的冻结方式如下:


'''
一堆代码
'''

# 冻结BN
def freeze_bn(m):
    classname = m.__class__.__name__
    if classname.find('BatchNorm') != -1:
        m.eval()


'''
一堆代码
'''
freeze_state_dict = torch.load(opt.loadckpt_freeze)
frozen_list = [k for k, _ in freeze_state_dict['state_dict'].items() if k in model_dict]
# 先冻结除了 BN 以外的参数
for param in model.named_parameters():
    if param[0] in frozen_list:		# 需要冻结的参数列表
        param[1].requires_grad = False

# 优化器优化的参数只包含需要梯度更新的参数        
optimizer = optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=opt.lr, betas=(0.9,0.999))

'''
一堆代码
'''

for epoch in range(opt.epoch):
	model.train()
	optimizer.zero_grad()
	# 冻结BN
	model.apply(freeze_bn)
	# 前向传播
	output = model(input)
	loss = loss_F(gt, output)
	loss.backward()
	optimizer.step()
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CV科研随想录

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值