参考教程:
transfer-learning
transfer-learning tutorial
文章目录
transfer learning
很少会有人从头开始训练一个卷积神经网络,因为并不是所有人都有机会接触到大量的数据。常用的选择是在一个非常大的模型上预训练一个模型,然后用这个模型为基础,或者固定它的参数用作特征提取,来完成特定的任务。
对卷积网络进行finetune
进行transfer-learning的一个方法是在基于大数据训练的模型上进行fine-tune。可以选择对模型的每一个层都进行fine-tune,也可以选择freeze特定的层(一般是比较浅的层)而只对模型的较深的层进行fine-tune。理论支持是,模型的浅层通常是一些通用的特征,比如edge或者colo blob,这些特征可以应用于多种类型的任务,而高层的特征则会更倾向于用于训练的原始数据集中的数据特点,因为不太能泛化到新数据上去。
把卷积网络作为特征提取器
将ConvNet作为一个特征提取器,通常是去掉它最后一个用于分类的全连接层,把剩余的层用来提取新数据的特征。你可以在该特征提取器后加上你自己的head,比如分类head或者回归head,用于完成你自己的任务。
何时、如何进行fine tune
使用哪种方法有多种因素决定,最主要的因素是你的新数据集的大小和它与原始数据集的相似度。
- 当你的新数据集很小,并和原始数据集比较相似时。
因为你的数据集很小,所以从过拟合的角度出发,不推荐在卷积网络上进行fine-tune。又因为你的数据和原始数据比较相似,所以卷积网络提取的高层特征和你的数据也是相关的。因此你可以直接卷积网络当作特征提取器,在此基础上训练一个线性分类器。 - 当你的新数据集很大,并和原始数据集比较相似时。
新数据集很大时,我们可以对整个网络进行fine-tune,因为我们不太会有过拟合的风险。 - 当你的新数据集很小,并和原始数据集不太相似时。
因为你的数据集很小,我们还是推荐只训练一个线性的分类器。但是新数据和原始数据又不相似,所以不建议在网络顶端接上新的分类器,因为网络顶端包含很多的dataset-specific的特征,所以更推荐的是从浅层网络的一个位置出发接上一个分类器。 - 当你的新数据集很大,并和原始数据集不太相似时。
因为你的数据集很大,我们仍然选择对整个网络进行fine-tune。因为通常情况下以一个pretrained-model对模型进行初始化的效果比随机初始化要好。
代码示例
我们使用与第四章 模型篇:模型训练与示例一样的流程进行模型训练。
加载数据集
首先是加载数据集,方便起见我们直接使用torchvision中的cifar10数据进行训练。
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
training_data = datasets.CIFAR10(
root="data",
train=True,
download=True,
transform=transform
)
test_data = datasets.CIFAR10(root='./data', train=False,
download=True, transform=

文章介绍了迁移学习的概念,特别是针对卷积网络的finetune策略。通过预训练模型进行特征提取,或者对模型的不同层进行finetune,以适应不同大小和相似度的新数据集。文章提供了一个使用ResNet18模型在CIFAR10数据集上进行训练和测试的代码示例,展示了如何定义训练和测试循环,以及如何选择合适的finetune策略。
最低0.47元/天 解锁文章
695

被折叠的 条评论
为什么被折叠?



