文章目录
- 模型微调(Finetune)
- 1、迁移学习(transfer learning)&模型微调(Finetune)
- 2、PyTorch中的Finetune
- (1)直接训练
- (2)迁移训练,但不冻结卷积层,固定学习率
- (3)迁移训练,冻结卷基层,固定学习率
- (4)迁移训练,不冻结卷基层,设置小学习率
模型微调(Finetune)
1、迁移学习(transfer learning)&模型微调(Finetune)
迁移学习:机器学习分支,研究源域(source domain)的知识如何应用到目标域(target domain)
模型微调:所谓的模型微调,其实就是模型的迁移学习,在深度学习中,通过不断的迭代,更新卷基层中的权值,这里的权值可以称之为 knowledge , 然后我们可以将这些 knowledge 进行迁移,主要目的是将这些 knowledge 运用到新的模型中,这样既可以减小由于数据量不足导致的过拟合现象,同时又能加快模型的训练速度
具体说来,对于卷积神经网络,我们可以把前面的卷基层,池化层看作是 feature extractor ,是一个非常有共性的部分,而后面的全连接层,可以称之为 classifier , 这一部分就需要针对不同的训练任务进行调整,尤其是最后一层需要根据任务进行相应的调整
- 模型微调的步骤
- 获取预训练模型参数
- 加载模型(load_state_dict)
- 修改输出层
- 模型微调训练方法:
- 固定预训练的参数
(requires_grad =False;lr=0)
- Features Extractor较小学习率(params_group)
2、PyTorch中的Finetune
通过Resnet-18
进行模型的Finetune:
Resnet-18
最后一个层是一个有1000个神经元的层,而用于二分类
(1)直接训练
如果不采用Resnet-18
模型进行Finetune,直接对二分类数据进行训练,得到的曲线如下:
可以看出,损失值一直在0.6附近,并且得到的只有70%
(2)迁移训练,但不冻结卷积层,固定学习率
path_pretrained_model = os.path.join(BASEDIR, "data/resnet18-5c106cde.pth")
state_dict_load = torch.load(path_pretrained_model)
resnet18_ft.load_state_dict(state_dict_load)
可以看出,损失值最后收敛到在0.2附近,并且在第二个的就达到了90%
(3)迁移训练,冻结卷基层,固定学习率
for param in resnet18_ft.parameters():
param.requires_grad = False
从上面的代码来看,所谓冻结卷积层,是直接把参数的梯度设置为False
可以看出,损失值最后收敛到在0.2附近,与不冻结卷积层的情况相似,并且在第二个的也达到了90%
(4)迁移训练,不冻结卷基层,设置小学习率
fc_params_id = list(map(id, resnet18_ft.fc.parameters())) # 返回的是parameters的 内存地址
base_params = filter(lambda p: id(p) not in fc_params_id, resnet18_ft.parameters())
optimizer = optim.SGD([
{'params': base_params, 'lr': LR*0}, # 0
{'params': resnet18_ft.fc.parameters(), 'lr': LR}], momentum=0.9)
可以看到这种方法得到的结果和冻结卷积层得到的结果相同
从上面的例子中可以看出迁移学习应用于深度学习的巨大优势