上一课,介绍了模型的权值初始化,以及PyTorch自带的权值初始化方法函数。我们知道一个而良好的权值初始化,可以使收敛速度加快,甚至收获更好的精度。但是实际应用中,并不是如此,我们通常采用一个已经训练的模型的权值参数作为我们模型的初始化参数,这个就是Finetune,更宽泛的说,就是迁移学习!! 迁移学习中的Finetune技术,本质上就是让我们新构建的模型,拥有一个较好的权值初始值。
finetune权值初始化分三步:
在进行finetune之前,我们呢需要拥有一个模型或者模型参数,因此我们要学习如何保存模型。官方文档中介绍了两种保存模型的方法:
我们现有一个Net模型,就像前面几课讲得那样
net = Net()
torch.save(net.state_dict(),'net_params.pkl')
这里只是加载模型的参数,就是上面那个玩意
pretrained_dict = torch.load('net_params.pkl')
放权值放到新的模型中:
首先我们创建新的模型,然后获取新模型的参数字典net_state_dict:
net = Net()
net_state_dict = net.state_dict()
# 接着将pretrain_dict中不属于net_state_dict的键剔除掉
pretrained_dict_1 = {k:v for k,v in pretrained_dict.items() if k in net_state_dict}
# 然后用与训练的参数字典,对新模型的参数字典net_state_dict进行更新
net_state_dict.update(pretrained_dict_1)
# 将更新的参数字典放回网络中
net.load_state_dict(net_state_dict)
这样,利用预训练模型参数对新模型的权值进行初始化的过程就算做完了
在利用pre-trained model的参数做初始化之后,我们可能想让fc曾更新的相对快一点,而希望前面的权值更新速度慢一点,这就可以通过为不同的层设置不同的学习率来达到此目的。
为不同层设置不同的学习率,主要是通过优化器的多个函数设置不同的参数,所以,只要将原来的参数组,划分成两个甚至更多的参数组,然后分别设置学习率。
不多说,上案例,这里将原始参数划分成fc3层和其他参数,为fc3设置更大的学习率
ignore_params = list(map(id,net.fc3.parameters()))
base_params = filter(lambda p:id(p) not in ignored_params,net.parameters())
# 这里的ignore_params是fc3的参数,base_params是除了fc3层之外的参数
optimizer = optim.SGD([
{'params':base_[arams},
{'params':net.fc3.parameters(),'lr':0.001*1-}],0.001,momentum=0.9,weight_decay = le-4)
补充:这里面好像是根据内存地址是否重复,来排除掉fc3中的参数,得到base_params的。
公众号回复【下载】有精选的免费机器学习学习资料。 公众号每天会更新一个机器学习、深度学习的小知识,都是面试官会问的知识点哦~
公众号每天会更新一个机器学习、深度学习的小知识,都是面试官会问的知识点哦~