2.7 Inception 网络(Inception network)

在上节视频中,你已经见到了所有的Inception网络基础模块。在本视频中,我们将学习如何将这些模块组合起来,构筑你自己的Inception网络。

(Deep learning)深度卷积网络实战——第三部分

Inception模块会将之前层的**或者输出作为它的输入,作为前提,这是一个28×28×192的输入,和我们之前视频中的一样。我们详细分析过的例子是,先通过一个1×1的层,再通过一个5×5的层,1×1的层可能有16个通道,而5×5的层输出为28×28×32,共32个通道,这就是上个视频最后讲到的我们处理的例子。

(Deep learning)深度卷积网络实战——第三部分

为了在这个3×3的卷积层中节省运算量,你也可以做相同的操作,这样的话3×3的层将会输出28×28×128。

(Deep learning)深度卷积网络实战——第三部分

或许你还想将其直接通过一个1×1的卷积层,这时就不必在后面再跟一个1×1的层了,这样的话过程就只有一步,假设这个层的输出是28×28×64。

(Deep learning)深度卷积网络实战——第三部分

最后是池化层。

(Deep learning)深度卷积网络实战——第三部分

这里我们要做些有趣的事情,为了能在最后将这些输出都连接起来,我们会使用same类型的padding来池化,使得输出的高和宽依然是28×28,这样才能将它与其他输出连接起来。但注意,如果你进行了最大池化,即便用了same padding,3×3的过滤器,stride为1,其输出将会是28×28×192,其通道数或者说深度与这里的输入(通道数)相同。所以看起来它会有很多通道,我们实际要做的就是再加上一个1×1的卷积层,去进行我们在1×1卷积层的视频里所介绍的操作,将通道的数量缩小,缩小到28×28×32。也就是使用32个维度为1×1×192的过滤器,所以输出的维度其通道数缩小为32。这样就避免了最后输出时,池化层占据所有的通道。

(Deep learning)深度卷积网络实战——第三部分

最后,将这些方块全都连接起来。在这过程中,把得到的各个层的通道都加起来,最后得到一个28×28×256的输出。通道连接实际就是之前视频中看到过的,把所有方块连接在一起的操作。这就是一个Inception模块,而Inception网络所做的就是将这些模块都组合到一起。

(Deep learning)深度卷积网络实战——第三部分

这是一张取自Szegety et al的论文中关于Inception网络的图片,你会发现图中有许多重复的模块,可能整张图看上去很复杂,但如果你只截取其中一个环节(编号1),就会发现这是在前一页ppt中所见的Inception模块。

我们深入看看里边的一些细节,这是另一个Inception模块(编号2),这也是一个Inception模块(编号3)。这里有一些额外的最大池化层(编号6)来修改高和宽的维度。这是另外一个Inception模块(编号4),这是另外一个最大池化层(编号7),它改变了高和宽。而这里又是另一个Inception模块(编号5)。

所以Inception网络只是很多这些你学过的模块在不同的位置重复组成的网络,所以如果你理解了之前所学的Inception模块,你就也能理解Inception网络。

(Deep learning)深度卷积网络实战——第三部分

事实上,如果你读过论文的原文,你就会发现,这里其实还有一些分支,我现在把它们加上去。所以这些分支有什么用呢?在网络的最后几层,通常称为全连接层,在它之后是一个softmax层(编号1)来做出预测,这些分支(编号2)所做的就是通过隐藏层(编号3)来做出预测,所以这其实是一个softmax输出(编号2),这(编号1)也是。这是另一条分支(编号4),它也包含了一个隐藏层,通过一些全连接层,然后有一个softmax来预测,输出结果的标签。

你应该把它看做Inception网络的一个细节,它确保了即便是隐藏单元和中间层(编号5)也参与了特征计算,它们也能预测图片的分类。它在Inception网络中,起到一种调整的效果,并且能防止网络发生过拟合。

还有这个特别的Inception网络是由Google公司的作者所研发的,它被叫做GoogleLeNet,这个名字是为了向LeNet网络致敬。在之前的视频中你应该了解了LeNet网络。我觉得这样非常好,因为深度学习研究人员是如此重视协作,深度学习工作者对彼此的工作成果有一种强烈的敬意。

