如何使用目前学到的机器学习算法的实用建议。
如何使用开源?
事实证明,很多的神经网络系统都很难复现,因为很多调整超参数的细节,例如衰减率还有其他的一些细节都会给最终效果带来影响。
幸运的是,很多深度学习的研究人员都会习惯性的把它们的成果放到网上,比如GitHub,同时对于你的成果,我当然也鼓励你考虑将你的代码贡献给开源社区。
所以看到论文时,想实现,先去开源社区找一找,节省时间。
如何使用GitHub?
首先google搜索关键词(残差网络),找到GitHub可以看到很多代码实现的描述,这个代码是根据MIT开源许可代码协议开发的,可以通过点击快速浏览,也可以下载代码。
复制代码链接,在Python中输入git clone + 网址,就可以下载。
现在你已经开始开发一个计算机视觉图像应用,在这个过程中最常见的流程就是从选取一个你喜欢的框架开始,然后去找一个开源的代码实现。
这样做的好处是:
这些网络可能需要很长的时间训练,也许有人已经用多个GPU和大数据集训练好了,这样你就可以直接对这些网络使用迁移学习。
当然,如果你是一个计算机视觉的研究者,你可能需要从头构建这个神经网络框架,这样的话工作流程就会不同。
当然如果你从头构建,别忘记开源分享你的代码。。。
第二课:迁移学习
如果你想实现一个计算机视觉应用,而不像从零开始训练权重,比方说,从随机初始化开始训练,实现更快的方式通常是下载已经训练好权重的网络结构,把这个作为预训练,迁移到你感兴趣的任务中。
计算机视觉的研究社区已经很擅长把许多数据库发布到网络上,比如ImageNet MSCOCO,PASCAL等数据库,这些是已经公开在线的不同数据库。
许多计算机视觉的研究者已经在上面训练了自己的算法,有时,算法训练需要耗费好几周的时间,占据许多的GPU,事实上已经有很多人做过这种训练,也经历了这种痛苦的高性能调试过程,这意味着你可以下载这些开源的权重,有人曾花数周,或数月来调试这些权重可以用来作为你自己的神经网络好的初始化的开端,且可以用迁移学习来迁移知识。
从这些大型公共数据库迁移知识到你自己的问题上。
如何实现迁移学习?
比如你要建立一个可识别自己宠物猫的猫脸检测器:
因为你没有足够多的识别Tigger和Misty的图片,这样你的训练集很小,这时你可以从网络上下载一些开源应用:
不但下载源码,还要下载相关权重。你可以下载许多已经训练好的网络,例如在1000类物体的ImageNet数据库上训练,因此该网络可以输出千分之一类别概率的softmax神经元。
你要做的是去除softmax层,然后创造自己softmax层来识别Tigger/Misty/其他。
从网络方面看,我建议你考虑冻结前面这些层,即冻结该网络前面所有层的相应参数。因此可以只训练与你自己softmax层有关的参数,即只输出三个类别。通过用别人训练好的权重,即使在很小的数据库中也可以得到很好的性能。
幸运的是,对于很多深度学习框架支持这样的做法。事实上,根据框架结构,你可以把前面某些层这样设置(可训练参数等于零)。另一种说法是:不要训练这些权重,或有时你可以用一个参数,比如freeze = 1来设置网络,这些不同的方法和不同的深度学习框架可以让你来确定是否训练与某些具体层相关的权重。
另一个应用中比较巧妙地是:
由于前面的层全部被冻结了,之前有些固定函数不会变,因为你现在也不改动它,也不训练它,所以网络接受输入图像X,并把X映射到该层的激活函数上,因此这个方法可以加快训练,因为我们刚预计算过该层,而该层重激活产生的特征就直接保存在硬盘中。
你所做的就是用这个固定的函数,在该神经网络的前半部分,接受任一输入图像X,然后计算其特征向量,然后依据这个特征向量训练一个浅层的softmax模型去预测。因此预计算之前层的激活结果是有利于你计算的操作,(预计算)训练集所有样本(激活结果)并存在硬盘上,然后训练左边的softmax类别。
这样做的好处是:
预计算的好处是你不需要在训练集上每次迭代,都重新计算这些激活结果。
所以,如果你的训练集比较小,以上就是你可以做的工作。
如果你的训练集够大,一个经验之谈就是:
如果你有更大的带标签的数据集,比如有很多Tigger和Misty的照片,你可以冻结更少的层数,然后训练后面这些层,尽管输出层的类别与你需要的不同。
有几种这样做的方法:
你可以用最后几层的权重,作为初始化开始做梯度下降训练。
你也可以去掉最后几层,然后用自己的新神经元和最终softmax输出训练。
这两种方法都值得尝试。但有个模式,你的数据越多,所冻结的层数可以越少,自己训练的层数可以越多。
其中的想法就是如果你选了个数据集,有足够的数据,不仅可以训练单层softmax,还可以训练由所采用网络的最后几层组成的中型网络。
其次,如果你有很多数据,你可以用该开源网络和权重,用全部算法初始化整个网络,然后训练,你有越多的带标签的数据,你可以训练的层数就越多。极端就是你可以用下载的权重作为初始化,因此这些权重可以代替随机初始化,然后做梯度下降训练,来更新所有权重和网络层。
总结:
这就是卷积神经网络训练中的迁移学习,实际上因为网上公开数据库非常大,你下载的权重也是别人从大量数据上花费数周训练而来的,你会发现对于很多计算机视觉应用来说,如果你下载别人的开源的权重来初始化自己的问题,你可以做的更好。
我认为计算机视觉是其中一个迁移学习可以一直应用的领域,除非你有特别大的数据集从零来训练自己的网络。而迁移学习值得认真考虑除非你的确拥有海量的数据和计算资源来自己从零开始。
第三课:数据增强
大多数计算机视觉需要用到很多数据,因此数据增强是其中一种常用的技术用于改善计算机视觉系统的性能。
计算机视觉很麻烦,因为你要把所有的像素输入到计算机中,貌似你需要训练出一个相当复杂的函数来做这件事。事实上,更多的数据对于几乎所有的计算机视觉工作都有好处。
我认为计算机视觉,对于绝大多数问题,我们总是不能获得足够的数据。那么这就意味着,当你在训练计算机视觉模型时,数据增强往往会有所帮助。
无论你是用迁移学习即用其他人预先训练好的模型来开头,还是试着从零开始训练自己的模型。
常见的计算机视觉中的数据增强方法:
最简单的数据增强方式:垂直镜像
并不完美的数据增强方式:随机裁剪,获得了不同的示例来扩充训练集
旋转
剪切
局部弯曲
...
第二类常用的数据增强的方法:色彩变化
RGB通道加入扰动
色彩变化
...
使得你的学习算法在应对图像色彩变化时健壮性更好。
脚注:有不同的方式来采样红蓝绿通道
其中一种色彩干扰的算法:PCA主成分分析/PCA色彩增强
如果你的图像主要呈紫色,即主要是红色和蓝色,带一点点绿色,那么PCA色彩增强,会增加和减少很多红色和蓝色的值,却对绿色值做很小的更改,因此来保持整体和之前相同的着色。
算法细节在AlexNet的论文中有描述!也可以找一些PCA色彩增强的开源代码!
你也许想将训练样本存在硬盘上,但是如果是一个非常大的训练集合,这是一个非常常见的情况,这里你也许会有一个CPU进程,不断地从硬盘中加载图像,你能做的就是用一个CPU进程来实现失真,可以是随机裁剪,或色彩变化,或镜像,对每个图像你就可以获得一些它的失真版本。
这里你的CPU线程不断地加载数据并作一些必要的失真处理,来行程一批或几小批数据,这些数据会不断地传给其他线程或进程,来实现训练学习,这些可以在CPU或GPU上实现,如果训练一个大的神经网络,后者越来越多的被用到。
因此,一个常用的数据增强的方法是:
通过一个线程,几乎是四个线程,用来加载数据并作失真处理,然后传递给其他线程或进程用来做深度学习训练,通常这两步可以并行。
以上,就是数据增强。
数据增强也有一些超参数:
例如要实现多大程度的色彩变化和具体用什么形式来做随机裁剪?
同计算机视觉其他部分一样,找到一个其他人用于数据增强的开源算法,也是一个很好的开始。
第四课:计算机视觉现状
对于深度学习在计算机视觉中的应用及现状有几个独特的方面,帮助你阅读以及如何搭建用于计算机视觉的系统?
大多数机器学习问题就是:
从拥有相对较少的数据————到拥有大量数据之间的问题。
如果纵观机器学习问题的发展,你会发现一般情况下,当你有很多数据的时候,你会发现差不多使用比较简单的算法,以及更少的人工设计就可以了。
即不太需要针对问题来仔细的设计特征
当你有大量数据的时候,你可以用一个巨大的神经网络,甚至更为简单的结构,就让一个神经网络学习我们想要学习的。
当你没有很多数据时,通常会发现人们更多的人工设计,即更多的手工处理,人工设计实际上是当你没有很多数据量时获得良好效果的最好方法。
通常机器学习算法有两个知识来源:
1.标记的数据,用于监督学习的(x,y)
2.人工设计,而且有很多方法可以用来手工设计一个系统,它可以精心的设计特性,到精心设计网络结构,抑或系统的其他组件。
所以当你没有太多的标记好的数据时,就需要在人工设计上下功夫。
我认为计算机视觉正试图学习一个非常复杂的函数,我们经常觉得没有足够的用于计算机视觉的数据,这就是为什么计算机视觉还非常依赖与人工设计。
所以在计算机视觉领域开发了相当复杂的网络结构,因为在没有足够的数据量的情况下,获得良好性能的途径就是花更多时间去精心设计。
但从历史的角度看,我认为对于计算机视觉使用非常小的数据集的担忧以及一直以来计算机视觉文献依赖于大量人工设计的担忧,即使最近几年 ,数据的量级伴随着正确的计算机视觉任务也有了显著地增加,这已经导致了一直以来做的人工设计的数量有了明显的减少。但仍然有很多网络结构和计算机视觉方面的人工设计,这就是为什么仍能在计算机视觉领域,看到相比与其他领域非常复杂的算法。
实际上,你通常有比图像识别数据更小的目标检测数据集,当谈及目标检测时,你会看到算法变得更复杂,并具有更为特定化的组件。
所幸的是,当只有少量数据时,迁移学习可以有很大的帮助,例如对于家猫的识别,这些都不是检测问题,你只有非常小的数据,迁移学习也会工作的不错。这是另外一种技术,被广泛使用于数据量很少的情况下。
对于计算机视觉的研究者而言,如果你在基准数据上做的很好,就很容易发表文章,所以很多人关注在基准数据上取得好的结果。
这样做的好处是:
它帮助整个学科领域搞清楚哪些是最有效的算法,但是你也看到,文章中的一些工作只是为了让你在基准数据上取得好结果。但是这个算法并不会真的应用于你现实中要发布的产品或者系统上。因此在这,我有一些对在基准数据上做的好的一些小建议:
如果我要把一个系统放到实际服务客户的产品中:
1.集成。在弄清楚了你要用什么神经网络,独立的训练多个神经网络,然后对它们的输出求平均作出结果,要对它们的输出y帽求平均,不要对权重求平均。
但是因为集成意味着要在每幅图像上进行测试,或许需要将一副图像输入到3到15个神经网络,这样会减慢运行速度,所以集成是人们在基准数据上测试获得好成绩的小贴士之一。
2.测试时使用多重剪切
多重剪切其实就是在你的测试图像上,应用图像增强的一种形式,这也许能为一个产品化的系统带来些许性能上的提升。
相比于集成,它不会吞噬太多内存,但它仍然很大程度上降低运行速度。
3.一个神经网络系统在某个视觉问题上效果很好,通常惊人的是它们大多在另外的视觉问题上也能用。
因此,要搭建一个有用的系统,你一般要做的是从别人的神经网络架构开始,而且如果可能,开源实现。
4.先使用别人预先训练的模型,然后在你的数据集上进行微调,你通常可以在你的应用上很快取得进展。