您好、欢迎来到现金彩票网!
当前位置:刘伯温论坛 > 图像分割 >

看一遍你也会做!用英伟达 DIGITS 进行图像分割(下)

发布时间:2019-06-19 06:16 来源:未知 编辑:admin

  雷锋网按:本文上接看一遍你也会做!用英伟达 DIGITS 进行图像分割(上)。已阅读的小伙伴儿可直接跳到教程部分。

  7 月 8 日,英伟达深度学习学院 DLI线下训练营即将来到深圳,主题是图像分类、目标检测与图像分割的零基础开发入门。

  虽然是全球范围内顶级的 AI 培训项目,但 DLI 进入中国的时间太晚,中文网页也才上线没多久,导致国内开发者只知英伟达的显卡,却不知道英伟达有线上、线下的 AI 技术培训。此前雷锋网曾撰文介绍过 DLI,详情戳这里。

  闲话少说,本期深圳 DLI 训练营主要用到 DIGITS 和 TensorFlow 两个工具。TensorFlow 大家都知道,不必介绍。但对 DIGITS 就很陌生了,它是什么呢?

  DIGITS 是英伟达为普及深度学习开发的图形化操作界面,简单易用,旨在帮助初学者跨越入门障碍,迅速上手。因此,DLI 的入门培训均要求学员从DIGITS 起步。

  说白了,DIGITS 就是一个新手工具。但由于 DLI 刚刚进入中国,关于 DIGITS 的教程和信息并不充足,为初学者带来信息鸿沟。 因此,雷锋网对这篇英伟达博客发布的官方教程进行了编译。该教程指导读者用 DIGITS 5 和 Caffe 进行图像分割,它脱胎于 DLI 的线上实验室(online labs)培训课。后者收费且只用英文授课,并不对非会员开放。但大家能从这篇教程对其了解一个大概。

  更重要的,7 月 8 日深圳的 DLI 线下训练营,三场主要培训分别是用DIGITS 进行图像分类,用 DIGITS 目标检测,以及用 TensorFlow 进行图像分割(了解详情请点此)。虽然前两场的内容与本教程并不一致,最后一场的难度比本文高出许多,而且用的是 TensorFlow 而非 Caffe,但这篇教程与 DLI 付费培训的内容已十分接近。

  前一节展示了如何设计一个FCN ,来预测每个窗口的某个类的概率分布。显然,窗口的数量取决于输入图像的大小、窗口的大小和扫描输入图像时窗口之间的步长。理想情况下,一个图像分割模型将生成图像中所有像素的概率分布。在实践中如何做到呢?这里将使用FCN paper上的一个方法。

  当输入图像遍历卷积化的 Alexnet 的连续层时,像素数据的输入被高效地压缩成一组粗化的、更高级的特性表征。图像分割的目的是篡改这些粗化的特征来重建细分类,对输入中的每个像素都是如此。事实证明,这在解卷积层中很容易实现。这些层执行与卷积层相反的操作:给定了卷积输出,一个解卷积层会将输入生成输出,从而给出过滤器的定义。记住,卷积中的跨层(或池化层)定义了处理输入时窗口的滑动距离,以此来衡量下游输出。相反,解卷积层的步幅是衡量上游取样的输出。若选择步幅为4,那么输出将是4倍大!

  下一个问题是:给定模型中的最终卷积层,需要对其激活做多大幅度的升采样,才能使输出与输入图像的大小相同?我需要仔细检查每层并写下它的缩放因子。一旦每一层都这样处理,我只需将缩放因子相乘并汇总。让我们看看第一个卷积Alexnet层。

  conv1的步幅是4,因此缩放因子是1/4。所有层都重复这样做,我确定了总缩放因子在模型中是1/32,如Table 2中概述那样。这样,解卷积层的步幅就是32了。

  出于严谨,我不得不说,“在所有的空间维度上,一个步幅为S的卷积层,产生的输出都是输入的1 / S”这句话并不是完全正确的。在实践中,向输入加入填充P 0将会增加激活数。相反,使用大小为 K 1的核(kernels)将会减少输入端的激活数。在此限制下,如果你为卷积层提供了一个无限长的输入,输入/输出大小的比例在所有的(空间)维度上实际是1 / S。现实中,每一个卷积(池)层的输出被偏移了(P -(k - 1)/ 2)/ S。

  例如,考虑conv1:因为这一层在两侧各有100像素的填充,它的输出比无填充的更大。通过上面的公式,我们可以计算出输出的每一侧在理论上有23.75个额外像素。随着添加更多层,这会累积起来。通过向后运行图,可以计算所有层的累计抵消。L1与L2层的组合(i.e. 在Caffe术语中,L2是L1的底层,L1、L2 又分别抵消 O1、O2) 会抵消O2 / F + O1,这里F是L2的累积缩放因子。

  表2:卷积化的Alexnet中,遍布连续层的缩放因子和抵消补偿。* 对反卷积层来说缩放因子等于步幅,抵消等于(k - 1)/ 2 p。

  表2表明,通过所有conv1到upscore的层时,神经网络的输出被18个像素根据输入做了相应移动。最后一个分割模型中的技巧,是一个修剪网络输出、移除每个边界上额外的18像素的层。这很容易在Caffe 的 Crop layer 中实现,下面的清单中对这些做了定义。

  你可能会注意到,这个版本的Alexnet的内边距(padding)比你经常在conv1层遇到的多一点。这背后有两个原因:一个原因是,产生了更大的初始化偏移,以补偿连续层没有吃进图像的缺失。然而,主要的原因是网络以最佳方式处理输入图像的边界 ,以命中网络可接受域的中心,大概就是这样。

  现在,我有了从FCN paper复制FCN FCN-Alexnet模型所需的一切。我们可以放松一下,欣赏一些SYNTHIA数据集里的图像。

  SYNTHIA数据集的样本图像见图9。这些图像展示了用不同的对象类合成的城市场景,比如不同条件下的建筑物、道路、车辆和行人, 如昼夜。有趣的是,图片看起来特真实以致于有时候人们会被它们吸引:嗯,第一张图片上那个在路中间看报纸的人有点反常,这么干很危险。

  在 DIGITS 5.0 中,创建一个图像分割数据集十分简单,只需要选中输入和真实样本图像文件夹,点击“Create”按键。DIGITS 支持多种标签格式,比如画板图片(它的标签图像中的像素值是彩色画板的指数)和 RGB 图片(每种颜色指示一个类)。

  在 DIGITS 中创建数据集之后,你可以探索数据库在视觉上检查它们的内容,见图10。

  在DIGITS里训练模型,有数据集和对神经网络的描述就够了。如果你觉得用卷积Alexnet太复杂太耗时的话,别烦恼:DIGITS 5.0版有一个模型商店,而且就像你能想象的那样,FCN-Alexnet可以从这个模型商店里下载!

  但如果你决定要走一条更难的路,去创造自己的模型描述,就可能要找一个合适的权重初始值方案,比如说Kaiming方法(另名MSRA),是目前最前沿的修正流线性单元形式。这个在Caffe里很容易实现,只要加上一个权重过滤器{ type: msra }指向你的参数层就好了。如果在DIGITS里用这种方法训练模型,很有可能得到像图11的曲线。从图中可以看出,结果并不尽如人意。验证集的准确程度在35%的时候达到最高(意思是说只有在验证数据集里35%的像素被准确地标记出来)。训练损失跟验证损失一致,意味着这个网络(模型)对训练数据集欠拟合。

  图11: 用Synthia数据训练FCN-Alexnet网络(模型),在DIGITS里面利用随机权重初始值方法得到的训练集/验证集的损失和准确率:蓝线--训练集的损失走势,绿线--验证集的损失走势,黄线--模型结果在验证集里的准确率

  你可以在一个样例图片上试试运气,让DIGITS帮你完成图片分割的可视化。你会发现网络(模型)会不分青红皂白的把所有元素都归类成“建筑物”,就像图12所示。原来在SYNTHIA数据中,“建筑物”是最具代表性的目标类别,而网络(模型)只是懒洋洋地进行了学习并把所有图片元素都标记成了“建筑物”才达到了35%的准确率。那么,一般可接受的处理这种网络(模型)在训练集里欠拟合的方法都有哪些呢?

  拉长训练时间:只观察损失曲线的走势,训练过程貌似达到了最高,然而这很可能没什么帮助。网络(模型)很有可能进入了局域最小值而且不能从中脱离出来。

  提高学习率同时减少每批量的大小:这样做可以鼓励陷入局域最小值不能自拔的网络(模型)去探索周围环境之外的区域,尽管这样会增大网络(模型)发散的风险。

  还有一种方法我发现在计算机视觉中应用得非常好:转化学习。更多请继续往下读。

  图12:图片分割可视化的样本展示:网络(模型)把所有元素都归类成了“建筑物”。此样本是利用随机权重初始值的方法,在DIGITS里用Synthia数据训练FCN-Alexnet网络(模型)得到的。

  你不用非得从随机初始化权重开始,来训练一个模型。很多情况下,重新利用网络(模型)训练另外一组数据中的得到的认知,会很有帮助。这种方法在计算机视觉里通过CNN网络(模型)尤其奏效,因为很多低级的特征(线路,拐角,形状,纹理)可以马上应用在任意数据中。由于图片分割是在像素水平下做分类分析,从类似ILSVRC2012这样的图片分类数据集里做迁移学习十分合理。利用Caffe这样做就变得相当简单---当然需要设立一个或两个陷阱!

  记得在Alexnet的fc6模型中(图8),权重的形状是4096×9216。在FCN-Alexnet的conv6模型中,权重的形状是4096x256x6x6。这其实是一样的权重值,但是由于形状不同,Caffe不能自动把权重转交到FCN-Alexnet模型里。这个任务可以交给“net surgery(网络手术)”脚本来履行,脚本例子可以在Github网站里的DIGITS知识库找到。网络手术脚本的功能在于把参数从全连接层移植到对应的卷积层里。然而,你会发现从公共的DIGITS模型商店里下载提前训练好的模型会更简单一些。图13展示了模型商店的界面:在“FCN-Alexnet”旁边,点击“导入”,DIGITS就会下载提前训练好的模型。

  你可能会有另外一个顾虑,那就是怎样初始化早先加入到该文本的升采样层呢?别忘了,此升采样层并不是原始Alexnet模型中的一部分。在FCN那篇论文中,作者建议随机初始化对应的权重,然后让网络(模型)学习它们。该篇论文的作者后来意识到,初始化这些权重其实很简单,通过做双线性插值,让升采样层充当放大镜就可以了。在Caffe里,这种方法可以通过加上一个权重过滤器{ type: bilinear }指向升采样层来实现。

  利用一个提前训练好的FCN-Alexnet模型,你会注意到,在检测图14这种个别图像的时候,准确率会快速超过90%。检测到9个不同的类别,图形分割结果会变得更有说服力。但你还是会有点失望,因为物体轮廓仍然非常模糊。请继续往下读本文的最后一个章节:如何进一步提高分割模型的精确性和准确性。

  图14:图片分割可视化的样本展示。此样本是利用一个提前训练好的ILSVRC2012-Alexnet模型,在DIGITS里用Synthia数据训练FCN-Alexnet网络(模型)得到的。

  之前加进FCN-Alexnet的升采样层,把conv7的输出值扩大了32倍。在实际应用中,这意着对于每个32×32的像素块,神经网络会做一次预测。这也就解释了为啥目标物体轮廓会那么模糊。那篇FCN文章介绍了另外一个非常棒的主意来解决上面的局限:跳过那些被加入的连接层,直接把pool3和pool4的输出值重新定向到网络的输出值上。由于那些汇总层(pool3, pool4)位于网络的靠后方向,它们就可以在低水平的特征上运作,从而能够抓到更细致的细节。

  在一个叫做FCN-8s的网络结构中,那篇FCN文章介绍了一个基于VGG-16的网络,利用这个网络,最后输出结果可以是pool3的总和采样层×8,可以是pool4的采样层×2,还可以是conv7的采样层×4,如图15所示。这就引导出一种网络,能够在更细分的纹路生成预测,向下到8×8的像素块。

  为了方便使用,用户可以在公共的DIGITS模型商店里下载一个提前训练好的FCN-8s。(你肯定不想自己动手卷积VGG-16)如果你用DIGITS在SYTHIA数据上训练FCN-8s,你会发现仅仅经过几个epoch(时期),验证集的准确率就能超越95%。更重要的是,当你在一个样本图片上做实验,观察DIGITS的高超图片分割可视化的时候,你会看到更为清晰的物体轮廓,像图16中那样。

  图16: 图片分割可视化的样本展示。此样本是利用DIGITS在Synthia数据上训练FCN-8s网络(模型)得到的。

  读过本文之后,怎样开始做图片分割,你应该心里有谱了。DIGITS 5会在12月份的第一个星期发布。访问DIGITS网站继续学习,注册NVIDIA Developer program账号,以便下载版本可用时及时收到通知。

  DIGITS在GitHub上是一个可共享的开源项目。如果你想上手实践图片分割技术,请直接访问DIGITS GitHub项目网页,以便得到源代码。

http://airgomusic.com/tuxiangfenge/364.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有