在学习pytorch然后刷官方的pytorch-tutorials到讲解Image/Finetune_Torchvision_Models时,看到Transfer Learning, 它在提及fine-tune和feature extraction两个方法时给了Transfer Learning概念解析的两个链接,这里着重翻译摘录下第一个链接的内容CS231n_transfer-learning。
一、为什么要有transfer-learning
在面对一个新任务的时候,很少有人会从头开始训练整个的CNN,因为新任务能提供的数据集有很大的可能是不足够支撑训练的。因此通常的做法是,将CNN在一个非常大的数据集上(比如imagenet、instagram等)做个pretrain,然后利用这个pretrain的结果再去解决新任务。
二、transfer-learning具体方案
1)ConvNet as fixed feature extractor:
我们将CNN在比如ImageNet这样子的大数据集上跑一下,然后可以将最后的一个全连接层做下更改,比如自己的目标任务是做5分类那么就要将最后的fc层的output_num从1000改为5。具体操作是,我们将除了最后一fc层的前面所有层都固定不动,将其看作是一个已经设计完备了的特征提取器(输入经过前面特征提取器的结果称之为CNN codes,在AlexNet网络里是一个4096维度的向量),我们要做的是只训练最后更改后的fc层,将其看作需要训练的分类器,当然也可直接抛弃最后的fc层,针对提取到的CNN codes去训练一个更轻便的SVM或Softmax等其他分类器。
2)Fine-tuning the ConvNet:
这个方法不仅是只更换并重新训练最后的“分类器”,而且会去对前面的网络做个重新训练,可以是对前面所有的网络重新训练得到权重参数;也可以是将最前面的几层固定不动,而只训练后面的几层网络,因为前面的网络提取到的一般都是浅层(通用)特征,例如边缘、色彩等,所以可以不用重新训练,而后面的网络就开始提取深层(具体)特征,例如某个类间的细节差别,所以可以重新训练这些网络,便于更好的提取。
3)Pretrained models:
因为做一个pretrain耗时非常的长,因此有很多人都将模型在ImageNet等认知度高的大数据集上的预训练结果上传分享,比如在caffe的model zool,在pytorch的torchvison等地方都可以下载到模型文件。
三、transfer-learning应用场景
1)新任务的数据集小,跟预训练的数据集有点类似:使用方案一ConvNet as fixed feature extractor,只训练分类器
2)新任务的数据集大,跟预训练的数据集有点类似:使用方案二Fine-tuning the ConvNet,不用担心数据集小引发的过拟合问题
3)新任务的数据集小,跟预训练的数据集差别较大:由于数据集小所以最好只训练一个线性分类器,由于新任务跟预训练的数据差别很大,那么在网络的前面某层开始就添加上一个线性分类器,剩下的网络层直接舍弃,可能会更好。
4)新任务的数据集大,跟预训练的数据集差别较大:使用方案二Fine-tuning the ConvNet,可以是随机初始化从头训练所有网络,也可以是导入pretrained model的参数文件,在此基础上再训练,不用担心数据集小引发的准确率低或过拟合问题。
四、transfer-learning通用注意
1)不能随意更改网络结构,比如随意删除或添加xx层,需要注意结果维度的问题,但一般而言输入的空间尺寸没有限制;
2)在做fine-tune有很多技巧,比如设置更小的学习率。