迁移学习
翻译自英文笔记
实践中,很少人从头开始训练神经网络(随机初始化),因为通常缺少一个足够大的数据集。通常,人们先在很大的数据集上预训练一个神经网络(比如:ImageNet),然后用这个网络作为初始化,或者固定的特征提取器,来训练自己感兴趣的任务,以下是三种主要的迁移学习方法:
- 卷积网络作为特征提取器,拿到一个在ImageNet上预训练的卷积网络,将它的最后一个卷积层移除(最后一层是1000个类的得分),然后将剩余的网络作为一个固定的特征提取器,来提取新数据集中的特征,在AlexNet中,对于每张图像我们得到一个4096维的向量,我们把这些特征称为CNN codes。重要的是,当它们在卷积网络在ImageNet上训练时被ReLUd的话,这些特征应该被ReLUd,得到了特征后,就可以训练一个线性分类器(SVM或Softmax)。
- Fine-tuning the ConvNet,第二个策略不仅仅取代最后一层,同事微调预训练网络前面的各层。可以fine-tune所有层,也可以保持最靠前几层的权值不变(为了避免过拟合)来调整靠后的层。这是因为前几层的特征包括了更加generic的特征(比如边界检测或色块检测)可适用于很多任务中,但是靠后的层就对原数据集具有一定的偏向性,以ImageNet为例,其中包括了很多犬种,所以网络很大一部分表达能力会致力于区分不同的犬种
- 预训练模型,因为现代的CNN在ImageNet上训练时,需要在多个GPU上训练2-3周,人们当前普遍的做法是把它们的checkpoints公开来让其他人进行fine-tuning,比如,Caffe 库就有一个Model Zoo,人们在那里分享它们的网络权值
何时、怎样进行fine-tune?
如何决定在新数据集上采用的迁移学习方法?这取决于多个因素,但两个最重要的是新数据集的大小和它与旧数据集的相似程度(比如ImageNet-like的图片,或者差异很大的显微镜图片),时刻记住卷积网络在前几层的特征更加的generic,后几层的特征更偏向数据集,以下是一些好的经验:
- 新数据集很小且与原数据集相似,不建议fine-tune,因为容易过拟合,既然数据和原数据相同,我们可以假定高层特征也适合新数据集的特征提取,因此,最好的方法是训练一个在CNN code上分类的线性分类器
- 新数据集很大且和原数据集相似。既然有了更多的数据,我们就可以相信我们不会过拟合,所以可以fine-tune整个网络
- 新数据集很小但和原数据集不同。既然数据集很小,最好就训练一个线性分类器,既然数据集不同,最好不要在网络的顶部训练这个分类器,因为这里包括了太多偏向原数据集的特征,反之,在网络前几层的位置训练一个SVM分类器是一个好的选择
- 新数据集很大但和原数据集不同,既然数据集很大,就可以从头开始训练网络,然后,在实践中,使用预训练的模型通常能达到更好的效果,这里我们有足够的数据因此可以fine-tune整个网络
实践建议:
- 预训练模型的局限性:注意如果你使用预训练模型,你可能限制了模型的结构,比如,你不能随意取出预训练模型中的一些卷积层,然而,有些东西可以直接改变:因为参数共享,你可以简单地在不同spatial size的图片上使用预训练模型
- 学习率:通常需要使用一个小的学习率来进行fine-tuning,这个“小”相对于从头训练而言,因为我们假定了网络的权值已经相对好了,所以我们不需再改变它们太多(尤其当随机初始化后的线性分类器在网络的顶部训练时)