原作 Slav Ivanov Root 编译自 Slav寄几的博客 量子位 出品 | 公众号 QbitAI
Slav Ivanov是Post Planer(提高社交媒体影响力的App)的CTO,这个当过黑客后又从良当企业家的大叔,结合自己的创业经历,把他认为比较好的迁移学习的资料分享给大家。以下是他的原文。
现在很多深度学习的应用都依赖于迁移学习,特别是在计算机视觉领域,这篇文章主要给大家介绍一下什么是迁移学成,怎么完成迁移学习,以及可能存在的缺点。
我最开始接触迁移学习,是因为创业要用到。
不如开个公司吧?
有一天,一个朋友和我们聊了个脑洞大开的想法。他希望能做出下一个爆款社交媒体,宠物版的脸书。人们可以在展示他们主子的照片,以及看其他人的喵喵和旺财。我们都第一反应都觉得,这个主意还不错诶。
△ 我们以为:谁会不想翻一整天萌宠的照片?
我们很快筹到了资金,然后开始做潜在用户调查。在问了几个特别喜欢宠物的人之后,我们意识到个问题:喜欢猫的人并不怎么喜欢看狗的照片。养鹦鹉的人也不喜欢看猫的照片,养金鱼的人只喜欢看其他人养的金鱼。
因为现在已经2017年了,我们不再需要花费大力气挨个问人们喜欢看什么宠物的照片,我们直接借用机器学习的办法,去自动识别人们看的照片里是什么宠物。然后根据他们所看照片的宠物来分类。
卷积神经网络(CNN,Convolutional Neural Networks)
我们把我们的计划分享给了个刚拿到机器学习PhD的哥们,他建议我们用CNN来解决这个问题。
因为最初有个很牛逼的团队,由Alex Krizhevsky领头,凭借CNN赢得了那一年的ImageNet挑战赛(大体上相当于计算机视觉的年度奥林匹克),他把分类误差记录从 26% 降到了 15%。CNN的表现当时震惊了世界。
从那以后,CNN就成为了计算机视觉里的主流算法。也同样应用于其他深度学习领域。
如果大家对深度学习的概况想要有更多的了解,我墙裂建议大家去看fast.ai上的Practical Deep Learning for coders的第一部分和第二部分(本文提到的所有学习资料链接都放在最后咯,一会看完自取哈)。这些资料都是开放的。
对于卷积神经网络来说,我们需要分类的图像数据是输入。然后可学习后不断调整权重的参数,依据分类的不同我们会称之为过滤器或通道。这些过滤器层层堆在一起,在网络的最后一层,是输出,告诉我们这张图里是猫,或狗,或鸟之类的。
CNN的入门
所以我们就用fast.ai上的资料,然后自己搭建CNN。我们知道深度学习需要大量的数据,所以我们就下载了ImageNet数据库,里面有上百万张图,当然也包括猫狗、金鱼。
我们开始用这些数据来训练我们的模型,并用随机梯度下降算法(Stochastic Gradient Descent algorithm)来优化。过了不久,我们的CNN就可以区分猫狗和鹦鹉啦。我们还给这个模型起了个名字,宠物识别Pet-cognizer®。
其实,已经有很多前辈用ImageNet做了大量的工作,训练出很多CNN模型。这些经过预训练的神经网络都是开放的。有兴趣的话可以去看Pretrained Models on Keras and TorchVision for PyTorch。
CNN模型里第一层过滤器已经可以分辨出边界、渐变和纯色区域。第二层过滤器可以结合从第一层得到的数据去判断哪些是条纹,哪些是直角,哪些是圆。
第三层已经可以辨别人、鸟、汽车轮子之类的了。
最后,神经网络的输出层显示最后的分类结果。
就这样,我们的Pet-cognizer®搞定啦!
新的任务
当我们试运行我们的项目是,有人建议说如果我们能按狗狗的品种来分类就更好了。所以,我们再继续捣腾模型。我们把这种可以识别狗狗品种的模型叫做Breed-cognizer®。但问题在于,我们不能找到足够多的上百张狗狗的图片来训练我们的新模型。我们的数据集有120个数据源,每个有100张图。我们只能先尝试这用这个很小的数据来训练我们的CNN,可是结果很差。
△ 从零开始训练,所有结果都不对
Reddit上有一个板块专门是迁移学习,探讨怎么把之前建模的知识迁移到另一个任务里。
迁移学习,字面上看就是我们要做的事。所以我们决定重新考虑在已经训练好的Pet-cognizer®上,看看怎么改改再用。
场景1:新的数据集和最初的数据集是相似的。
我们的Breed-cognizer®所需的数据集,包含了真实世界里的图片(而不是文档的图片或者医学类的扫描),这一点和我们第一次训练用的ImageNet很像。所以是可以再用之前CNN的过滤器的。我们不用再学一次了。
对于Breed-cognizer®来说,我们仅仅把网络最后一层换了。因为我们现在要知道的,不再是这张图片是什么小动物,而是狗狗是什么品种。
因为最后一层权重是最初训练的时候随机设的,所以要训练最后一层并且调参的话,可能会改变上面几层的过滤器,所以我们就把除最后一层以外的所有层的权重都固定住,只优化最后一层。
△ 只训练最后一层的结果
精准微调
但是我们从训练的情况了解到,最后一层目前的参数不适合当前的任务。
比如说,模型里肯定有一些权重是倾向于更高效区分出猫和金鱼的。但是这个权重对推送狗狗照片没什么用。为了进一步优化我们的网络,我们还解锁倒数后几层,再重新微调。
那要解锁几层呢?这要看情况,我们一层一层试过去,直到发现再无法优化结果为止。
但因为这些被解锁层都对最后结果有影响,所以我们只能慢一点点地训练,希望尽可能做到保留有用的权重,而把无关的去掉。
训练的进度会影响到我们每一次梯度下降迭代的调参程度。这样精准地微调之后,推送识别器的准确率可以达到90%(在无法增加数据样本的情况下)。
场景2:新的数据集不再和最初的数据集一样
我们视觉识别模型的效果很好,越来越多的人听说到我们的模型表现后,开始联系我们,开出各种项目需求。其中一个还是卫星图像识别,另外一个是医学初创企业。
######△ 卫星图像
这两个项目需求的数据集都和我们曾经训练宠物识别器不一样。特别是医学上的CT影像。
△ 肺部的CT扫描
这种情况,还是用预训练过的权重更好,但是需要解锁所有网络层。然后我们在用新数据集,以正常的学习率训练。另外,斯坦福CS231n李飞飞主讲的王牌课程也论述了这个问题。
迁移学系几乎是所有视觉识别研究的主场。除非你有个庞大的数据集,否则很少会一上来从0开始训练。这篇入门文章所提到的学习资源可能会给你建立一定的感觉,迁移学习大概是怎么一回事,以及它的工作原理。
原文链接:https://blog.slavv.com/a-gentle-intro-to-transfer-learning-2c0b674375a0
最后给大家个List~~汇总下前面提到的学习资源(๑•̀ㅂ•́)و✧
- 深度学习概况:fast.ai
- 随机梯度下降算法概述:http://ruder.io/optimizing-gradient-descent/
- 更多预训练的神经网络 Pretrained Models on Keras:https://keras.io/applications/ TorchVision for PyTorch:http://pytorch.org/docs/master/torchvision/models.html
- 供参考的训练Breed-cognizer®的数据集:https://www.kaggle.com/c/dog-breed-identification/data
- 斯坦福CS231n李飞飞主讲的王牌课程 生肉:http://cs231n.github.io/transfer-learning/ 熟肉:http://study.163.com/course/introduction/1003223001.htm