写在前面:最近有很久没有更新博客了,主要是在学习研究深度学习这块知识,语言主要为pytorch,目前这块主要对技术知识做一个总结,以此勉励自己以及他人。
首先,我们会在什么情况下需要用到迁移学习呢?在实际工程应用方面,主要有以下2点
1、缺乏数据集
2、重新构造模型难度和代价太大
因此,所谓迁移学习就是说,已经有一个还不错的模型,但是它的类别数与需求不同,但是应用环境类似,比如图像识别(这里的识别是指单一对象识别,并不包括对象检测这种),那么那些已经训练好的模型对图像特征提取已经做的很好了,我们不太需要自己非要重新构建一个模型去训练,我们只需要利用已经训练好的模型的权重去提取新类别的图像的特征就可以了,所以下面详细介绍迁移学习的类别以及过程,会附上相应源码。
迁移学习有两类:finetuning 和 feature extraction
所谓finetuning就是说主要是调参,如(学习率,动量,等)相当于重新训练整个模型,只不过参数是微调
所谓feature extraction,就是说保留除最后一层以外其他层的weights不变,这个可调范围就很小了
实际应用中,使用finetuning的居多
首先我们要了解一下经典的卷积神经网络模型,如果还有刚入门的童鞋没看过,我强烈建议看一看,因为后续许多方法都是基于这些经典模型展开的,深入了解非常有帮助的。好了,废话不多说了。。
经典模型:[resnet, alexnet, vgg, densenet, inception],其中应用非常广泛的为resnet与vgg,这里我就不详细介绍这些模型了
如何进行迁移学习?
这里,我们首先要找到模型的最后一层,也就是全连接层,这里以resnet为例
(fc): Linear(in_features=512, out_features=1000, bias=True)
找到这个后,将out_features改为num_classes,也就是
model.fc = nn.Linear(512, num_classes)
看,简单吧,这里说明一下,如果是开源项目的模型,也是同样的道理,找到最后的全连接层,改为我们需要的类别即可
整个过程如下:
if model_name == "resnet":
""" Resnet18
"""
model_ft = models.resnet18(pretrained=use_pretrained)
set_parameter_requires_grad(model_ft, feature_extract)
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs, num_classes)
input_size = 224
def set_parameter_requires_grad(model, feature_extracting):
if feature_extracting:
for param in model.parameters():
param.requires_grad = False
其他的步骤,包括加载数据,设置optimizer等与之前方法一致,其中,feature_extract是一个boolean类型的值,如果设置为False则说明采用第一种方式进行迁移学习,模型的所有weights都会更新,如果此值设置为True,则是采用第二种方式进行迁移学习