最后,有个有趣的事实,Inception网络这个名字又是缘何而来呢?Inception的论文特地提到了这个模因(meme,网络用语即“梗”),就是“我们需要走的更深”(We need to go deeper),论文还引用了这个网址(http://knowyourmeme.com/memes/we-need-to-go-deeper),连接到这幅图片上,如果你看过Inception盗梦空间)这个电影,你应该能看懂这个由来。作者其实是通过它来表明了建立更深的神经网络的决心,他们正是这样构建了Inception。我想一般研究论文,通常不会引用网络流行模因(梗),但这里显然很合适。

(Deep learning)深度卷积网络实战——第三部分

最后总结一下,如果你理解了Inception模块,你就能理解Inception网络,无非是很多个Inception模块一环接一环,最后组成了网络。自从Inception模块诞生以来,经过研究者们的不断发展,衍生了许多新的版本。所以在你们看一些比较新的Inception算法的论文时,会发现人们使用这些新版本的算法效果也一样很好,比如Inception V2V3以及V4,还有一个版本引入了跳跃连接的方法,有时也会有特别好的效果。但所有的这些变体都建立在同一种基础的思想上,在之前的视频中你就已经学到过,就是把许多Inception模块通过某种方式连接到一起。通过这个视频,我想你应该能去阅读和理解这些Inception的论文,甚至是一些新版本的论文。

直到现在,你已经了解了许多专用的神经网络结构。在下节视频中,我将会告诉你们如何真正去使用这些算法来构建自己的计算机视觉系统,我们下节视频再见。

2.8 使用开源的实现方案(Using open-source implementations)

你现在已经学过几个非常有效的神经网络和ConvNet架构,在接下来的几段视频中我想与你分享几条如何使用它们的实用性建议,首先从使用开放源码的实现开始。

事实证明很多神经网络复杂细致,因而难以复制,因为一些参数调整的细节问题,例如学习率衰减等等,会影响性能。所以我发现有些时候,甚至在顶尖大学学习AI或者深度学习的博士生也很难通过阅读别人的研究论文来复制他人的成果。幸运的是有很多深度学习的研究者都习惯把自己的成果作为开发资源,放在像GitHub之类的网站上。当你自己编写代码时,我鼓励你考虑一下将你的代码贡献给开源社区。如果你看到一篇研究论文想应用它的成果,你应该考虑做一件事,我经常做的就是在网络上寻找一个开源的实现。因为你如果能得到作者的实现,通常要比你从头开始实现要快得多,虽然从零开始实现肯定可以是一个很好的锻炼。

如果你已经熟悉如何使用GitHub,这段视频对你来说可能没什么必要或者没那么重要。但是如果你不习惯从GitHub下载开源代码,让我来演示一下。

(整理者注:ResNets实现的GitHub地址https://github.com/KaimingHe/deep-residual-networks

(Deep learning)深度卷积网络实战——第三部分

假设你对残差网络感兴趣,那就让我们搜索GitHub上的ResNets,那么你可以在GitHub看到很多不同的ResNet的实现。我就打开这里的第一个网址,这是一个ResNets实现的GitHub资源库。在很多GitHub的网页上往下翻,你会看到一些描述,这个实现的文字说明。这个GitHub资源库,实际上是由ResNet论文原作者上传的。这些代码,这里有麻省理工学院的许可,你可以点击查看此许可的含义,MIT许可是比较开放的开源许可之一。我将下载代码,点击这里的链接,它会给你一个URL,通过这个你可以下载这个代码。

(Deep learning)深度卷积网络实战——第三部分

我点击这里的按钮(Clone or download),将这个URL复制到我的剪切板里。

(Deep learning)深度卷积网络实战——第三部分

(整理者注:NG此处使用的是linux系统的bash命令行,对于win10系统,可以开启linux子系统功能,然后在win10应用商店下载ubuntu安装,运行CMD,输入命令bash即可进入linuxbash命令行)

(Deep learning)深度卷积网络实战——第三部分

接着到这里,接下来你要做的就是输入git clone,接着粘贴URL,按下回车,几秒之内就将这个资源库的副本下载到我的本地硬盘里。

让我们进入目录,让我们看一下,比起Windows,我更习惯用Mac,不过没关系,让我们试一下,让我们进入prototxt,我认为这就是存放这些网络文件的地方。让我们看一下这个文件。因为这个文件很长,包含了ResNet里101层的详细配置。我记得,从这个网页上看到这个特殊实现使用了Caffe框架。但如果你想通过其它编程框架来实现这一代码,你也可以尝试寻找一下。

(Deep learning)深度卷积网络实战——第三部分

(Deep learning)深度卷积网络实战——第三部分

(Deep learning)深度卷积网络实战——第三部分

(Deep learning)深度卷积网络实战——第三部分

如果你在开发一个计算机视觉应用,一个常见的工作流程是,先选择一个你喜欢的架构,或许是你在这门课中学习到的,或者是你从朋友那听说的,或者是从文献中看到的,接着寻找一个开源实现,从GitHub下载下来,以此基础开始构建。这样做的优点在于,这些网络通常都需要很长的时间来训练,而或许有人已经使用多个GPU,通过庞大的数据集预先训练了这些网络,这样一来你就可以使用这些网络进行迁移学习,我们将在下一节课讨论这些内容。

当然,如果你是一名计算机视觉研究员,从零来实现这些,那么你的工作流程将会不同,如果你自己构建,那么希望你将工作成果贡献出来,放到开源社区。因为已经有如此多计算机视觉研究者为了实现这些架构做了如此之多的工作,我发现从开源项目上开始是一个更好的方法,它也确实是一个更快开展新项目的方法。

2.9 迁移学习(Transfer Learning)

如果你要做一个计算机视觉的应用,相比于从头训练权重,或者说从随机初始化权重开始,如果你下载别人已经训练好网络结构的权重,你通常能够进展的相当快,用这个作为预训练,然后转换到你感兴趣的任务上。计算机视觉的研究社区非常喜欢把许多数据集上传到网上,如果你听说过,比如ImageNet,或者MS COCO,或者Pascal类型的数据集,这些都是不同数据集的名字,它们都是由大家上传到网络的,并且有大量的计算机视觉研究者已经用这些数据集训练过他们的算法了。有时候这些训练过程需要花费好几周,并且需要很多的GPU,其它人已经做过了,并且经历了非常痛苦的寻最优过程,这就意味着你可以下载花费了别人好几周甚至几个月而做出来的开源的权重参数,把它当作一个很好的初始化用在你自己的神经网络上。用迁移学习把公共的数据集的知识迁移到你自己的问题上,让我们看一下怎么做。

(Deep learning)深度卷积网络实战——第三部分

举个例子,假如说你要建立一个猫咪检测器,用来检测你自己的宠物猫。比如网络上的Tigger,是一个常见的猫的名字,Misty也是比较常见的猫名字。假如你的两只猫叫TiggerMisty,还有一种情况是,两者都不是。所以你现在有一个三分类问题,图片里是Tigger还是Misty,或者都不是,我们忽略两只猫同时出现在一张图片里的情况。现在你可能没有Tigger或者Misty的大量的图片,所以你的训练集会很小,你该怎么办呢?

(Deep learning)深度卷积网络实战——第三部分

我建议你从网上下载一些神经网络开源的实现,不仅把代码下载下来,也把权重下载下来。有许多训练好的网络,你都可以下载。举个例子,ImageNet数据集,它有1000个不同的类别,因此这个网络会有一个Softmax单元,它可以输出1000个可能类别之一。

(Deep learning)深度卷积网络实战——第三部分

你可以去掉这个Softmax层,创建你自己的Softmax单元,用来输出TiggerMistyneither三个类别。就网络而言,我建议你把所有的层看作是冻结的,你冻结网络中所有层的参数,你只需要训练和你的Softmax层有关的参数。这个Softmax层有三种可能的输出,TiggerMisty或者都不是。

通过使用其他人预训练的权重,你很可能得到很好的性能,即使只有一个小的数据集。幸运的是,大多数深度学习框架都支持这种操作,事实上,取决于用的框架,它也许会有trainableParameter=0这样的参数,对于这些前面的层,你可能会设置这个参数。为了不训练这些权重,有时也会有freeze=1这样的参数。不同的深度学习编程框架有不同的方式,允许你指定是否训练特定层的权重。在这个例子中,你只需要训练softmax层的权重,把前面这些层的权重都冻结。

(Deep learning)深度卷积网络实战——第三部分

另一个技巧,也许对一些情况有用,由于前面的层都冻结了,相当于一个固定的函数,不需要改变。因为你不需要改变它,也不训练它,取输入图像X,然后把它映射到这层(softmax的前一层)的**函数。所以这个能加速训练的技巧就是,如果我们先计算这一层(紫色箭头标记),计算特征或者**值,然后把它们存到硬盘里。你所做的就是用这个固定的函数,在这个神经网络的前半部分(softmax层之前的所有层视为一个固定映射),取任意输入图像X,然后计算它的某个特征向量,这样你训练的就是一个很浅的softmax模型,用这个特征向量来做预测。对你的计算有用的一步就是对你的训练集中所有样本的这一层的**值进行预计算,然后存储到硬盘里,然后在此之上训练softmax分类器。所以,存储到硬盘或者说预计算方法的优点就是,你不需要每次遍历训练集再重新计算这个**值了。

(Deep learning)深度卷积网络实战——第三部分

因此如果你的任务只有一个很小的数据集,你可以这样做。要有一个更大的训练集怎么办呢?根据经验,如果你有一个更大的标定的数据集,也许你有大量的TiggerMisty的照片,还有两者都不是的,这种情况,你应该冻结更少的层,比如只把这些层冻结,然后训练后面的层。如果你的输出层的类别不同,那么你需要构建自己的输出单元,TiggerMisty或者两者都不是三个类别。有很多方式可以实现,你可以取后面几层的权重,用作初始化,然后从这里开始梯度下降。

(Deep learning)深度卷积网络实战——第三部分

或者你可以直接去掉这几层,换成你自己的隐藏单元和你自己的softmax输出层,这些方法值得一试。但是有一个规律,如果你有越来越多的数据,你需要冻结的层数越少,你能够训练的层数就越多。这个理念就是,如果你有一个更大的数据集,也许有足够多的数据,那么不要单单训练一个softmax单元,而是考虑训练中等大小的网络,包含你最终要用的网络的后面几层。

(Deep learning)深度卷积网络实战——第三部分

最后,如果你有大量数据,你应该做的就是用开源的网络和它的权重,把这、所有的权重当作初始化,然后训练整个网络。再次注意,如果这是一个1000节点的softmax,而你只有三个输出,你需要你自己的softmax输出层来输出你要的标签。

如果你有越多的标定的数据,或者越多的TiggerMisty或者两者都不是的图片,你可以训练越多的层。极端情况下,你可以用下载的权重只作为初始化,用它们来代替随机初始化,接着你可以用梯度下降训练,更新网络所有层的所有权重。

这就是卷积网络训练中的迁移学习,事实上,网上的公开数据集非常庞大,并且你下载的其他人已经训练好几周的权重,已经从数据中学习了很多了,你会发现,对于很多计算机视觉的应用,如果你下载其他人的开源的权重,并用作你问题的初始化,你会做的更好。在所有不同学科中,在所有深度学习不同的应用中,我认为计算机视觉是一个你经常用到迁移学习的领域,除非你有非常非常大的数据集,你可以从头开始训练所有的东西。总之,迁移学习是非常值得你考虑的,除非你有一个极其大的数据集和非常大的计算量预算来从头训练你的网络。

 

相关文章:

  • 2021-05-16
  • 2021-12-15
  • 2022-12-23
  • 2021-09-23
  • 2022-01-07
  • 2021-10-07
  • 2021-12-23
  • 2022-01-24
猜你喜欢
  • 2021-11-01
  • 2021-09-09
  • 2022-01-12
  • 2021-07-06
  • 2021-05-19
  • 2021-08-02
  • 2022-12-23
相关资源
相似解决方案