Machine Learning Mastery 计算机视觉教程(八)
ImageNet 挑战赛(ILSVRC)的温和介绍
最后更新于 2019 年 7 月 5 日
深度学习神经网络技术的普及和使用可以追溯到卷积神经网络应用于图像分类任务的创新。
一些最重要的创新来自学者和行业领袖提交给 ImageNet 大规模视觉识别挑战赛或 ILSVRC 的参赛作品。ILSVRC 是一年一度的计算机视觉竞赛,是基于一个名为 ImageNet 的公开计算机视觉数据集的子集开发的。因此,任务甚至挑战本身通常被称为 ImageNet 竞赛。
在这篇文章中,您将发现 ImageNet 数据集、ILSVRC 以及由竞赛产生的图像分类中的关键里程碑。
看完这篇文章,你会知道:
- ImageNet 数据集是一个非常大的人类注释照片集合,由学者设计用于开发计算机视觉算法。
- ImageNet 大规模视觉识别挑战赛(ILSVRC)是一项年度竞赛,使用 ImageNet 数据集的子集,旨在促进最先进算法的开发和基准测试。
- ILSVRC 任务已经导致了计算机视觉和深度学习交叉领域的里程碑模型架构和技术。
用我的新书计算机视觉深度学习启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
对 ImageNet 和大规模视觉识别挑战的温和介绍 图片由汤姆·霍尔提供,保留部分权利。
概观
本教程分为三个部分;它们是:
- imagenes 数据集
- imageset 大规模视觉识别挑战
- 来自 ILSVRC 的深度学习里程碑
imagenes 数据集
ImageNet 是一个旨在用于计算机视觉研究的带注释照片的大数据集。
开发数据集的目的是提供一种资源,促进计算机视觉改进方法的研究和开发。
我们认为,大规模的图像本体是开发先进的、大规模的基于内容的图像搜索和图像理解算法,以及为这些算法提供关键的训练和基准数据的关键资源。
——ImageNet:大规模分层图像数据库,2009。
基于对 ImageNet 主页上记录的数据集的统计,数据集中有 1400 多万张图像,2.1 万多组或类(synset)以及 100 多万张带有边界框注释的图像(例如图像中已识别对象周围的框)。
这些照片由人类使用众包平台(如亚马逊的机械土耳其人)进行注释。
开发和维护数据集的项目是通过普林斯顿、斯坦福和其他美国大学的学者之间的搭配来组织和执行的。
该项目不拥有构成图像的照片;相反,它们属于版权所有者。因此,数据集不是直接分布的;向数据集中包含的图像提供网址。
ImageNet 大规模视觉识别挑战
ImageNet 大规模视觉识别挑战赛简称 ILSVRC,是一项在 2010 年至 2017 年间举办的年度竞赛,挑战任务使用 ImageNet 数据集的子集。
挑战的目标是既促进更好的计算机视觉技术的发展,又对最先进的技术进行基准测试。
一年一度的挑战集中在“图像分类”的多项任务上,包括基于照片中的主要对象为图像分配类别标签,以及涉及定位照片中的对象的“对象检测”。
ILSVRC 注释分为两类之一:(1)二进制标签的图像级注释,用于指示图像中是否存在对象类,[…]以及(2)图像中对象实例周围的紧密边界框和类标签的对象级注释
——ImageNet 大规模视觉识别挑战赛,2015 年。
大多数年份的一般挑战任务如下:
- 图像分类:预测图像中存在的对象的类别。
- 单对象定位:图像分类+围绕每个呈现对象的一个示例绘制一个边界框。
- 对象检测:图像分类+在每个出现的对象周围画一个包围盒。
最近,鉴于静态照片技术的发展取得了巨大成功,挑战任务正在转变为更困难的任务,如给视频贴标签。
数据集包括大约 100 万幅图像和 1,000 个对象类。挑战任务中使用的数据集有时是不同的(取决于任务),并公开发布,以促进学术界和工业界的广泛参与。
对于每个年度挑战,都会发布一个带注释的训练数据集,以及一个未经注释的测试数据集,必须对其进行注释并提交给服务器进行评估。通常,训练数据集由 100 万幅图像组成,其中 50,000 幅用于验证数据集,150,000 幅用于测试集。
公开发布的数据集包含一组手动注释的训练图像。还发布了一组测试图像,保留了手动注释。参与者使用训练图像训练他们的算法,然后自动注释测试图像。这些预测的注释被提交给评估服务器。评估结果将在比赛结束时公布
——ImageNet 大规模视觉识别挑战赛,2015 年。
在计算机视觉会议的年度研讨会上介绍了结果,以促进成功技术的共享和传播。
尽管您必须注册,但每个年度挑战赛的数据集仍然可用。
来自 ILSVRC 的深度学习里程碑
从事 ILSVRC 任务的研究人员已经将计算机视觉研究的前沿推了回来,描述它们的方法和论文是计算机视觉、深度学习以及更广泛的人工智能领域的里程碑。
ILSVRC 头五年的改进速度是惊人的,甚至可能令计算机视觉领域感到震惊。成功主要是通过图形处理单元(GPU)硬件上的大型(深度)卷积神经网络(CNNs)实现的,这引发了对深度学习的兴趣,深度学习超越了领域,进入了主流。
从 ILSVRC2010 到 ILSVRC2014,最先进的精确度有了显著提高,展示了过去五年在大规模对象识别方面取得的巨大进步
——ImageNet 大规模视觉识别挑战赛,2015 年。
竞赛前五年 ILSVRC 任务改进总结。 摘自 ImageNet 大规模视觉识别挑战赛,2015。
多年来,该委员会得到了广泛参与,取得了许多重要进展,出版了大量学术出版物。从如此多的工作中挑选里程碑本身就是一个挑战。
尽管如此,仍有一些技术,通常以其母大学、研究小组或公司的名字命名,脱颖而出,成为深度学习和计算机视觉交叉领域的主要内容。描述方法的论文已经成为必读,模型使用的技术已经成为在实践中使用一般技术的启发。
在本节中,我们将重点介绍作为 ILSVRC 的一部分而提出的一些里程碑式的技术,以及介绍这些技术的论文。重点将是图像分类任务。
ILSVRC-2012 年欧洲足球锦标赛
AlexNet(监理)
多伦多大学的 Alex Krizhevsky 等人在 2012 年发表的题为“使用深度卷积神经网络进行图像网络分类”的论文中开发了一种卷积神经网络,该网络在 ILSVRC-2010 和 ILSVRC-2012 图像分类任务中取得了最佳结果。
这些结果激发了人们对计算机视觉深度学习的兴趣。
……我们在 ILSVRC-2010 和 ILSVRC-2012 竞赛中使用的 ImageNet 子集上训练了迄今为止最大的卷积神经网络之一,并在这些数据集上取得了迄今为止报告的最佳结果。
——深度卷积神经网络的 ImageNet 分类,2012。
ILSVRC-2013 年欧洲足球锦标赛
ZFNet(克拉辉)
马修·泽勒和罗布·弗格斯在他们 2013 年的论文《可视化和理解卷积网络》中提出了一种变体 AlexNet,通常被称为 ZFNet,该变体赢得了 ILSVRC-2013 图像分类任务。
ILSVRC-2014 年欧洲足球锦标赛
《Inception》
来自谷歌的 Christian Szegedy 等人利用其利用初始模块和架构的谷歌网络模型在对象检测方面取得了最佳结果。这种方法在他们 2014 年发表的题为“用盘旋走得更深”的论文中有所描述
我们提出了一种深度卷积神经网络架构,代号为 Inception,负责在 ImageNet 大规模视觉识别挑战赛 2014 (ILSVRC14)中设置分类和检测的新技术。
——用回旋更深入,2014。
VGG
牛津视觉几何集团(VGG)的卡伦·西蒙扬和安德鲁·齐塞曼用他们的 VGG 模型在图像分类和定位方面取得了最好的结果。他们的方法在他们 2015 年发表的题为“用于大规模图像识别的非常深的卷积网络”的论文中有所描述
……我们提出了明显更精确的 ConvNet 架构,不仅在 ILSVRC 分类和定位任务上实现了最先进的准确率,而且还适用于其他图像识别数据集,即使作为相对简单的管道的一部分,它们也能实现出色的表现
——用于大规模图像识别的超深度卷积网络,2015。
ILSVRC-2015 年欧洲足球锦标赛
ResNet (MSRA)
来自微软研究院的何等人在他们 2015 年发表的论文《用于图像识别的深度残差学习》中描述了他们的残差网络或 ResNet,在对象检测和带有定位任务的对象检测方面取得了顶级成果
这些剩余网的集合在 ImageNet 测试集上实现了 3.57%的误差。这一结果获得了 ILSVRC 2015 分类任务的第一名。
——图像识别的深度残差学习,2015。
我错过了一个重要的里程碑吗? 在下面的评论里告诉我。
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
报纸
- ImageNet:大规模分层图像数据库,2009。
- ImageNet 大规模视觉识别挑战赛,2015 年。
- 深度卷积神经网络的 ImageNet 分类,2012。
- 可视化和理解卷积网络,2013。
- 用回旋更深入,2014。
- 用于大规模图像识别的超深度卷积网络,2015。
- 图像识别的深度残差学习,2015。
文章
摘要
在这篇文章中,您发现了 ImageNet 数据集、ILSVRC 竞赛以及由竞赛产生的图像分类中的关键里程碑。
具体来说,您了解到:
- ImageNet 数据集是一个非常大的人类注释照片集合,由学者设计用于开发计算机视觉算法。
- ImageNet 大规模视觉识别挑战赛(ILSVRC)是一项年度竞赛,使用 ImageNet 数据集的子集,旨在促进最先进算法的开发和基准测试。
- ILSVRC 任务已经导致了计算机视觉和深度学习交叉领域的里程碑模型架构和技术。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。
深度学习对象识别入门
最后更新于 2021 年 1 月 27 日
对于初学者来说,区分不同的相关计算机视觉任务可能很有挑战性。
例如,图像分类是直截了当的,但对象定位和对象检测之间的差异可能会令人困惑,尤其是当这三项任务都可能等同于对象识别时。
图像分类涉及为图像分配类别标签,而对象定位涉及在图像中的一个或多个对象周围绘制边界框。对象检测更具挑战性,它将这两项任务结合起来,在图像中的每个感兴趣的对象周围绘制一个边界框,并为它们分配一个类别标签。所有这些问题统称为目标识别。
在这篇文章中,你会发现一个关于对象识别问题的温和介绍,以及为解决这个问题而设计的最先进的深度学习模型。
看完这篇文章,你会知道:
- 对象识别是指在数码照片中识别对象的相关任务的集合。
- 基于区域的卷积神经网络是一系列解决目标定位和识别任务的技术,是为模型表现而设计的。
- 你只看一次,或 YOLO,是为速度和实时使用而设计的第二类对象识别技术。
用我的新书计算机视觉深度学习启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
深度学习对象识别入门 图片由巴特·艾弗森提供,版权所有。
概观
本教程分为三个部分;它们是:
- 什么是对象识别?
- 美国有线电视新闻网模范家庭
- YOLO 模范家庭
什么是对象识别?
对象识别是一个通用术语,用来描述一系列相关的计算机视觉任务,包括识别数码照片中的对象。
图像分类涉及预测图像中一个对象的类别。对象定位指的是识别图像中一个或多个对象的位置,并围绕它们的范围绘制丰富的方框。对象检测结合这两项任务,对图像中的一个或多个目标进行定位和分类。
当用户或从业者提到“对象识别”时,他们通常指的是“对象检测”。
……我们将广泛使用对象识别这一术语来涵盖图像分类(需要算法来确定图像中存在哪些对象类别的任务)和对象检测(需要算法来定位图像中存在的所有对象的任务
——ImageNet 大规模视觉识别挑战赛,2015 年。
因此,我们可以区分这三种计算机视觉任务:
- 图像分类:预测图像中对象的类型或类别。
- 输入:单个对象的图像,如照片。
- 输出:一个类标签(例如一个或多个映射到类标签的整数)。
- 对象定位:定位图像中对象的存在,并用边框指示其位置。
- 输入:带有一个或多个对象的图像,如照片。
- 输出:一个或多个边界框(例如,由点、宽度和高度定义)。
- 对象检测:用边界框定位对象的存在以及图像中被定位对象的类型或类别。
- 输入:带有一个或多个对象的图像,如照片。
- 输出:一个或多个边界框(例如,由点、宽度和高度定义),以及每个边界框的类别标签。
计算机视觉任务细分的另一个扩展是对象分割,也称为“对象实例分割”或“语义分割”,其中通过突出显示对象的特定像素而不是粗略的边界框来指示识别对象的实例。
从这个细分中,我们可以看到对象识别指的是一套具有挑战性的计算机视觉任务。
目标识别计算机视觉任务综述
最近在图像识别问题上的大多数创新都是作为参与 ILSVRC 任务的一部分而出现的。
这是一年一度的学术竞赛,对这三种问题类型中的每一种都有单独的挑战,目的是在每一个层次上培养独立和单独的改进,以便更广泛地利用。例如,见以下摘自 2015 ILSVRC 综述论文的三种对应任务类型列表:
- 图像分类:算法生成图像中存在的对象类别列表。
- 单对象定位:算法生成图像中存在的对象类别列表,以及指示每个对象类别的一个实例的位置和比例的轴对齐边界框。
- 对象检测:算法生成图像中存在的对象类别列表,以及指示每个对象类别的每个实例的位置和比例的轴对齐边界框。
我们可以看到“单目标定位”是更广泛定义的“目标定位”的更简单版本,“将定位任务约束到图像内的一种类型的目标,我们可以假设这是更容易的任务。
下面是一个比较单目标定位和对象检测的例子,摘自 ILSVRC 论文。注意在每种情况下地面真实期望的差异。
单目标定位和对象检测的比较。摘自:ImageNet 大规模视觉识别挑战。
使用预测类别标签上的平均分类误差来评估图像分类模型的表现。使用预期类的预期边界框和预测边界框之间的距离来评估单对象定位模型的表现。而使用图像中已知对象的每个最佳匹配边界框的准确率和召回率来评估对象识别模型的表现。
现在我们已经熟悉了对象定位和检测的问题,让我们来看看最近一些表现最好的深度学习模型。
美国有线电视新闻网模范家庭
R-CNN 方法家族指的是 R-CNN,它可能代表“具有 CNN 特征的区域”或“基于区域的卷积神经网络”,由罗斯·吉尔希克等人开发。
这包括为目标定位和目标识别而设计和演示的技术。
让我们依次仔细看看这些技术的亮点。
美国有线电视新闻网
加州大学伯克利分校的罗斯·吉尔西克等人在 2014 年发表的题为“丰富的特征层次结构,用于精确的对象检测和语义分割”的论文中描述了 R-CNN
这可能是卷积神经网络在目标定位、检测和分割问题上的第一次大规模成功应用。该方法在基准数据集上进行了演示,在 VOC-2012 数据集和 200 级 ILSVRC-2013 对象检测数据集上取得了当时最先进的结果。
他们提出的有线电视新闻网模型由三个模块组成;它们是:
- 模块 1:地区提案。生成和提取类别无关的区域建议,例如候选边界框。
- 模块 2:特征提取器。从每个候选区域提取特征,例如使用深度卷积神经网络。
- 模块 3:分类器。将特征分类为已知类别之一,例如线性 SVM 分类器模型。
该模型的架构总结如下图,取自该论文。
美国有线电视新闻网模型体系结构概述从丰富的特征层次中提取,用于精确的对象检测和语义分割。
使用计算机视觉技术来提出图像中潜在对象的候选区域或边界框,称为“选择性搜索”,尽管设计的灵活性允许使用其他区域建议算法。
该模型使用的特征提取器是赢得 ILSVRC-2012 图像分类竞赛的 AlexNet deep CNN 。美国有线电视新闻网的输出是一个 4,096 元素的向量,它描述了输入到线性 SVM 分类器的图像内容,具体来说,为每个已知类别训练一个 SVM。
将神经网络应用于目标定位和识别是一种相对简单和直接的方法。这种方法的缺点是速度慢,需要对区域建议算法生成的每个候选区域进行基于 CNN 的特征提取。这是一个问题,因为本文描述的模型在测试时对每个图像大约 2000 个建议区域进行操作。
论文中描述的 Python ( Caffe )和 MatLab 源代码可在 R-CNN GitHub 资源库中获得。
美国有线电视新闻网
鉴于 R-CNN 的巨大成功,时任微软研究院的罗斯·吉尔西克(Ross Girshick)在 2015 年发表的一篇题为《快速 R-CNN 》的论文中,提出了一个扩展,以解决 R-CNN 的速度问题
本文首先回顾了美国有线电视新闻网的局限性,总结如下:
- 训练是多阶段流水线。涉及三个独立模型的准备和操作。
- 训练在空间和时间上都很昂贵。在每个图像上训练一个深度 CNN 关于如此多的区域提议是非常慢的。
- 对象检测缓慢。利用美国有线电视新闻网对如此多的地区提案进行预测是非常缓慢的。
在 2014 年的论文“深度卷积网络中用于视觉识别的空间金字塔池化”中,提出了一项先前的工作来加速称为空间金字塔池化网络(SPPnets)的技术这确实加快了特征提取的速度,但本质上使用了一种前向传递缓存算法。
快速 R-CNN 是作为单一模型而不是直接学习和输出区域和分类的管道提出的。
该模型的架构将一组区域建议作为输入拍摄照片,这些建议通过深度卷积神经网络传递。预先训练的美国有线电视新闻网,如 VGG-16,用于特征提取。深度有线电视新闻网的末端是一个称为兴趣区域池层(Pooling Layer)的自定义层,它提取特定于给定输入候选区域的特征。
有线电视新闻网的输出由一个完全连接的层解释,然后模型分成两个输出,一个用于通过 softmax 层的类别预测,另一个具有边界框的线性输出。然后对给定图像中的每个感兴趣区域重复该过程多次。
该模型的架构总结如下图,取自该论文。
快速有线电视新闻网模型架构概述。 摘自:快 R-CNN。
该模型的训练和预测速度要快得多,但仍然需要与每个输入图像一起提出一组候选区域。
论文中描述的用于 Fast R-CNN 的 Python 和 C++ (Caffe)源代码可以在 GitHub 资源库中获得。
更快
微软研究院的任等人在 2016 年发表的题为《更快的 R-CNN:利用区域提议网络实现实时对象检测》的论文中,针对训练和检测的速度进一步改进了模型架构
该架构是在 ILSVRC-2015 和 MS COCO-2015 目标识别和检测竞赛任务中取得第一名表现的基础。
该架构旨在作为培训过程的一部分提出和完善地区提案,称为地区提案网络(RPN)。然后,这些区域在单个模型设计中与快速反应-有线电视新闻网模型一起使用。这些改进既减少了区域提议的数量,又将模型的测试时间操作加速到接近实时,具有当时最先进的表现。
……我们的检测系统在 GPU 上的帧速率为 5fps(包括所有步骤),同时在 PASCAL VOC 2007、2012 和 MS COCO 数据集上实现了最先进的对象检测准确率,每幅图像只有 300 个建议。在 ILSVRC 和 COCO 2015 的比赛中,fast R-CNN 和 RPN 是几个赛道第一名获奖作品的基础
——更快的 R-CNN:借助区域建议网络实现实时对象检测,2016 年。
尽管它是一个单一的统一模型,但该体系结构由两个模块组成:
- 模块 1:区域提案网络。卷积神经网络,用于提出区域和区域中要考虑的对象类型。
- 模块 2:快速 R-CNN 。卷积神经网络,用于从建议区域提取特征,并输出边界框和类别标签。
这两个模块都运行在深度有线电视新闻网的相同输出上。区域建议网络充当快速反应-美国有线电视新闻网网络的关注机制,通知第二个网络在哪里寻找或关注。
该模型的架构总结如下图,取自该论文。
更快的有线电视新闻网模型架构概述。摘自:更快的 R-CNN:使用区域提议网络实现实时对象检测。
RPN 的工作原理是获取预先训练好的深度 CNN(如 VGG-16)的输出,并在特征地图上传递一个小网络,输出多个区域建议和每个区域的类别预测。区域建议是边界框,基于所谓的锚框或预定义的形状,旨在加速和改进区域的建议。类别预测是二进制的,指示对象的存在与否,即所提议区域的所谓“T0”对象。
使用交替训练的过程,其中两个子网络被同时训练,尽管是交错的。这使得特征检测器深度 CNN 中的参数可以同时为这两项任务进行定制或微调。
在撰写本文时,这种 fast R-CNN 架构是该系列模型的巅峰之作,并继续在对象识别任务上取得接近最先进的成果。进一步的扩展增加了对图像分割的支持,如论文 2017 论文“ Mask R-CNN ”中所述
论文中描述的用于 Fast R-CNN 的 Python 和 C++ (Caffe)源代码可以在 GitHub 资源库中获得。
YOLO 模范家庭
另一个流行的对象识别模型家族被统称为 YOLO 或“你只看一次”,由约瑟夫·雷德蒙等人开发。
美国有线电视新闻网的模型可能通常更准确,但 YOLO 系列的模型更快,比美国有线电视新闻网快得多,实现了实时对象检测。
YOLO
约瑟夫·雷德蒙(Joseph Redmon)等人在 2015 年发表的论文《你只看一次: 》中首次描述了 YOLO 模型,该论文名为《统一实时对象检测》请注意,美国有线电视新闻网的开发者罗斯·吉尔西克也是这部作品的作者和贡献者,当时在脸书人工智能研究。
这种方法包括一个单独的神经网络,它被训练成首尾相连,以一张照片作为输入,并直接为每个边界框预测边界框和类标签。该技术提供了较低的预测准确率(例如,更多的定位误差),尽管对于速度优化版本的模型,该技术以每秒 45 帧和高达每秒 155 帧的速度运行。
我们的统一架构速度极快。我们的基本 YOLO 模型以每秒 45 帧的速度实时处理图像。一个较小版本的网络,快速 YOLO,每秒处理惊人的 155 帧…
——你只看一次:统一实时对象检测,2015。
该模型的工作原理是首先将输入图像分割成单元网格,如果边界框的中心位于单元内,则每个单元负责预测边界框。每个网格单元预测一个包含 x、y 坐标、宽度、高度和置信度的边界框。类别预测也基于每个单元格。
例如,图像可以被分成 7×7 的网格,并且网格中的每个单元可以预测 2 个边界框,从而产生 94 个建议的边界框预测。类别概率图和具有置信度的边界框然后被组合成边界框和类别标签的最终集合。下图总结了模型的两个输出。
YOLO 模型所做预测的摘要。摘自:你只看一次:统一、实时的对象检测
YOLOv2 (YOLO9000)和 YOLOv3
约瑟夫·雷德蒙(Joseph Redmon)和阿里·法尔哈迪(Ali)在 2016 年发表的论文《YOLO9000:更好、更快、更强》中对该模型进行了更新,以进一步提高模型表现
尽管该模型的这种变体被称为 YOLO v2,但是描述了该模型的一个实例,该实例在两个对象识别数据集上并行训练,能够预测 9000 个对象类别,因此被命名为“ YOLO9000
对模型进行了大量的训练和架构更改,例如使用批处理规范化和高分辨率输入图像。
像 fast R-CNN 一样,YOLOv2 模型利用了锚框,这是预定义的边界框,具有在训练过程中定制的有用形状和大小。使用训练数据集上的 k-均值分析对图像的边界框的选择进行预处理。
重要的是,边界框的预测表示被改变,以允许小的改变对预测具有较小的影响,从而产生更稳定的模型。不是直接预测位置和大小,而是预测偏移,用于相对于网格单元移动和整形预定义的锚盒,并由逻辑函数衰减。
预测边界框位置和形状时选择的表示示例摘自:YOLO9000:更好、更快、更强
约瑟夫·雷德蒙和阿里·法尔哈迪在他们 2018 年发表的题为“YOLOv3:增量改进”的论文中提出了对该模型的进一步改进这些改进相当小,包括更深的特征检测器网络和微小的代表性变化。
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
报纸
- ImageNet 大规模视觉识别挑战赛,2015 年。
美国有线电视新闻网家庭报纸
- 丰富的特征层次,用于精确的对象检测和语义分割,2013。
- 用于视觉识别的深度卷积网络中的空间金字塔池,2014。
- 快 R-CNN ,2015 年。
- 更快的 R-CNN:使用区域提议网络实现实时对象检测,2016 年。
- 口罩 R-CNN ,2017 年。
YOLO 家庭文件
- 你只看一次:统一实时对象检测,2015。
- YOLO9000:更好更快更强,2016。
- YOLOv3:一个增量改进,2018。
代码项目
- R-CNN:具有卷积神经网络特征的区域,GitHub 。
- 快速 R-CNN,GitHub 。
- 更快的 R-CNN Python 代码,GitHub 。
- yolo,GitHub 。
资源
文章
- 图像分割中的 CNN 简史:从 R-CNN 到 Mask R-CNN ,2017。
- 假人的对象检测第三部分:R-CNN 家族,2017。
- 对象检测第四部分:快速检测模型,2018。
摘要
在这篇文章中,你发现了对对象识别问题的温和介绍,以及为解决这个问题而设计的最先进的深度学习模型。
具体来说,您了解到:
- 对象识别是指在数码照片中识别对象的相关任务的集合。
- 基于区域的卷积神经网络是一系列解决目标定位和识别任务的技术,是为模型表现而设计的。
- 你只看一次,或 YOLO,是为速度和实时使用而设计的第二类对象识别技术。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。
用于人脸识别的单样本学习
最后更新于 2020 年 6 月 11 日
单样本学习是一种分类任务,其中一个或几个示例用于对未来的许多新示例进行分类。
这是在人脸识别领域中看到的任务的特征,例如人脸识别和人脸验证,在这些任务中,人们必须在给定一张或几张模板照片的情况下,根据不同的面部表情、照明条件、配饰和发型进行正确分类。
现代人脸识别系统通过学习一种丰富的低维特征表示(称为人脸嵌入)来解决通过人脸识别进行单样本学习的问题,这种低维特征表示可以很容易地针对人脸进行计算,并在验证和识别任务中进行比较。
历史上,嵌入是使用暹罗网络为单样本学习问题学习的。具有比较损失函数的暹罗网络的训练导致了更好的表现,后来导致了谷歌在 FaceNet 系统中使用的三重损失函数,该函数在基准人脸识别任务上取得了当时最先进的结果。
在这篇文章中,你将发现人脸识别中单样本学习的挑战,以及如何使用比较和三重损失函数来学习高质量的人脸嵌入。
看完这篇文章,你会知道:
- 单样本学习是分类任务,给定每个类的一个(或几个)例子,需要进行许多预测,人脸识别就是单样本学习的例子。
- 暹罗网络是一种解决单样本学习的方法,其中将已知示例和候选示例的学习特征向量进行比较。
- 对比损失和后期三重损失函数可以用来学习高质量的人脸嵌入向量,为现代人脸识别系统提供基础。
用我的新书计算机视觉深度学习启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
使用暹罗网络、对比和三连音丢失进行人脸识别的单样本学习 图片由希斯·卡詹丁提供,保留部分权利。
概观
本教程分为四个部分;它们是:
- 单样本学习和人脸识别
- 暹罗单样本学习网络
- 降维的对比损失
- 学习人脸嵌入的三重损失
单样本学习和人脸识别
典型地,分类包括拟合给定每个类的许多例子的模型,然后使用拟合模型对每个类的许多例子进行预测。
例如,我们可能有来自三个不同物种的成千上万的植物测量。一个模型可以适用于这些例子,从给定物种的测量值的共性中进行归纳,并对比不同物种测量值的差异。结果,希望,是一个稳健的模型,给定一套新的测量在未来,可以准确地预测植物物种。
单样本学习是一种分类任务,其中每个类给出一个例子(或非常少的例子),用于准备一个模型,该模型反过来必须对未来许多未知的例子进行预测。
在单样本学习的情况下,一个对象类的单个样本被呈现给算法。
——学习识别视觉对象类中的知识转移,2006。
对于人类来说,这是一个相对容易的问题。例如,一个人可能会看到一辆法拉利跑车,在未来,能够在新的情况下,在路上,在电影中,在书籍中,以及在不同的灯光和颜色下识别法拉利。
人类在很少监督的情况下学习新概念——例如,一个孩子可以从一本书的一张图片中概括出“长颈鹿”的概念——然而,我们最好的深度学习系统需要成百上千个例子。
——单样本学习的匹配网络,2017。
单样本学习与零样本学习既有联系又有区别。
这应该与零触发学习相区别,在零触发学习中,模型不能查看目标类的任何示例。
——用于单次拍摄图像识别的暹罗神经网络,2015。
人脸识别任务提供了单样本学习的例子。
具体而言,在面部识别的情况下,模型或系统可能只有给定人的面部的一个或几个示例,并且必须从表情、发型、照明、配饰等发生变化的新照片中正确识别该人。
在人脸验证的情况下,一个模型或系统可能只有一个记录在案的人脸示例,并且必须正确验证该人的新照片,可能每天都要验证一次。
因此,人脸识别是单样本学习的一个常见例子。
暹罗单样本学习网络
暹罗网络是一种因其用于单样本学习而得到普及的网络。
暹罗网络是具有两个并行神经网络的体系结构,每个神经网络采用不同的输入,并且其输出被组合以提供一些预测。
这是一个为验证任务而设计的网络,由 Jane Bromley 等人在 1993 年发表的题为“使用暹罗时间延迟神经网络进行签名验证”的论文中首次提出
该算法基于一种新型的人工神经网络,称为“暹罗”神经网络。该网络由两个输出端相连的相同子网组成。
——使用“暹罗”时延神经网络的签名验证,1993 年。
使用两个相同的网络,一个获取该人的已知签名,另一个获取候选签名。两个网络的输出被组合并评分,以指示候选签名是真实的还是伪造的。
验证包括将提取的特征向量与签名者存储的特征向量进行比较。比所选阈值更接近该存储表示的签名被接受,所有其他签名作为伪造被拒绝。
——使用“暹罗”时延神经网络的签名验证,1993 年。
用于签名验证的暹罗网络示例。 摘自:使用“暹罗”时延神经网络的签名验证。
暹罗网络是最近才使用的,在 Gregory Koch 等人在 2015 年发表的题为“用于单次图像识别的暹罗神经网络的论文中,深度卷积神经网络被用于并行图像输入。”
深度 CNN 首先被训练来区分每一类的例子。其思想是让模型学习能够有效地从输入图像中提取抽象特征的特征向量。
用于训练暹罗网络的图像验证示例。 取自:用于单镜头图像识别的暹罗神经网络。
然后,模型被重新用于验证,以预测新的例子是否与每个类的模板相匹配。
具体而言,每个网络产生输入图像的特征向量,然后使用 L1 距离和 sigmoid 激活对其进行比较。将该模型应用于计算机视觉中手写字符数据集的基准测试。
用于测试暹罗网络的一次性图像分类示例。 取自:用于单镜头图像识别的暹罗神经网络。
暹罗网络的有趣之处在于它通过学习特征表示(特征向量)来解决单样本学习的方法,然后将这些特征表示与验证任务进行比较。
使用暹罗网络开发的人脸识别系统的一个例子是 DeepFace,由 Yaniv Taigman 等人在 2014 年题为“ DeepFace:缩小人脸验证中与人类水平表现的差距的论文中描述
他们的方法包括首先训练用于人脸识别的模型,然后移除模型的分类器层,并使用激活作为特征向量,然后对两个不同的人脸进行计算和比较,用于人脸验证。
我们还测试了一种端到端的度量学习方法,称为暹罗网络:一旦被学习,人脸识别网络(没有顶层)将被复制两次(每个输入图像一次),这些特征用于直接预测两个输入图像是否属于同一个人。
——deep Face:缩小与人脸验证中人层面表现的差距,2014。
降维的对比损失
学习复杂输入的向量表示,如图像,是降维的一个例子。
降维旨在将高维数据转换为低维表示,从而将相似的输入对象映射到流形上的邻近点。
——通过学习不变映射进行降维,2006。
有效降维的目标是学习一种新的低维表示,它保留了输入的结构,使得输出向量之间的距离有意义地捕捉输入中的差异。然而,向量必须捕捉输入中的不变特征。
问题是在给定输入空间中样本之间的邻域关系的情况下,找到一个将高维输入模式映射到低维输出的函数。
——通过学习不变映射进行降维,2006。
降维是暹罗网络用来解决单样本学习的方法。
在他们 2006 年题为“通过学习不变映射”的论文降维中, Raia Hadsell 等人探索使用暹罗网络和卷积神经网络对图像数据进行降维,并提出通过对比损失来训练模型。
不同于可能评估训练数据集中所有输入示例的模型表现的其他损失函数,对比损失是在输入对之间计算的,例如在提供给暹罗网络的两个输入之间。
成对的例子被提供给网络,并且损失函数基于样本的类别是相同还是不同来不同地惩罚模型。具体而言,如果类别相同,则损失函数促使模型输出更相似的特征向量,而如果类别不同,则损失函数促使模型输出不太相似的特征向量。
对比损失需要面部图像对,然后将正对拉在一起,将负对推开。[……]然而,对比损失的主要问题是保证金参数往往难以选择。
——深度人脸识别:一项调查,2018 年。
损失函数要求选择一个裕度,用于确定不同对的示例受到惩罚的限度。选择这个余量需要仔细考虑,这是使用损失函数的一个缺点。
相似(红色)和不相似(蓝色)对的对比损耗计算图。 取自:通过学习不变映射进行降维
对比损失可以用来训练一个人脸识别系统,专门用于人脸验证的任务。此外,这可以通过顺序提供成对的示例并在计算损失和更新模型之前保存预测的特征向量来实现,而不需要在暹罗网络架构中使用并行模型。
一个例子是 DeepID2 和后续系统(DeepID2+和 DeepID3),它们使用深度卷积神经网络,但不是暹罗网络架构,并在基准人脸识别数据集上取得了当时最先进的结果。
验证信号直接调节深度 ID2,可以有效减少个体内部的差异。常用的约束包括 L1/L2 范数和余弦相似性。我们在 L2 范数的基础上采用了以下损失函数,它最初是由 Hadsell 等人提出的降维方法。
——联合识别验证深度学习人脸表示,2014。
学习人脸嵌入的三重损失
比较损失的概念可以从两个例子进一步扩展到三个,称为三重损失。
来自谷歌的 Florian Schroff 等人在他们 2015 年的论文《T2 人脸网:人脸识别和聚类的统一嵌入》中介绍了三重损失
三重损失不是基于两个例子来计算损失,而是涉及一个锚定例子和一个正的或匹配的例子(同一类)以及一个负的或不匹配的例子(不同类)。
损失函数惩罚模型,使得匹配示例之间的距离减小,而非匹配示例之间的距离增大。
它需要脸三元组,然后它最小化一个锚和相同身份的正样本之间的距离,最大化锚和不同身份的负样本之间的距离。
——深度人脸识别:一项调查,2018 年。
应用三重态损失前后对锚定、正和负的影响示例。 取自:Facenet:一种用于人脸识别和聚类的统一嵌入。
结果是一个特征向量,被称为“人脸嵌入”,其具有有意义的欧几里德关系,使得相似的人脸产生具有小距离的嵌入(例如,可以被聚类),并且同一人脸的不同示例产生非常小的嵌入,并且允许与其他身份进行验证和区分。
这种方法被用作 FaceNet 系统的基础,该系统在基准人脸识别数据集上取得了当时最先进的结果。
在本文中,我们介绍了一个名为 FaceNet 的系统,该系统直接学习从人脸图像到紧致欧氏空间的映射,其中距离直接对应于人脸相似性的度量。
——face net:人脸识别和聚类的统一嵌入,2015。
用来训练模型的三胞胎是精心挑选的。
容易的三元组,导致很小的损失,并且在更新模型时无效。取而代之的是,寻找鼓励改变模型和预测人脸嵌入的硬三元组。
选择使用哪一个三元组对取得好的表现非常重要,受课程学习的启发,我们提出了一种新颖的在线负样本挖掘策略,确保随着网络训练,三元组的难度不断增加。
——face net:人脸识别和聚类的统一嵌入,2015。
三元组以在线方式生成,并且发现所谓的硬正(匹配)和硬负(不匹配)情况,并用于估计该批的损失。
重要的是选择硬三元组,它们是活跃的,因此可以有助于改进模型。
——face net:人脸识别和聚类的统一嵌入,2015。
直接训练人脸嵌入的方法,如通过三重损失,并使用嵌入作为人脸识别和人脸验证模型的基础,如 FaceNet,是现代和最先进的人脸识别方法的基础。
……对于从零开始训练的模型以及预训练的模型,使用三元组损失的变体来执行端到端深度度量学习比大多数其他已发布的方法要优越得多。
——为人身重新认定三重损失辩护,2017 年。
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
报纸
- 学习识别视觉对象类中的知识转移,2006。
- 单样本学习的匹配网络,2017。
- 用于单次拍摄图像识别的暹罗神经网络,2015。
- 使用“暹罗”时延神经网络的签名验证,1993 年。
- DeepFace:缩小与人脸验证中人层面表现的差距,2014。
- 通过学习不变映射进行降维,2006。
- 深度人脸识别:一项调查,2018。
- 联合识别-验证深度学习人脸表征,2014。
- Facenet:人脸识别和聚类的统一嵌入,2015。
- 为人身重新认定三重损失辩护,2017 年。
文章
摘要
在这篇文章中,你发现了人脸识别中单样本学习的挑战,以及如何使用比较和三重损失函数来学习高质量的人脸嵌入。
具体来说,您了解到:
- 单样本学习是分类任务,给定每个类的一个(或几个)例子,需要进行许多预测,人脸识别就是单样本学习的例子。
- 暹罗网络是一种解决单样本学习的方法,其中将已知示例和候选示例的学习特征向量进行比较。
- 对比损失和后期三重损失函数可以用来学习高质量的人脸嵌入向量,为现代人脸识别系统提供基础。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。
卷积神经网络填充和步长的温和介绍
最后更新于 2019 年 8 月 16 日
卷积神经网络中的卷积层系统地对输入应用滤波器,并创建输出特征图。
虽然卷积层非常简单,但它能够实现复杂而令人印象深刻的结果。然而,对于过滤器的形状如何影响输出特征图的形状以及相关的配置超参数(例如填充和步幅)应该如何配置,开发直觉可能是一项挑战。
在本教程中,您将发现卷积神经网络中滤波器大小、填充需求和步长的直觉。
完成本教程后,您将知道:
- 过滤器大小或内核大小如何影响输出要素图的形状。
- 过滤器大小如何在要素地图中创建边框效果,以及如何通过填充来克服它。
- 如何使用输入图像上过滤器的步幅对输出要素图的大小进行下采样。
用我的新书计算机视觉深度学习启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
卷积神经网络填充和步幅的温和介绍 图片由红星提供,版权所有。
教程概述
本教程分为五个部分;它们是:
- 卷积层
- 边界效应问题
- 过滤器大小的影响(内核大小)
- 使用填充修复边框效果问题
- 带步幅的下采样输入
卷积层
在卷积神经网络中,卷积层负责对输入系统应用一个或多个滤波器。
滤波器与输入图像的相乘产生单个输出。输入通常是三维图像(例如,行、列和通道),反过来,过滤器也是三维的,具有与输入图像相同数量的通道和更少的行和列。这样,过滤器被重复应用于输入图像的每个部分,产生激活的二维输出图,称为特征图。
Keras 提供了一个卷积层的实现,称为 Conv2D。
它要求您根据行(高度)、列(宽度)和通道(深度)或*【行、列、通道】*来指定输入图像的预期形状。
过滤器包含在层的训练过程中必须学习的权重。过滤器权重表示过滤器将检测到的结构或特征,激活强度表示检测到特征的程度。
该层要求指定过滤器的数量和形状。
我们可以用一个小例子来证明这一点。在本例中,我们定义了一个输入图像或样本,它有一个通道,是一个 8 像素乘 8 像素的正方形,所有值都为 0,中间有一条 2 像素宽的垂直线。
# define input data
data = [[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0]]
data = asarray(data)
data = data.reshape(1, 8, 8, 1)
接下来,我们可以定义一个模型,该模型期望输入样本具有形状(8,8,1),并且具有单个隐藏卷积层,该卷积层具有三个像素乘三个像素的形状的单个滤波器。
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), input_shape=(8, 8, 1)))
# summarize model
model.summary()
作为模型初始化的一部分,使用随机权重初始化过滤器。我们将覆盖随机权重并硬编码我们自己的 3×3 过滤器,它将检测垂直线。
也就是说,当检测到垂直线时,过滤器将被强激活,当检测不到垂直线时,过滤器将被弱激活。我们预计,通过在输入图像上应用此过滤器,输出特征图将显示检测到垂直线。
# define a vertical line detector
detector = [[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]]]
weights = [asarray(detector), asarray([0.0])]
# store the weights in the model
model.set_weights(weights)
接下来,我们可以通过调用模型上的 predict() 函数将过滤器应用于我们的输入图像。
# apply filter to input data
yhat = model.predict(data)
结果是一个四维输出,具有一个批次、给定数量的行和列以及一个过滤器,或*【批次、行、列、过滤器】*。
我们可以在单个特征图中打印激活,以确认检测到该行。
# enumerate rows
for r in range(yhat.shape[1]):
# print each column in the row
print([yhat[0,r,c,0] for c in range(yhat.shape[2])])
将所有这些结合在一起,下面列出了完整的示例。
# example of using a single convolutional layer
from numpy import asarray
from keras.models import Sequential
from keras.layers import Conv2D
# define input data
data = [[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0]]
data = asarray(data)
data = data.reshape(1, 8, 8, 1)
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), input_shape=(8, 8, 1)))
# summarize model
model.summary()
# define a vertical line detector
detector = [[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]]]
weights = [asarray(detector), asarray([0.0])]
# store the weights in the model
model.set_weights(weights)
# apply filter to input data
yhat = model.predict(data)
# enumerate rows
for r in range(yhat.shape[1]):
# print each column in the row
print([yhat[0,r,c,0] for c in range(yhat.shape[2])])
运行示例首先总结模型的结构。
值得注意的是,单个隐藏卷积层将采用 8×8 像素的输入图像,并将产生尺寸为 6×6 的特征图。我们将在下一节探讨为什么会出现这种情况。
我们还可以看到该层有 10 个参数,即滤波器的 9 个权重(3×3)和偏差的 1 个权重。
最后,打印特征图。通过查看 6×6 矩阵中的数字,我们可以看到手动指定的过滤器确实检测到了输入图像中间的垂直线。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 6, 6, 1) 10
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0
_________________________________________________________________
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
边界效应问题
在上一节中,我们定义了一个三像素高、三像素宽(行、列)的单个过滤器。
我们看到,对 8×8 输入图像应用 3×3 滤波器(在 Keras 中称为核大小)产生了大小为 6×6 的特征图。
也就是说,具有 64 个像素的输入图像被简化为具有 36 个像素的特征图。其他 28 像素去哪了?
滤波器被系统地应用于输入图像。它从图像的左上角开始,一次从左向右移动一个像素列,直到滤镜的边缘到达图像的边缘。
对于应用于 8×8 输入图像的 3×3 像素滤波器,我们可以看到它只能应用 6 次,导致输出特征图中的宽度为 6。
例如,让我们逐一查看输入图像(左)点积(")的六个补丁操作员)过滤器(右):
0, 0, 0 0, 1, 0
0, 0, 0 . 0, 1, 0 = 0
0, 0, 0 0, 1, 0
向右移动一个像素:
0, 0, 1 0, 1, 0
0, 0, 1 . 0, 1, 0 = 0
0, 0, 1 0, 1, 0
向右移动一个像素:
0, 1, 1 0, 1, 0
0, 1, 1 . 0, 1, 0 = 3
0, 1, 1 0, 1, 0
向右移动一个像素:
1, 1, 0 0, 1, 0
1, 1, 0 . 0, 1, 0 = 3
1, 1, 0 0, 1, 0
向右移动一个像素:
1, 0, 0 0, 1, 0
1, 0, 0 . 0, 1, 0 = 0
1, 0, 0 0, 1, 0
向右移动一个像素:
0, 0, 0 0, 1, 0
0, 0, 0 . 0, 1, 0 = 0
0, 0, 0 0, 1, 0
这给出了输出要素图的第一行和每一列:
0.0, 0.0, 3.0, 3.0, 0.0, 0.0
要素图输入大小的减少称为边界效果。它是由滤镜与图像边框的相互作用引起的。
这对于大图像和小滤镜来说通常不是问题,但对于小图像来说可能是问题。一旦堆叠了多个卷积层,这也会成为一个问题。
例如,下面是更新为具有两个堆叠卷积层的相同模型。
这意味着对 8×8 输入图像应用 3×3 滤波器,以产生如前一节所述的 6×6 特征图。然后将 3×3 滤波器应用于 6×6 特征图。
# example of stacked convolutional layers
from keras.models import Sequential
from keras.layers import Conv2D
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), input_shape=(8, 8, 1)))
model.add(Conv2D(1, (3,3)))
# summarize model
model.summary()
运行该示例总结了每一层的输出形状。
我们可以看到,将过滤器应用于第一层的要素图输出,反过来会产生更小的 4×4 要素图。
当我们开发具有几十或几百层的非常深的卷积神经网络模型时,这可能成为一个问题。我们的要素地图中的数据将会用完,无法继续操作。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 6, 6, 1) 10
_________________________________________________________________
conv2d_2 (Conv2D) (None, 4, 4, 1) 10
=================================================================
Total params: 20
Trainable params: 20
Non-trainable params: 0
_________________________________________________________________
过滤器大小的影响(内核大小)
不同大小的过滤器将检测输入图像中不同大小的特征,并进而产生不同大小的特征图。
对于较大的输入图像,通常使用 3×3 尺寸的滤波器,或许 5×5 甚至 7×7 尺寸的滤波器。
例如,下面是一个模型的例子,其中单个过滤器被更新为使用 5×5 像素的过滤器大小。
# example of a convolutional layer
from keras.models import Sequential
from keras.layers import Conv2D
# create model
model = Sequential()
model.add(Conv2D(1, (5,5), input_shape=(8, 8, 1)))
# summarize model
model.summary()
运行示例表明,5×5 过滤器只能应用于 8×8 输入图像 4 次,从而产生 4×4 的要素图输出。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 4, 4, 1) 26
=================================================================
Total params: 26
Trainable params: 26
Non-trainable params: 0
_________________________________________________________________
观察两种极端情况可能有助于进一步发展过滤器尺寸和输出特征图之间关系的直觉。
第一种是 1×1 像素大小的滤镜。
# example of a convolutional layer
from keras.models import Sequential
from keras.layers import Conv2D
# create model
model = Sequential()
model.add(Conv2D(1, (1,1), input_shape=(8, 8, 1)))
# summarize model
model.summary()
运行该示例表明,输出要素图与输入要素图具有相同的大小,特别是 8×8。这是因为滤波器只有一个权重(和一个偏差)。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 8, 8, 1) 2
=================================================================
Total params: 2
Trainable params: 2
Non-trainable params: 0
_________________________________________________________________
另一个极端是与输入相同大小的滤波器,在本例中为 8×8 像素。
# example of a convolutional layer
from keras.models import Sequential
from keras.layers import Conv2D
# create model
model = Sequential()
model.add(Conv2D(1, (8,8), input_shape=(8, 8, 1)))
# summarize model
model.summary()
运行该示例,我们可以看到,如您所料,输入图像中的每个像素都有一个权重(偏差为 64 + 1),输出是一个具有单个像素的特征图。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 1, 1, 1) 65
=================================================================
Total params: 65
Trainable params: 65
Non-trainable params: 0
_________________________________________________________________
现在,我们已经熟悉了过滤器大小对生成的要素图大小的影响,让我们看看如何才能避免丢失像素。
使用填充修复边框效果问题
默认情况下,滤镜从图像的左侧开始,滤镜的左侧位于图像的最左侧像素。然后,过滤器一次一列地跨过图像,直到过滤器的右侧位于图像的最右侧像素上。
对图像应用滤镜的另一种方法是确保图像中的每个像素都有机会位于滤镜的中心。
默认情况下,情况并非如此,因为输入边缘的像素只暴露在滤波器的边缘。通过在图像帧外启动过滤器,它为图像边界上的像素提供了更多与过滤器交互的机会,也为过滤器检测特征提供了更多机会,进而提供了与输入图像形状相同的输出特征图。
例如,在对 8×8 输入图像应用 3×3 滤波器的情况下,我们可以在图像外部周围添加一个像素的边框。这具有人工创建 10×10 输入图像的效果。当应用 3×3 滤波器时,会产生 8×8 的特征图。当应用过滤器时,添加的像素值可以具有对点积运算没有影响的零值。
x, x, x 0, 1, 0
x, 0, 0 . 0, 1, 0 = 0
x, 0, 0 0, 1, 0
向图像边缘添加像素称为填充。
在 Keras 中,这是通过 Conv2D 层上的“填充”参数指定的,该参数的默认值为“有效”(无填充)。这意味着过滤器仅适用于输入的有效方式。
“相同的“填充”值计算输入图像(或特征图)所需的填充,并将其相加,以确保输出与输入具有相同的形状。
在我们的工作示例中,下面的示例向卷积层添加了填充。
# example a convolutional layer with padding
from keras.models import Sequential
from keras.layers import Conv2D
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), padding='same', input_shape=(8, 8, 1)))
# summarize model
model.summary()
运行该示例演示了输出要素图的形状与输入图像相同:填充具有所需的效果。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 8, 8, 1) 10
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0
_________________________________________________________________
填充的增加允许以这样一种方式开发非常深的模型,使得特征地图不会缩小到零。
下面的例子用三个堆叠的卷积层演示了这一点。
# example a deep cnn with padding
from keras.models import Sequential
from keras.layers import Conv2D
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), padding='same', input_shape=(8, 8, 1)))
model.add(Conv2D(1, (3,3), padding='same'))
model.add(Conv2D(1, (3,3), padding='same'))
# summarize model
model.summary()
运行该示例,我们可以看到,通过添加填充,输出要素图的形状保持固定在 8×8 甚至三层深。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 8, 8, 1) 10
_________________________________________________________________
conv2d_2 (Conv2D) (None, 8, 8, 1) 10
_________________________________________________________________
conv2d_3 (Conv2D) (None, 8, 8, 1) 10
=================================================================
Total params: 30
Trainable params: 30
Non-trainable params: 0
_________________________________________________________________
带步幅的下采样输入
滤镜在图像上从左到右、从上到下移动,水平移动时改变一个像素的列,垂直移动时改变一个像素的行。
滤波器对输入图像的应用之间的移动量被称为步幅,并且在高度和宽度维度上几乎总是对称的。
二维中的默认步幅是(1,1)表示高度和宽度移动,在需要时执行。这种默认在大多数情况下运行良好。
步幅可以改变,这对于如何将过滤器应用于图像以及由此产生的特征图的大小都有影响。
例如,步幅可以更改为(2,2)。这具有这样的效果,即在创建要素地图时,过滤器的每次水平移动向右移动两个像素,过滤器的每次垂直移动向下移动两个像素。
我们可以用一个例子来演示这一点,该例子使用带有垂直线(左)点积(")的 8×8 图像运算符),垂直线滤镜(右)的步长为两个像素:
0, 0, 0 0, 1, 0
0, 0, 0 . 0, 1, 0 = 0
0, 0, 0 0, 1, 0
向右移动两个像素:
0, 1, 1 0, 1, 0
0, 1, 1 . 0, 1, 0 = 3
0, 1, 1 0, 1, 0
向右移动两个像素:
1, 0, 0 0, 1, 0
1, 0, 0 . 0, 1, 0 = 0
1, 0, 0 0, 1, 0
我们可以看到,3×3 滤波器对于 8×8 输入图像只有三种有效的应用,步长为 2。这在垂直维度上是相同的。
这具有以这样的方式应用滤波器的效果,即正常特征图输出(6×6)被下采样,使得每个维度的大小减少一半(3×3),导致像素数量的 1/4(36 个像素减少到 9 个)。
步幅可以通过“步幅参数在 Conv2D 层上的 Keras 中指定,并指定为具有高度和宽度的元组。
该示例演示了我们的手动垂直线滤波器在 8×8 输入图像上的应用,其中卷积层的步长为 2。
# example of vertical line filter with a stride of 2
from numpy import asarray
from keras.models import Sequential
from keras.layers import Conv2D
# define input data
data = [[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0]]
data = asarray(data)
data = data.reshape(1, 8, 8, 1)
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), strides=(2, 2), input_shape=(8, 8, 1)))
# summarize model
model.summary()
# define a vertical line detector
detector = [[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]]]
weights = [asarray(detector), asarray([0.0])]
# store the weights in the model
model.set_weights(weights)
# apply filter to input data
yhat = model.predict(data)
# enumerate rows
for r in range(yhat.shape[1]):
# print each column in the row
print([yhat[0,r,c,0] for c in range(yhat.shape[2])])
运行该示例,我们可以从模型的摘要中看到,输出要素图的形状将为 3×3。
将手工制作的过滤器应用于输入图像并打印生成的激活特征图,我们可以看到,实际上,过滤器仍然检测到垂直线,并且可以用更少的信息来表示这一发现。
在模型中使用的滤波器或模型体系结构的更深入的知识允许在结果特征图中进行一些压缩的一些情况下,下采样可能是期望的。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 3, 3, 1) 10
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0
_________________________________________________________________
[0.0, 3.0, 0.0]
[0.0, 3.0, 0.0]
[0.0, 3.0, 0.0]
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
邮件
书
- 第九章:卷积网络,深度学习,2016。
- 第五章:计算机视觉深度学习,Python 深度学习,2017。
应用程序接口
摘要
在本教程中,您发现了卷积神经网络中滤波器大小、填充需求和步长的直觉。
具体来说,您了解到:
- 过滤器大小或内核大小如何影响输出要素图的形状。
- 过滤器大小如何在要素地图中创建边框效果,以及如何通过填充来克服它。
- 如何使用输入图像上过滤器的步幅对输出要素图的大小进行下采样。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。
卷积神经网络池化层的简单介绍
最后更新于 2019 年 7 月 5 日
卷积神经网络中的卷积层总结输入图像中特征的存在。
输出要素地图的一个问题是,它们对输入中要素的位置很敏感。解决这种敏感性的一种方法是对特征图进行下采样。这具有使所得到的下采样特征图对图像中特征位置的变化更鲁棒的效果,这由技术短语“局部平移不变性来指代。”
通过汇总要素图的面片中存在的要素,池化层提供了一种对要素图进行下采样的方法。两种常见的池化方法是平均池化和最大池化,它们分别总结了特征的平均存在和特征的最活跃存在。
在本教程中,您将发现池操作如何工作,以及如何在卷积神经网络中实现它。
完成本教程后,您将知道:
- 需要使用池对要素地图中的要素检测进行下采样。
- 如何计算和实现卷积神经网络中的平均池和最大池?
- 如何在卷积神经网络中使用全局池?
用我的新书计算机视觉深度学习启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
卷积神经网络的池化层简介 尼古拉斯·a·托内利摄,版权所有。
教程概述
本教程分为五个部分;它们是:
- 联营
- 检测垂直线
- 平均池层数
- 最大池层数
- 全局池层
池化层
卷积神经网络中的卷积层系统地将学习的滤波器应用于输入图像,以便创建总结输入中存在的那些特征的特征图。
卷积层被证明非常有效,在深度模型中堆叠卷积层允许接近输入的层学习低级特征(例如线),而在模型中更深的层学习高阶或更抽象的特征,例如形状或特定对象。
卷积层的特征映射输出的一个限制是,它们记录输入中特征的精确位置。这意味着输入图像中要素位置的微小移动将导致不同的要素图。这可能发生在对输入图像进行重新裁剪、旋转、移动和其他微小更改时。
从信号处理中解决这个问题的一种常见方法叫做下采样。这是在输入信号的较低分辨率版本被创建的地方,它仍然包含大的或重要的结构元素,没有可能对任务不那么有用的精细细节。
通过改变图像上卷积的步距,可以用卷积层实现下采样。一种更健壮和常见的方法是使用池层。
池化层是在卷积层之后添加的新层。具体地,在非线性(例如,ReLU)已经被应用于卷积层输出的特征图之后;例如,模型中的层可能如下所示:
- 输入图像
- 卷积层
- 非线性
- 池化层
在卷积层之后添加池化层是用于在卷积神经网络内排序层的常见模式,在给定的模型中可以重复一次或多次。
池化层分别对每个要素地图进行操作,以创建一组相同数量的池化要素地图。
池化包括选择池化操作,很像应用于要素地图的过滤器。池操作或过滤器的大小小于要素地图的大小;具体来说,几乎总是以 2 像素的步幅应用 2×2 像素。
这意味着池化层将始终将每个要素地图的大小减少 2 倍,例如每个维度减半,将每个要素地图中的像素或值的数量减少到大小的四分之一。例如,应用于 6×6 (36 像素)要素图的池化层将产生 3×3 (9 像素)的输出池化要素图。
池操作是指定的,而不是学习的。池操作中使用的两个常见功能是:
- 平均池化:计算要素图上每个斑块的平均值。
- 最大池化(或最大池化):计算要素图每个面片的最大值。
使用池化层并创建下采样或池化要素图的结果是在输入中检测到的要素的汇总版本。它们是有用的,因为卷积层检测到的输入中的特征位置的微小变化将导致具有相同位置的特征的池化特征图。通过池化增加的这种能力被称为模型对本地翻译的不变性。
在所有情况下,池化有助于使表示对于输入的小翻译变得近似不变。对翻译的不变性意味着,如果我们翻译少量的输入,大多数合并输出的值不会改变。
—第 342 页,深度学习,2016。
现在我们已经熟悉了池层的需求和好处,让我们看一些具体的例子。
检测垂直线
在我们看一些池层及其效果的例子之前,让我们开发一个输入图像和卷积层的小例子,稍后我们可以添加和评估池层。
在本例中,我们定义了一个输入图像或样本,它有一个通道,是一个 8 像素乘 8 像素的正方形,所有值都为 0,中间有一条两像素宽的垂直线。
# define input data
data = [[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0]]
data = asarray(data)
data = data.reshape(1, 8, 8, 1)
接下来,我们可以定义一个模型,该模型期望输入样本具有形状(8,8,1),并且具有单个隐藏卷积层,该隐藏卷积层具有形状为 3 像素乘 3 像素的单个滤波器。
然后,将校正后的线性激活函数(简称 ReLU)应用于特征图中的每个值。这是一种简单而有效的非线性,在这种情况下不会改变要素图中的值,但它的存在是因为我们稍后将添加后续的池化层,并且在将非线性应用于要素图后添加池化,例如最佳实践。
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), activation='relu', input_shape=(8, 8, 1)))
# summarize model
model.summary()
作为模型初始化的一部分,使用随机权重初始化过滤器。
相反,我们将硬编码我们自己的 3×3 过滤器,它将检测垂直线。也就是说,当检测到垂直线时,过滤器将被强激活,当检测不到垂直线时,过滤器将被弱激活。我们期望通过在输入图像上应用该过滤器,输出特征图将显示垂直线被检测到。
# define a vertical line detector
detector = [[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]]]
weights = [asarray(detector), asarray([0.0])]
# store the weights in the model
model.set_weights(weights)
接下来,我们可以通过调用模型上的 predict() 函数将过滤器应用于我们的输入图像。
# apply filter to input data
yhat = model.predict(data)
结果是一个四维输出,包含一个批处理、给定数量的行和列以及一个过滤器,或[批处理、行、列、过滤器]。我们可以在单个特征图中打印激活,以确认检测到该行。
# enumerate rows
for r in range(yhat.shape[1]):
# print each column in the row
print([yhat[0,r,c,0] for c in range(yhat.shape[2])])
将所有这些结合在一起,下面列出了完整的示例。
# example of vertical line detection with a convolutional layer
from numpy import asarray
from keras.models import Sequential
from keras.layers import Conv2D
# define input data
data = [[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0]]
data = asarray(data)
data = data.reshape(1, 8, 8, 1)
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), activation='relu', input_shape=(8, 8, 1)))
# summarize model
model.summary()
# define a vertical line detector
detector = [[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]]]
weights = [asarray(detector), asarray([0.0])]
# store the weights in the model
model.set_weights(weights)
# apply filter to input data
yhat = model.predict(data)
# enumerate rows
for r in range(yhat.shape[1]):
# print each column in the row
print([yhat[0,r,c,0] for c in range(yhat.shape[2])])
运行示例首先总结模型的结构。
值得注意的是,单个隐藏卷积层将采用 8×8 像素的输入图像,并将产生尺寸为 6×6 的特征图。
我们还可以看到该层有 10 个参数:即滤波器的 9 个权重(3×3)和偏差的 1 个权重。
最后,打印单一要素地图。
通过查看 6×6 矩阵中的数字,我们可以看到手动指定的过滤器确实检测到了输入图像中间的垂直线。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 6, 6, 1) 10
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0
_________________________________________________________________
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
我们现在可以看看一些常见的池化方法,以及它们如何影响输出要素图。
平均池层
在二维要素地图上,池化通常应用于跨度为(2,2)的 2×2 要素地图块。
平均池包括计算要素地图每个面片的平均值。这意味着特征图的每个 2×2 的正方形被下采样到正方形中的平均值。
例如,上一节中的线检测器卷积滤波器的输出是 6×6 特征图。我们可以考虑将平均池操作手动应用到要素地图的第一行。
输出要素图的第一行(前两行六列)如下所示:
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
第一个池操作应用如下:
average(0.0, 0.0) = 0.0
0.0, 0.0
假设步幅为 2,操作将向左移动两列,并计算平均值:
average(3.0, 3.0) = 3.0
3.0, 3.0
同样,该操作向左移动两列,并计算平均值:
average(0.0, 0.0) = 0.0
0.0, 0.0
这是第一条联营线。结果是平均池操作的第一行:
[0.0, 3.0, 0.0]
给定(2,2)步距,操作将向下移动两行,回到第一列,过程继续。
因为下采样操作将每个维度减半,所以我们期望应用于 6×6 要素图的池化输出是新的 3×3 要素图。给定要素图输入的水平对称性,我们期望每行具有相同的平均池值。因此,我们预计前一部分中检测到的线要素图的平均池如下所示:
[0.0, 3.0, 0.0]
[0.0, 3.0, 0.0]
[0.0, 3.0, 0.0]
我们可以通过更新上一节中的示例来确认这一点,以使用平均池。
这可以在 Keras 中通过使用平均池 2D 层来实现。层的默认 pool_size(如内核大小或过滤器大小)是(2,2),默认的步长是无,这种情况下意味着使用 pool_size 作为步长,将是(2,2)。
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), activation='relu', input_shape=(8, 8, 1)))
model.add(AveragePooling2D())
下面列出了平均池的完整示例。
# example of average pooling
from numpy import asarray
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import AveragePooling2D
# define input data
data = [[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0]]
data = asarray(data)
data = data.reshape(1, 8, 8, 1)
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), activation='relu', input_shape=(8, 8, 1)))
model.add(AveragePooling2D())
# summarize model
model.summary()
# define a vertical line detector
detector = [[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]]]
weights = [asarray(detector), asarray([0.0])]
# store the weights in the model
model.set_weights(weights)
# apply filter to input data
yhat = model.predict(data)
# enumerate rows
for r in range(yhat.shape[1]):
# print each column in the row
print([yhat[0,r,c,0] for c in range(yhat.shape[2])])
运行示例首先总结模型。
我们可以从模型摘要中看到,池化层的输入将是一个具有形状(6,6)的单个要素地图,平均池化层的输出将是一个每个维度减半的单个要素地图,具有形状(3,3)。
应用平均池会产生一个新的要素图,该图仍然可以检测到线,尽管是以向下采样的方式,这与我们通过手动计算操作所预期的完全一样。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 6, 6, 1) 10
_________________________________________________________________
average_pooling2d_1 (Average (None, 3, 3, 1) 0
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0
_________________________________________________________________
[0.0, 3.0, 0.0]
[0.0, 3.0, 0.0]
[0.0, 3.0, 0.0]
平均池运行良好,尽管使用最大池更常见。
最大池层
最大池化或最大池化是一种池化操作,用于计算每个要素地图的每个面片中的最大值。
结果是向下采样或池化的要素图,突出显示补丁中最常见的要素,而不是平均池化情况下要素的平均存在。在实践中发现,这种方法比计算机视觉任务(如图像分类)的平均池化更有效。
简而言之,原因是要素往往会在要素地图的不同区块上编码某种模式或概念的空间存在(因此,术语“要素地图”),并且查看不同要素的最大存在比查看它们的平均存在更能提供信息。
—第 129 页,Python 深度学习,2017。
我们可以通过再次将其应用于线检测器卷积运算的输出特征图并手动计算合并特征图的第一行来使最大合并操作具体化。
输出要素图的第一行(前两行六列)如下所示:
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
[0.0, 0.0, 3.0, 3.0, 0.0, 0.0]
第一个最大池操作应用如下:
max(0.0, 0.0) = 0.0
0.0, 0.0
如果步幅为 2,操作将向左移动两列,并计算最大值:
max(3.0, 3.0) = 3.0
3.0, 3.0
同样,操作会向左移动两列,并计算最大值:
max(0.0, 0.0) = 0.0
0.0, 0.0
这是第一条联营线。
结果是最大池操作的第一行:
[0.0, 3.0, 0.0]
同样,考虑到为池化提供的要素图的水平对称性,我们期望池化的要素图如下所示:
[0.0, 3.0, 0.0]
[0.0, 3.0, 0.0]
[0.0, 3.0, 0.0]
当使用平均池和最大池进行下采样时,所选的线检测器图像和特征图会产生相同的输出。
通过添加 Keras API 提供的maxpool2d层,可以将最大池操作添加到工作示例中。
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), activation='relu', input_shape=(8, 8, 1)))
model.add(MaxPooling2D())
下面列出了最大池化垂直线检测的完整示例。
# example of max pooling
from numpy import asarray
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
# define input data
data = [[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0]]
data = asarray(data)
data = data.reshape(1, 8, 8, 1)
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), activation='relu', input_shape=(8, 8, 1)))
model.add(MaxPooling2D())
# summarize model
model.summary()
# define a vertical line detector
detector = [[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]]]
weights = [asarray(detector), asarray([0.0])]
# store the weights in the model
model.set_weights(weights)
# apply filter to input data
yhat = model.predict(data)
# enumerate rows
for r in range(yhat.shape[1]):
# print each column in the row
print([yhat[0,r,c,0] for c in range(yhat.shape[2])])
运行示例首先总结模型。
我们可以看到,正如我们现在可能预期的那样,最大池层的输出将是每个维度减半的单个要素地图,形状为(3,3)。
应用最大池会产生一个新的要素图,该图仍然可以检测到线,尽管是以向下采样的方式。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 6, 6, 1) 10
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 3, 3, 1) 0
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0
_________________________________________________________________
[0.0, 3.0, 0.0]
[0.0, 3.0, 0.0]
[0.0, 3.0, 0.0]
全局池层
还有另一种类型的池,有时被称为全局池。
全局池不是对输入要素图的面片进行向下采样,而是将整个要素图向下采样为单个值。这与将池大小设置为输入要素图的大小相同。
全局池可用于模型中,以积极总结图像中某个特征的存在。它有时也用于模型中,作为使用完全连接的层从要素地图过渡到模型输出预测的替代方法。
Keras 分别通过global average pool 2d和global maxpool 2d类支持全局平均池和全局最大池。
例如,我们可以向用于垂直线检测的卷积模型添加全局最大池。
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), activation='relu', input_shape=(8, 8, 1)))
model.add(GlobalMaxPooling2D())
结果将是一个单一的值,它将总结输入图像中垂直线的最强激活或存在。
完整的代码列表如下。
# example of using global max pooling
from numpy import asarray
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import GlobalMaxPooling2D
# define input data
data = [[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0]]
data = asarray(data)
data = data.reshape(1, 8, 8, 1)
# create model
model = Sequential()
model.add(Conv2D(1, (3,3), activation='relu', input_shape=(8, 8, 1)))
model.add(GlobalMaxPooling2D())
# summarize model
model.summary()
# # define a vertical line detector
detector = [[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]],
[[[0]],[[1]],[[0]]]]
weights = [asarray(detector), asarray([0.0])]
# store the weights in the model
model.set_weights(weights)
# apply filter to input data
yhat = model.predict(data)
# enumerate rows
print(yhat)
运行示例首先总结模型
我们可以看到,正如预期的那样,全局池层的输出是一个单一值,它总结了单一要素地图中要素的存在。
接下来,打印模型的输出,在要素图上显示全局最大池化的效果,打印单个最大激活。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 6, 6, 1) 10
_________________________________________________________________
global_max_pooling2d_1 (Glob (None, 1) 0
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0
_________________________________________________________________
[[3.]]
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
邮件
书
- 第九章:卷积网络,深度学习,2016。
- 第五章:计算机视觉深度学习,Python 深度学习,2017。
应用程序接口
摘要
在本教程中,您发现了池操作如何工作,以及如何在卷积神经网络中实现它。
具体来说,您了解到:
- 需要使用池对要素地图中的要素检测进行下采样。
- 如何计算和实现卷积神经网络中的平均池和最大池?
- 如何在卷积神经网络中使用全局池?
你有什么问题吗? 在下面的评论中提问,我会尽力回答。
深度学习计算机视觉前景的温和介绍
最后更新于 2019 年 7 月 5 日
计算机视觉领域的深度学习的承诺是通过可能需要更多数据但较少数字信号处理专业知识来训练和操作的模型获得更好的表现。
有很多关于深度学习方法的炒作和大量声明,但是除了炒作之外,深度学习方法在具有挑战性的问题上取得了最先进的结果。值得注意的是,在计算机视觉任务上,如图像分类、目标识别和人脸检测。
在这篇文章中,你会发现深度学习方法对于解决计算机视觉问题的具体承诺。
看完这篇文章,你会知道:
- 计算机视觉深度学习的前景。
- 深度学习已经或正在兑现承诺的例子。
- 计算机视觉的关键深度学习方法及应用。
用我的新书计算机视觉深度学习启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
对计算机视觉深度学习的承诺的温和介绍 图片由冈本 osamu】提供,版权所有。
概观
本教程分为三个部分;它们是:
- 深度学习的承诺
- 深度学习网络模型的类型
- 计算机视觉问题的类型
深度学习的承诺
深度学习方法很受欢迎,主要是因为它们兑现了自己的承诺。
这并不是说这项技术没有炒作,而是炒作是基于非常真实的结果,这些结果正在从计算机视觉和自然语言处理的一系列非常具有挑战性的人工智能问题中得到证明。
深度学习的力量最初的一些大型演示是在计算机视觉中,具体来说是图像识别。最近在对象检测和人脸识别。
在这篇文章中,我们将看看计算机视觉领域深度学习方法的五个具体承诺。
概括来说,它们是:
- 自动特征提取的承诺。可以从原始图像数据中自动学习和提取特征。
- 端到端模型的承诺。单个端到端模型可以替代专用模型的管道。
- 模型重用的承诺。学习的特性甚至整个模型都可以在任务中重用。
- 卓越表现的承诺。技术展示了更好的挑战任务的技能。
- 通用方法的承诺。单一的通用方法可用于一系列相关任务。
我们现在将仔细看看每一个。
计算机视觉还有其他深度学习的希望;这只是我选择强调的五点。
你认为深度学习对计算机视觉的承诺是什么? 在下面的评论里告诉我。
承诺 1:自动特征提取
计算机视觉领域的主要研究重点是从数字图像中检测和提取特征的技术。
提取的特征为关于图像的推断提供了背景,并且通常特征越丰富,推断越好。
复杂的手工设计特征如尺度不变特征变换(SIFT) 、 Gabor 滤波器、方向梯度直方图(HOG) 一段时间以来一直是计算机视觉用于特征提取的重点,并取得了很好的成功。
深度学习的前景是复杂和有用的特征可以直接从大型图像数据集自动学习。更具体地说,可以从图像中学习和自动提取丰富特征的深层结构,这是由多个深层神经网络模型提供的。
他们有更深的体系结构,有能力学习比浅体系结构更复杂的特性。此外,可表达性和健壮的训练算法允许学习信息丰富的对象表示,而不需要手动设计特征。
——深度学习的对象检测:综述,2018。
深度神经网络模型正在兑现这一承诺,最显著的表现是从复杂的手工特征检测方法(如 SIFT)向标准计算机视觉基准数据集和竞赛(如 ImageNet 大规模视觉识别竞赛(ILSVRC) )上的深度卷积神经网络过渡。
在过去的五年里,ILSVRC 为计算机视觉的几项突破铺平了道路。分类目标识别领域已经发生了巨大的变化……从编码的 SIFT 特征开始,发展到大规模卷积神经网络,在图像分类、单目标定位和对象检测这三个任务中占据主导地位。
— ImageNet 大规模视觉识别挑战,2015。
承诺 2:端到端模型
解决传统上涉及使用模块化模型系统的计算机视觉任务。
每个模型都是为特定任务设计的,例如特征提取、图像对齐或分类。这些模型在管道中使用,一端是原始图像,另一端是结果,如预测。
这种流水线方法可以并且仍然用于深度学习模型,其中特征检测器模型可以用深度神经网络代替。
或者,深度神经网络允许单个模型包含两个或多个传统模型,例如特征提取和分类。使用直接在原始像素值上训练的单个模型进行图像分类是很常见的,并且已经出现了替换使用深度神经网络模型的管道的趋势,其中直接端到端地训练单个模型。
有了如此多的训练数据(以及高效的算法实现和图形处理器计算资源),就有可能直接从图像数据中学习神经网络,而不需要创建提取特征和鉴别分类器的多级手动调整管道。
——ImageNet 大规模视觉识别挑战赛,2015 年。
这方面的一个很好的例子是在对象检测和人脸识别中,其中最初仅使用深度卷积神经网络进行特征提取就获得了优异的表现,最近,直接使用多输出模型(例如类和包围盒)和/或新的损失函数(例如对比或三元组损失函数)来训练端到端模型。
承诺 3:模型重用
通常,为数据集准备的特征检测器对该数据集具有高度的特异性。
这是有意义的,因为您可以在模型中使用的域信息越多,模型在域中的表现就越好。
深度神经网络通常在比传统数据集大得多的数据集上训练,例如数百万或数十亿幅图像。这使得模型能够学习照片中常见的特征和特征层次,这本身就很了不起。
如果这个原始数据集足够大并且足够通用,那么由预训练网络学习的特征的空间层次可以有效地充当视觉世界的通用模型,因此它的特征可以被证明对许多不同的计算机视觉问题有用,即使这些新问题可能涉及与原始任务完全不同的类别。
—第 143 页,Python 深度学习,2017。
例如,通常使用在大型 ImageNet 数据集或该数据集的子集中训练的深度模型,直接或作为一系列计算机视觉任务的起点。
…通常使用在 ImageNet 上训练的卷积网络的特征来解决其他计算机视觉任务
—第 426 页,深度学习,2016。
这被称为迁移学习,使用可能需要几天甚至几周时间来训练的预训练模型已经成为标准做法。
预训练模型可用于从数字图像中提取有用的一般特征,也可以根据新任务的具体情况进行微调。这可以节省大量时间和资源,并几乎立即产生非常好的结果。
在小图像数据集上进行深度学习的一种常见且高效的方法是使用预训练网络。
—第 143 页,Python 深度学习,2017。
承诺 4:卓越的表现
深度神经网络在计算机视觉中的一个重要前景是更好的表现。
正是深度神经网络显著提高的表现促进了深度学习领域的发展和兴趣。虽然这种技术已经存在了几十年,但火花是 Alex Krizhevsky 等人在 2012 年进行图像分类时的出色表现。
当前深度学习的商业兴趣强度始于 Krizhevsky 等人(2012 年)赢得 ImageNet 对象识别挑战…
—第 371 页,深度学习,2016。
他们的深度卷积神经网络模型,当时被称为 SuperIt,后来被称为 AlexNet,导致了分类准确率的飞跃。
我们还在 ILSVRC-2012 竞赛中输入了该模型的变体,并获得了 15.3%的前 5 名测试成功率,而第二名的测试成功率为 26.2%。
——深度卷积神经网络的 ImageNet 分类,2012。
该技术随后被用于一系列极具挑战性的计算机视觉任务,包括对象检测,与当时最先进的传统方法相比,该技术的模型表现也有了很大的飞跃。
对象检测的第一个突破是 RCNN,它比以前的技术水平提高了近 30%。
——利用深度学习的现代对象检测文献综述,2018。
在一系列计算机视觉任务中,这种改进趋势逐年持续。
表现如此引人注目,以至于以前被认为不容易被计算机寻址并用作验证码来防止垃圾邮件的任务(例如预测照片是狗还是猫)被有效地“解决了”,人脸识别等问题的模型取得了比人类更好的表现。
自深度学习在 2012 年进入市场以来,我们可以观察到显著的表现(平均准确率)提升。最佳检测器的表现每年都在稳步提升。
——面向通用对象检测的深度学习:一项调查,2018。
承诺 5:一般方法
也许深度学习最重要的承诺是,表现最好的模型都是从相同的基本组件开发出来的。
令人印象深刻的结果来自一种称为卷积神经网络的网络,由卷积层和池化层组成。它是专门为图像数据设计的,可以直接在像素数据上进行训练(只需进行一些小的缩放)。
卷积网络提供了一种方法,使神经网络专门化,以处理具有清晰网格结构拓扑的数据,并将这种模型扩展到非常大的规模。这种方法在二维图像拓扑中最为成功。
—第 372 页,深度学习,2016。
这不同于更广泛的领域,该领域可能需要为手写识别、字符识别、面部识别、对象检测等开发的专门的特征检测方法。取而代之的是,可以直接在每个计算机视觉任务中配置和使用一个通用的模型类。
这是一般机器学习的承诺;令人印象深刻的是,这样一种多功能的技术已经被发现并展示给计算机视觉。
此外,该模型相对容易理解和训练,尽管可能需要现代图形处理器硬件来在大数据集上有效训练,并且可能需要模型超参数调整来实现边缘表现。
深度学习网络模型的类型
深度学习是一个很大的研究领域,并不是所有的都与计算机视觉相关。
很容易陷入旨在提升表现的特定优化方法或模型类型扩展中。
从高层次来看,有一种来自深度学习的方法在计算机视觉应用中最值得关注。它是:
- 卷积神经网络。
CNN 之所以成为深度学习模型关注的焦点,是因为它们是专门为图像数据设计的。
此外,以下两种网络类型可能有助于从神经网络学习和提取的特征中解释或开发推理模型;它们是:
- 多层感知器(MLP)。
- 递归神经网络。
MLP 或全连接型神经网络层对于开发模型很有用,这些模型可以在已知由 CNN 提取的学习特征的情况下进行预测。当随着时间的推移处理图像序列时,如视频,像 LSTMs 这样的 rnn 可能会有所帮助。
计算机视觉问题的类型
深度学习解决不了计算机视觉或人工智能。
到目前为止,深度学习方法已经在计算机视觉的一组更广泛的问题上进行了评估,并在一小部分问题上取得了成功,其中成功表明表现或能力达到或超过了以前其他方法可能达到的水平。
重要的是,那些深度学习方法显示出最大成功的领域是一些更终端用户面临的、具有挑战性的、也许更有趣的问题。
五个例子包括:
- 光学字符识别。
- 图像分类。
- 对象检测。
- 人脸检测。
- 人脸识别。
所有这五项任务都在“对象识别的保护伞下相关联,对象识别是指涉及从数字照片中识别、定位和/或提取特定内容的任务。
计算机视觉的最深度学习用于对象识别或某种形式的检测,无论这意味着报告图像中存在哪个对象,用每个对象周围的边界框注释图像,从图像中转录符号序列,还是用其所属对象的身份标记图像中的每个像素。
—第 453 页,深度学习,2016。
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
书
- 深度学习,2016 年。
- 用 Python 深度学习,2017。
报纸
- ImageNet 大规模视觉识别挑战赛,2015 年。
- 深度卷积神经网络的 ImageNet 分类,2012。
- 深度学习的对象检测:综述,2018。
- 利用深度学习的现代对象检测文献综述,2018。
- 通用对象检测的深度学习:一项调查,2018。
摘要
在这篇文章中,你发现了深度学习方法对解决计算机视觉问题的具体承诺。
具体来说,您了解到:
- 计算机视觉深度学习的前景。
- 深度学习已经或正在兑现承诺的例子。
- 计算机视觉的关键深度学习方法及应用。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。
用于图像分类的卷积神经网络模型创新
最后更新于 2019 年 7 月 5 日
温和地介绍了 LeNet,AlexNet,VGG,Inception 和 ResNet 卷积神经网络的创新。
尽管很简单,但对于给定的计算机视觉问题,有几乎无限种方法来排列这些层。
幸运的是,既有配置这些层的通用模式,也有可以用来开发深度卷积神经网络的架构创新。研究这些为最先进的图像分类任务开发的架构设计决策,可以为设计自己的深度卷积神经网络模型时如何使用这些设计提供理论基础和直觉。
在本教程中,您将发现卷积神经网络用于挑战图像分类问题的关键架构里程碑。
完成本教程后,您将知道:
- 在实现卷积神经网络时如何对滤波器数量和滤波器大小进行模式化?
- 如何以统一的模式排列卷积层和池化层,以开发表现良好的模型。
- 如何利用初始模块和剩余模块开发更深层次的卷积网络?
用我的新书计算机视觉深度学习启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
- 2019 年 4 月更新:修正了 LeNet 的过滤器尺寸说明(感谢黄)。
教程概述
本教程分为六个部分;它们是:
- CNN 的建筑设计
- 莱内-5
- 阿勒克斯网
- VGG
- Inception 和谷歌网
- 剩余网络或资源网
CNN 的建筑设计
卷积神经网络的元素,如卷积层和池化层,理解起来相对简单。
在实践中使用卷积神经网络的挑战部分是如何设计最好地使用这些简单元素的模型架构。
学习如何设计有效的卷积神经网络体系结构的一个有用方法是研究成功的应用。这一点特别容易做到,因为在 2012 年至 2016 年期间,针对 ImageNet 大规模视觉识别挑战(ILSVRC)对 CNN 进行了大量研究和应用。这一挑战导致了非常困难的计算机视觉任务在技术水平上的快速进步,以及卷积神经网络模型体系结构的一般创新的发展。
我们将从 LeNet-5 开始,它通常被描述为在 ILSVRC 之前 CNNs 的第一个成功和重要的应用,然后看看为 ILSVRC 开发的卷积神经网络的四个不同的获奖架构创新,即 AlexNet、VGG、Inception 和 ResNet。
通过从高层次理解这些里程碑模型及其架构或架构创新,您将对这些架构元素在 CNN 在计算机视觉中的现代应用中的使用形成欣赏,并能够识别和选择可能对您自己的模型设计有用的架构元素。
莱内-5
也许卷积神经网络的第一个广为人知的成功应用是 LeNet-5,由 Yann LeCun 等人在 1998 年发表的题为“基于梯度的学习在文档识别中的应用”(获得 PDF )的论文中进行了描述。
该系统是为手写字符识别问题而开发的,并在 MNIST 标准数据集上进行了演示,实现了大约 99.2%的分类准确率(或 0.8%的错误率)。该网络随后被描述为被称为图形转换器网络的更广泛系统中的核心技术。
这是一篇很长的论文,也许最值得关注的部分是第二部分。b .描述 LeNet-5 架构。在本节中,论文将网络描述为七层,输入灰度图像的形状为 32×32,即 MNIST 数据集中图像的大小。
该模型提出了一种卷积层模式,后面是平均池化层,称为子采样层。在输出要素图被展平并馈送到多个完全连接的层进行解释和最终预测之前,此模式会重复两次半。论文中提供了网络架构的图片,转载如下。
用于手写字符识别的 LeNet-5 卷积神经网络的结构(取自 1998 年的论文)。
二十多年后的今天,卷积层和池化层分组在一起并重复的块模式仍然是设计和使用卷积神经网络的常见模式。
有趣的是,该架构使用少量滤镜作为第一隐藏层,具体来说是六个滤镜,每个滤镜的大小为 5×5 像素。在合并(称为子采样层)之后,另一个卷积层具有更多的滤波器,同样具有更小的尺寸,但是比先前的卷积层更小,具体地说,具有 5×5 像素尺寸的 16 个滤波器,再次跟随合并。在这两个卷积和池化层块的重复中,趋势是过滤器的数量增加。
与现代应用相比,过滤器的数量也很少,但是随着网络的深度增加过滤器数量的趋势也仍然是该技术的现代使用中的常见模式。
特征地图的展平以及通过完全连接的层对提取的特征进行解释和分类也仍然是当今的常见模式。在现代术语中,体系结构的最后一部分通常被称为分类器,而模型中前面的卷积层和池化层被称为特征提取器。
我们可以将与现代模型相关的架构的关键方面总结如下:
- 固定大小的输入图像。
- 将卷积层和池层分组为块。
- 体系结构中卷积池块的重复。
- 随着网络的深度增加过滤器的数量。
- 架构中不同的特征提取和分类器部分。
阿勒克斯网
这项工作也许可以被认为激发了人们对神经网络的新兴趣,并开始了深度学习在许多计算机视觉应用中的主导地位,这是亚历克斯·克里哲夫斯基等人在 2012 年发表的题为“用深度卷积神经网络进行图像网络分类”的论文
该论文描述了一个后来被称为“阿列克谢网”的模型,旨在解决“T2”图像网大规模视觉识别挑战“T3”或“T4”ILSVRC-2010“T5”竞赛,将对象照片分类为 1000 个不同类别之一。
ILSVRC 是 2011 年至 2016 年举办的竞赛,旨在激励计算机视觉领域的创新。在 AlexNet 开发之前,这项任务被认为非常困难,远远超出了现代计算机视觉方法的能力。AlexNet 成功地展示了卷积神经网络模型在该领域的能力,并点燃了一把火,带来了更多的改进和创新,在随后的几年中,许多人在同一个 ILSVRC 任务上进行了演示。更广泛地说,该论文表明,在不使用当时流行的无监督预处理技术的情况下,为一个具有挑战性的问题开发深度和有效的端到端模型是可能的。
在 AlexNet 的设计中,重要的是一套新的或成功的方法,但在当时没有被广泛采用。现在,它们已经成为使用 CNNs 进行图像分类时的要求。
AlexNet 使用校正线性激活函数,或 ReLU,作为每个卷积层之后的非线性函数,而不是在此之前常见的 S 形函数,如 logistic 或 tanh。此外,在输出层使用了 softmax 激活函数,现在是神经网络多类分类的主要工具。
LeNet-5 中使用的平均池化被最大池化方法取代,尽管在这种情况下,重叠池化被发现优于目前常用的非重叠池化(例如,池化操作的步长与池化操作的步长相同,例如 2 乘 2 像素)。为了解决过拟合问题,在模型的分类器部分的完全连接层之间使用了新提出的脱落方法来改善泛化误差。
AlexNet 的体系结构是深入的,并且扩展了 LeNet-5 建立的一些模式。下图,取自论文,总结了模型架构,在这种情况下,分为两个管道,在当时的 GPU 硬件上进行训练。
用于对象照片分类的 AlexNet 卷积神经网络的体系结构(取自 2012 年论文)。
该模型在模型的特征提取部分有五个卷积层,在模型的分类器部分有三个完全连接的层。
输入图像大小固定为 224×224,有三个颜色通道。就每个卷积层中使用的滤波器数量而言,在 LeNet 中看到的随着深度增加滤波器数量的模式基本上得到遵守,在这种情况下,大小为 96、256、384、384 和 256。类似地,使用了随深度减小滤波器(核)大小的模式,从较小的 11×11 开始,减小到 5×5,然后在更深的层中减小到 3×3。现在,使用 5×5 和 3×3 等小型滤波器已成为常态。
在模型的特征检测部分的开始和结束使用了卷积层后跟池化层的模式。有趣的是,使用了紧接着第二卷积层的卷积层模式。这种模式也成为了现代标准。
该模型通过数据扩充进行训练,人工增加了训练数据集的大小,并使模型有更多的机会在不同方向学习相同的特征。
我们可以将与现代模型相关的架构的关键方面总结如下:
- 卷积层之后使用 ReLU 激活函数,输出层使用 softmax。
- 使用最大池而不是平均池。
- 在完全连接的层之间使用 Dropout 正则化。
- 卷积层的模式直接馈送到另一个卷积层。
- 数据扩充的使用。
VGG
用于计算机视觉任务的深度卷积神经网络的发展似乎是 AlexNet 之后的一种黑暗艺术。
一项旨在实现深度卷积网络架构设计标准化并在此过程中开发更深入、表现更好的模型的重要工作是卡伦·西蒙扬和安德鲁·齐泽曼在 2014 年发表的题为“用于大规模图像识别的非常深卷积网络”的论文。
他们的建筑通常被称为 VGG,以他们的实验室牛津视觉几何小组的名字命名。他们的模型是在 sameILSVRC 竞赛上开发和演示的,在本例中,是 ILSVRC-2014 版本的挑战赛。
成为事实标准的第一个重要区别是使用了大量小型过滤器。具体来说,3×3 和 1×1 的滤波器,步长为 1,不同于 LeNet-5 中的大尺寸滤波器和 AlexNet 中较小但仍然相对较大的滤波器以及 4 的大步长。
借鉴 AlexNet 中的示例,最大池层在卷积层之后使用,但不是全部,然而所有池都以 2×2 的大小和相同的步长执行,这也已经成为事实上的标准。具体来说,在使用最大池层之前,VGG 网络使用堆叠在一起的两个、三个甚至四个卷积层的例子。其原理是,具有较小滤波器的堆叠卷积层近似于具有较大尺寸滤波器的一个卷积层的效果,例如,具有 3×3 滤波器的三个堆叠卷积层近似于具有 7×7 滤波器的一个卷积层。
另一个重要的区别是使用了大量的过滤器。过滤器的数量随着模型的深度而增加,尽管从相对较多的 64 个过滤器开始,并在模型的特征提取部分结束时增加到 128 个、256 个和 512 个过滤器。
开发和评估了该体系结构的多种变体,尽管考虑到它们的表现和深度,最常提到的是两种。它们是根据层数命名的:VGG 16 层和 VGG 19 层分别代表 16 层和 19 层。
下面是一张取自报纸的表格;请注意,最右边的两列显示了 VGG-16 和 VGG-19 架构版本中使用的配置(过滤器数量)。
用于对象照片分类的 VGG 卷积神经网络的体系结构(取自 2014 年论文)。
一般来说,VGG 模型中的设计决策已经成为简单直接使用卷积神经网络的起点。
最后,VGG 的工作是第一批在许可许可下发布有价值的模型权重的工作之一,这导致了深度学习计算机视觉研究人员的趋势。这反过来又导致像 VGG 这样的预训练模型在转移学习中被大量使用,作为新的计算机视觉任务的起点。
我们可以将与现代模型相关的架构的关键方面总结如下:
- 使用非常小的卷积滤波器,例如 3×3 和 1×1,步长为 1。
- 使用最大池,大小为 2×2,步长相同。
- 在使用池化层定义块之前,将卷积层堆叠在一起的重要性。
- 卷积池块模式的戏剧性重复。
- 开发非常深的(16 层和 19 层)模型。
Inception 和谷歌网
克里斯蒂安·塞格迪(Christian Szegedy)等人在 2015 年的论文中提出了卷积层使用方面的重要创新,该论文的标题为“利用卷积进行更深入的研究”
在这篇论文中,作者提出了一个被称为初始(或称初始 v1,以区别于扩展)的架构,以及一个被称为 GoogLeNet 的特定模型,该模型在 2014 年版本的 ILSVRC 挑战赛中取得了最好的结果。
初始模型的关键创新被称为初始模块。这是一组并行卷积层,具有不同大小的滤波器(例如 1×1、3×3、5×5)和一个 3×3 最大池化层,然后将它们的结果连接起来。以下是摘自论文的初始模块示例。
天真初始模块的例子(摘自 2015 年的论文)。
初始模型的天真实现的一个问题是过滤器(深度或通道)的数量开始快速增加,尤其是当初始模块被堆叠时。
在大量滤波器上执行具有较大滤波器尺寸(例如 3 和 5)的卷积在计算上可能是昂贵的。为了解决这个问题,使用 1×1 卷积层来减少初始模型中的滤波器数量。特别是在 3×3 和 5×5 卷积层之前和池化层之后。下面这张来自论文的图片展示了对初始模块的这一改变。
降维初始模块示例(摘自 2015 年的论文)。
初始模型中第二个重要的设计决策是连接模型中不同点的输出。这是通过从主网络创建小的离拍输出网络来实现的,这些网络被训练来进行预测。目的是在深度模型的不同点提供来自分类任务的额外误差信号,以便解决梯度消失问题。这些小的输出网络在训练后被移除。
下图显示了 GoogLeNet 模型架构的旋转版本(从左到右为输入到输出),该模型取自论文,使用了从左侧输入到右侧输出分类的 Inception 模块以及仅在培训期间使用的两个额外的输出网络。
在对象照片分类训练期间使用的谷歌网络模型的架构(取自 2015 年的论文)。
有趣的是,在模型的特征提取部分的末尾,在模型的分类器部分之前,使用了重叠最大池化,并且使用了大平均池化操作。
我们可以将与现代模型相关的架构的关键方面总结如下:
- 初始模块的开发和重复。
- 大量使用 1×1 卷积来减少通道数量。
- 在网络中的多个点使用错误反馈。
- 非常深(22 层)模型的开发。
- 模型输出使用全球平均池。
剩余网络或资源网
我们将回顾的卷积神经网络的最后一个重要创新是何等人在 2016 年发表的题为“用于图像识别的深度残差学习”的论文中提出的
在这篇论文中,作者提出了一个非常深入的模型,称为残差网络,简称 ResNet,它的一个例子在 2015 年版本的 ILSVRC 挑战中取得了成功。
他们的模型有令人印象深刻的 152 层。模型设计的关键是利用快捷连接的剩余块的思想。这些只是网络架构中的连接,其中输入保持原样(不加权)并传递到更深的层,例如跳过下一层。
残余块是具有 ReLU 激活的两个卷积层的模式,其中块的输出与块的输入相结合,例如快捷方式连接。如果块的输入形状不同于块的输出,则通过 1×1 使用输入的投影版本,即所谓的 1×1 卷积。与未加权或相同的快捷方式连接相比,这些被称为投影快捷方式连接。
作者从他们所谓的简单网络开始,这是一个受 VGG 启发的深度卷积神经网络,具有小滤波器(3×3),分组卷积层之后没有池化,以及在模型的特征检测器部分末端的平均池化,在具有 softmax 激活函数的完全连接输出层之前。
通过添加快捷连接来定义剩余块,将普通网络修改为剩余网络。通常,快捷方式连接的输入形状与剩余块的输出大小相同。
下图取自论文,从左到右比较了 VGG 模型、普通卷积模型和带有残差模块的普通卷积版本(称为残差网络)的体系结构。
对象照片分类剩余网络的结构(取自 2016 年论文)。
我们可以将与现代模型相关的架构的关键方面总结如下:
- 快捷连接的使用。
- 残余区块的开发和重复。
- 非常深(152 层)模型的开发。
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
报纸
- 基于梯度的学习应用于文档识别,( PDF ) 1998。
- 深度卷积神经网络的 ImageNet 分类,2012。
- 用于大规模图像识别的超深度卷积网络,2014。
- 用回旋更深入,2015。
- 图像识别的深度残差学习,2016
应用程序接口
文章
摘要
在本教程中,您发现了使用卷积神经网络挑战图像分类的关键架构里程碑。
具体来说,您了解到:
- 在实现卷积神经网络时如何对滤波器数量和滤波器大小进行模式化?
- 如何以统一的模式排列卷积层和池化层,以开发表现良好的模型。
- 如何利用初始模块和剩余模块开发更深层次的卷积网络?
你有什么问题吗? 在下面的评论中提问,我会尽力回答。
斯坦福卷积神经网络视觉识别课程(复习)
最后更新于 2019 年 7 月 5 日
斯坦福大学的计算机视觉深度学习课程可能是这方面最广为人知的课程。
这并不奇怪,因为该课程已经运行了四年,由该领域的顶级学者和研究人员讲授,课程讲座和笔记免费提供。
对于学生和深度学习实践者来说,这是一个不可思议的资源。
在这篇文章中,你会发现这门课程的一个温和的介绍,你可以用它来用深度学习方法在计算机视觉上获得一个快速的开始。
看完这篇文章,你会知道:
- 课程的分类,包括谁教的,教了多久,涵盖了什么。
- 如果你已经熟悉深度学习,课程中的讲座包括三个重点讲座。
- 对课程的回顾,包括它与同一主题的类似课程的比较。
用我的新书计算机视觉深度学习启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
概观
本教程分为三个部分;它们是:
- 课程分解
- 讲座分类
- 讨论和回顾
课程分解
课程 CS231n 是一门关于计算机视觉的计算机科学课程,其神经网络名为“用于视觉识别的卷积神经网络”,在斯坦福大学工程学院授课
这门课程以其早期(在 AlexNet 突破三年后的 2015 年开始)和免费(提供视频和幻灯片)而闻名。
安德烈·卡普西(Andrej Karpathy)创造的有趣实验也让这门课程得到了推广,比如用 Javascript(Conventjs)演示计算机视觉问题的神经网络。
从入门讲座到 CS231n 课程的示例
在撰写本报告时,本课程已经运行了四年,其中每一年的大部分内容仍然可用:
该课程由费教授,他是斯坦福视觉实验室的著名计算机视觉研究员,最近在谷歌担任首席科学家。在 2015 年至 2016 年期间,该课程由现在特斯拉的安德烈·卡普西共同教授。贾斯廷·约翰逊也从一开始就参与其中,并在 2017 年至 2018 年与杨小威共同执教。
本课程的重点是卷积神经网络(CNNs)在计算机视觉问题中的应用,重点是 CNNs 的工作原理、图像分类和识别任务,以及生成模型和深度强化学习等高级应用的介绍。
本课程深入探讨深度学习架构的细节,重点学习这些任务的端到端模型,尤其是图像分类。
讲座分类
在撰写本报告时,2018 年的视频尚未公开,但 2017 年的视频公开了。
因此,我们将重点关注 2017 年的教学大纲和视频内容。
- 【2017 年春季课程主页
- 【2017 年春季课程大纲
- 春季 2017 播放 YouTube 播放列表
课程分为 16 场讲座,14 场涵盖课程主题,两场高级主题的客座讲座,以及一段不公开的学生演讲的最终视频。
下面提供了所有视频的完整列表及其链接:
- 第一讲:视觉识别卷积神经网络介绍
- 第二讲:图像分类
- 第三讲:损失函数和优化
- 第四讲:神经网络导论
- 第五讲:卷积神经网络
- 第六讲:训练神经网络,第一部分
- 第七讲:训练神经网络,第二部分
- 第八讲:深度学习软件
- 第 9 讲:CNN 架构
- 第十讲:递归神经网络
- 第 11 讲:检测和分割
- 第 12 讲:可视化和理解
- 第十三讲:生成模型
- 第十四讲:深度强化学习
- 第 15 讲:
- 第 16 讲:学生聚光灯演讲,结论
- 没有视频
不要忽视课程大纲网页。它包括有价值的材料,例如:
- 您可以在单独的浏览器选项卡中打开讲座的 PDF 幻灯片链接。
- 链接到讲座中讨论的论文,这些论文通常是必读的。
- 链接到 HTML 注释页面,包括方法和示例代码的详细描述。
通过课程大纲提供的超文本标记语言注释示例
经验丰富的从业者必看的讲座
也许你已经熟悉了神经网络和深度学习的基础知识。
在这种情况下,如果你想参加计算机视觉技术速成班,你不需要看所有的讲座。
讲座的必看清单如下:
- 第五讲:卷积神经网络。本次讲座将让您了解 CNN 层及其工作原理。
- 第九讲:CNN 架构。本讲座将帮助您了解流行的图像分类网络体系结构。
- 第十一讲:检测与分割。本讲座将帮助您了解图像分类和对象识别任务。
这是最小的一组。
你可以多加三堂课,多得一点;它们是:
- 第 12 讲:可视化和理解。
- 本讲座描述了理解 fit 模型所见或所学的方法。
- 第十三讲:生成模型。
- 本讲座介绍了视频增强系统和图像扩充系统以及现代图像合成方法。
- 第十四讲:深度强化学习。
- 这个讲座提供了深度强化学习方法的速成课程。
讨论和回顾
我已经看了这门课的所有视频,我想每年都会有。
最近,我花了两天时间(两个早上,2 倍的速度)看完了 2017 版课程的所有讲座,并做了大量笔记。我推荐这种方法,即使你是一个有经验的深度学习实践者。
我推荐这种方法有几个原因:
- 深度学习的领域正在迅速变化。
- 斯坦福是该领域的创新和卓越中心(例如视觉实验室)。
- 基础知识的重复会带来新的想法和见解。
尽管如此,如果你想通过对计算机视觉的深度学习来快速提高速度,上一节中建议的三个讲座是你应该走的路(例如讲座 5、9 和 11)。
这门课节奏极快。
它希望你能跟上,如果你没有得到什么,那就由你来暂停,然后去解决它。
这很公平,毕竟课程是在斯坦福大学,但它比其他课程不太友好,最著名的是吴恩达的 DeepLearning.ai 卷积神经网络课程。
因此,如果你需要一些手把手的东西,我不推荐这门课;选修另一门课程,因为它是为开发者设计的,而不是斯坦福的学生。
也就是说,你从世界顶级学者和研究生那里听到了关于 CNN 和现代方法是如何工作的,这是无价的。
事实上,这些视频是免费提供的,这对从业者来说是一个独特的机会。
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
- CS231n:用于视觉识别的卷积神经网络,2018。
- CS231n:用于视觉识别的卷积神经网络,2017。
- cs231 n 2017 年课表及教学大纲。
- 斯坦福大学 CS231n,2017 年春季,YouTube 播放列表
- 费飞李主页
- 安德烈·卡尔帕西主页
- 贾斯廷·约翰逊主页
- 杨小威主页
- 斯坦福计算机科学课程的笔记和作业,GitHub
- 【t0/cs231 n 次纬度】T1
- convnetjs
摘要
在这篇文章中,你发现了这门课程的一个温和的介绍,你可以用它来用深度学习方法在计算机视觉上获得一个快速的开始。
具体来说,您了解到:
- 课程的分类,包括谁教的,教了多久,涵盖了什么。
- 课程中讲座的细分,包括如果你已经熟悉深度学习要重点关注的三个讲座。
- 对课程的回顾,包括它与同一主题的类似课程的比较。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。