11.1 迁移学习
1. 迁移学习是什么?
迁移学习就是能在一个任务上学习一个模型,然后用其来解决相关的别的任务,这样我们在一个地方花的时间,学习的一些知识,研究的一些看法可以在另外一个地方被使用到; 例如,如果你已经训练好一个神经网络,能够识别像猫这样的对象,然后使用那些知识,或者部分习得的知识去帮助您更好地阅读x射线扫描图,这就是所谓的迁移学习。假设你已经训练好一个图像识别神经网络,所以你首先用一个神经网络,并在(x,y)对上训练,其中x是图像,y是某些对象,图像是猫、狗、鸟或其他东西。如果你把这个神经网络拿来,然后让它适应或者说迁移,在不同任务中学到的知识,比如放射科诊断,就是说阅读X射线扫描图。你可以做的是把神经网络最后的输出层拿走,就把它删掉,还有进入到最后一层的权重删掉,然后为最后一层重新赋予随机权重,然后让它在放射诊断数据上训练。迁移学习在深度学习领域应用非常的广泛,因为在深度学习中需要训练很多的深层神经网络,需要很多的数据,代价也很高。
2. 迁移学习的途径:
1.做好一个模型将其做成一个特征提取的模块,例如Word2Vec在文本上做训练一个单层神经网络,在训练好之后,每一个词对应一个特征,然后用这个特征去别的事情。ResNet则是对图片做特征,然后用这个特征来对作为另一个模型的输入,这样假设效果非常好,那么就可以代替人工去抽取特征,而I3D则是用来对视频做特征。
2.在一个相关的任务上训练一个模型,然后在另一个任务上直接用它。
3.训练好一个模型,然后在一个新的任务上对其做微调,使模型能更好的适应新的任务;
3. 相关的领域:
1.半监督学习:利用没有标号的数据,让有标号的数据变得好
2.在极端的条件下,可以做zero-shot,即每一个任务有很多的类别,但是我任何样本都不告诉你,让你预测;或采用few-shot,一个任务就给你一些对应的样本。
3.Multi-task learning:每一个任务都有它自己的数据,但是数据不是很够,可是任务之间相关,那么可以将所有的数据放在一起,然后同时训练多个任务出来,这样我们希望能从别的任务之中获益
4.迁移学习在计算机视觉领域:
不管是共有数据还是私有数据,在图片分类领域中存在了很多大规模标好的数据集。把迁移学习应用到CV领域,我们可以把存一些有很多数在应用上比较好的模型,让它的知识拓展到我们自己的对应的任务上去。因为我们自己任务的数据集会比大的数据集要小很多,然后我们想要快速的迭代,看看能不能用比较大的数据集来将一些学到的东西迁移到我们自己的任务上面去。经典规则是:“如果你有一个小数据集,就只训练输出层前的最后一层,或者也许是最后一两层。但是如果你有很多数据,那么也许你可以重新训练网络中的所有参数。
5.预训练(Pre-train):
在一个比较大的数据上训练好的一个模型,会具有一定的泛化能力,也就是说把这个已经训练好的模型(权重)放到新模型上或新的数据集上,这个模型还是有效果的,比如在图片分类预训练好的模型也可以用来试试目标检测 。
6.微调(Fine-tuning):
把预训练好的模型用在新任务上叫Fine-tuning(微调)。即在新的任务上构建一个新的模型,新的模型的架构要更预训练的模型的架构是一样的;在找到合适的预训练模型之后要初始化我们的模型,我们将预训练模型的除了最后一层(图中的Output layer)之外的权重(图中的Layer1~N)都复制给我们的模型,最后一层(图中的Output layer)的解码器用的还是随机的权重。
在初始化之后,就可以开始学习了,但是有一个小tips:我们要限制Fine-tuning的学习率。因为我们初始的结果已经比较好了,已经在想要解的附近了,限制学习率可以使得我们可以不会走太远,一般是用1e-3(0.001);另外是说不要训练太长的时间,把数据扫个10/50遍,这些做法是为了缩小搜索空间。
7.限制搜索空间(不要训练太多epoch):
限制搜索空间方法—固定最底层:神经网络是层次化的,最底层一般是学习了底层的特征,上层的更与语义相关,一般来说底层与上面层没有太多的关系,在换了数据集之后泛化性都很好。最后一层(Output layer)还是随机初始化学习,然后只对某一些层进行改动,最下面那些层在微调时基本不在改动,即学习率为0。固定住多少层是要根据应用来看的,假设应用与预训练模型差别比较大的话,可以多训练一些层。
8.寻找预训练模型:
Tensorflow Hub: https://tfhub.dev/;
TIMM(一位小哥把pytorch上能找到的各种代码实现弄过来):
https://github.com/rwightman/pytorch-image-models
9.Fine-tuning应用:
在大的数据集上训练好模型再微调到自己的应用上在CV领域上广泛的应用。新的任务包含目标检测、语义分割等(图片类似但是目标不一样),在医疗领域等(同样的任务但是图片大相径庭),现在的观点是微调加速了收敛(微调让初始的点不再试一个随机的点而是一个离最终的目标比较近的点,使得损失比较平滑),但是不一定可以提升精度(一般不会让精度变低,因为它只是改变初始值而已,跟随机初始化没区别,只要走的足够远也能摆脱初始值的影响)。
比如你用100张图训练图像识别系统,然后有100甚至1000张图用于训练X光片诊断系统,人们可能会想,为了提升X光片诊诊断的性能,假设你真的希望这个X光片诊诊断系统做得好,那么用X光片诊图像训练可能比使用猫和狗的图像更有价值,所以这里(100甚至1000张图用于训练X光片诊诊断系统)的每个样本价值比这里(100张图训练图像识别系统)要大得多,至少就建立性能良好的X光片诊系统而言是这样。所以,如果你的X光片诊断数据更多,那么你这100张猫猫狗狗或者随机物体的图片肯定不会有太大帮助,因为来自猫狗识别任务中,每一张图的价值肯定不如一张X射线扫描图有价值,对于建立良好的X光片诊诊断系统而言是这样。所以,这是其中一个例子,说明迁移学习可能不会有害,但也别指望这么做可以带来有意义的增益。
总结:
1.如果你想从任务A学习模型并迁移一些知识到任务B中,那么当任务A和任务B都有同样的输入x时,迁移学习是有意义的。比如,A和B的输入都是图像,或者两者输入都是音频。
2.此外,当任务A的数据远远大于任务B时,迁移学习才有帮助。如果你希望提高任务B的性能,但是任务B可以训练的数据有比较少,但是任务A的数据比任务B的大得多,因为任务A里单个样本的价值没有比任务B单个样本价值大。
3.其次如果任务A的一些低层次特征,可以帮助任务B的学习,那么迁移学习也是有意义的。