PyTorch中使用预训练的模型初始化网络的一部分参数
2018-01-15 20:50
1491 查看
在预训练网络的基础上,修改部分层得到自己的网络,通常我们需要解决的问题包括:
1. 从预训练的模型加载参数
2. 对新网络两部分设置不同的学习率,主要训练自己添加的层
一. 加载参数的方法:
加载参数可以参考apaszke推荐的做法,即删除与当前model不匹配的key。代码片段为:
二. 不同层设置不同学习率的方法
此部分主要参考PyTorch教程的Autograd machnics部分
2.1 在PyTorch中,每个Variable数据含有两个flag(requires_grad和volatile)用于指示是否计算此Variable的梯度。设置requires_grad = False,或者设置volatile=True,即可指示不计算此Variable的梯度:
注意,在模型测试时,对input_data设置volatile=True,可以节省测试时的显存
2.2 PyTorch的Module.modules()和Module.children()
参考PyTorch document和discuss
在PyTorch中,所有的neural network module都是class torch.nn.Module的子类,在Modules中可以包含其它的Modules,以一种树状结构进行嵌套。当需要返回神经网络中的各个模块时,Module.modules()方法返回网络中所有模块的一个iterator,而Module.children()方法返回所有直接子模块的一个iterator。具体而言:
2.3 选择特定的层进行finetune
先使用Module.children()方法查看网络的直接子模块,将不需要调整的模块中的参数设置为param.requires_grad = False,同时用一个list收集需要调整的模块中的参数。具体代码为:
到此我们实现了PyTorch中使用预训练的模型初始化网络的一部分参数,参考代码见我的GitHub:
1. 从预训练的模型加载参数
2. 对新网络两部分设置不同的学习率,主要训练自己添加的层
一. 加载参数的方法:
加载参数可以参考apaszke推荐的做法,即删除与当前model不匹配的key。代码片段为:
model = ... model_dict = model.state_dict() # 1. filter out unnecessary keys pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict} # 2. overwrite entries in the existing state dict model_dict.update(pretrained_dict) # 3. load the new state dict model.load_state_dict(model_dict)
二. 不同层设置不同学习率的方法
此部分主要参考PyTorch教程的Autograd machnics部分
2.1 在PyTorch中,每个Variable数据含有两个flag(requires_grad和volatile)用于指示是否计算此Variable的梯度。设置requires_grad = False,或者设置volatile=True,即可指示不计算此Variable的梯度:
for param in model.parameters(): param.requires_grad = False
注意,在模型测试时,对input_data设置volatile=True,可以节省测试时的显存
2.2 PyTorch的Module.modules()和Module.children()
参考PyTorch document和discuss
在PyTorch中,所有的neural network module都是class torch.nn.Module的子类,在Modules中可以包含其它的Modules,以一种树状结构进行嵌套。当需要返回神经网络中的各个模块时,Module.modules()方法返回网络中所有模块的一个iterator,而Module.children()方法返回所有直接子模块的一个iterator。具体而言:
list(nn.Sequential(nn.Linear(10, 20), nn.ReLU()).modules()) Out[9]: [Sequential ( (0): Linear (10 -> 20) (1): ReLU () ), Linear (10 -> 20), ReLU ()] In [10]: list(nn.Sequential(nn.Linear(10, 20), nn.ReLU()).children()) Out[10]: [Linear (10 -> 20), ReLU ()]
2.3 选择特定的层进行finetune
先使用Module.children()方法查看网络的直接子模块,将不需要调整的模块中的参数设置为param.requires_grad = False,同时用一个list收集需要调整的模块中的参数。具体代码为:
count = 0 para_optim = [] for k in model.children(): count += 1 # 6 should be changed properly if count > 6: for param in k.parameters(): para_optim.append(param) else: for param in k.parameters(): param.requires_grad = False optimizer = optim.RMSprop(para_optim, lr)
到此我们实现了PyTorch中使用预训练的模型初始化网络的一部分参数,参考代码见我的GitHub:
相关文章推荐
- 深度学习源码剖析:使用双线性插值方式初始化神经网络的可训练参数
- pytorch中的pre-train函数模型或者旧的模型的引用及修改(增减网络层,修改某层参数等) finetune微调等
- pytorch:在网络中添加可训练参数,修改预训练权重文件
- pytorch 如何加载部分预训练模型
- 自己定义CNN网络模型并使用caffe训练
- PyTorch参数初始化方法
- 实用:使用caffe训练模型时solver.prototxt中的参数设置解析
- Torch 网络层 参数的初始化问题
- pytorch使用(二)自定义网络
- TF Saver 保存/加载训练好模型(网络+参数)的那些事儿
- 使用单线程对文本分类的朴素贝叶斯模型的超参数组合执行网络搜索
- Caffe下py-faster-rcnn使用残差网络Resnet进行训练
- Caffe 之 使用非图片的鸢尾花(IRIS)数据集(hdf5格式) 训练网络模型
- (继)pytorch中的pretrain模型网络结构修改
- PyTorch(7)——模型的训练和测试、保存和加载
- 使用TensorFlow训练循环神经网络语言模型
- (原)ubuntu16在torch中使用caffe训练好的模型
- Tensorflow使用笔记(1) 怎么保存和使用训练好的参数和模型
- Caffe初试(三)使用caffe的cifar10网络模型训练自己的图片数据
- 使用Caffe训练适合自己样本集的AlexNet网络模型,并对其进行分类