美文网首页
【征文精选】深度卷积网络通俗介绍(PyTorch)

【征文精选】深度卷积网络通俗介绍(PyTorch)

作者: AI研习社 | 来源:发表于2020-06-22 15:46 被阅读0次

    这篇文章是 medium 上《Deep Learning 入门指南》系列中的一部分。我打算逐步去完善这个系列的内容。目标受众是有基本编程能力的新手,当然最好是会 Python。

    前提

    这篇文章假设您已对 Deep Neural Networks(也称为前馈神经网络)有基本的了解。上一篇文章《Deep Neural Networks 入门指南》中已经详细介绍了此内容。强烈建议您阅读上一篇文章,以更好地理解本文的内容。

    序幕

    随着

    深度学习

    的到来,作为一个领域,“计算机视觉”已发展到了新的高度。帮助机器以更直观的方式理解图像细节的能力(而非从孤立的像素值出发或者借助于少量手工设计的特征),带来了该领域的研究范式的转变。如今,我们的日常生活、商业和企业、以及工业技术产品中都使用了各种尖端的计算机视觉应用程序。我们在日常生活中已经从计算机视觉领域中深度学习最新进展中获得了巨大的好处。您可能并没有意识到在某些产品中计算机视觉领域的应用程序的细节。有几个值得注意的例子:特斯拉的自动驾驶模式(auto-pilot),iPhone 的面部识别解锁(face-id)、Animoji 和高级相机功能,您智能手机相机的背景模糊效果(bokeh effect 或者 portrait mode),Snapchat 和 Facebook Messenger 的滤镜等等。

    计算机视觉领域的基本想法始于一个非常简单的问题,即确定图像中存在什么东西。事实证明,尽管,我们人类处理这一点非常容易,但该问题是一项极为艰巨的任务。

    我们可以使用像素值组成的三维矩阵这样的数字形式来表示图像(长 ×宽,并包含 R、G、B 三个通道)。从这个三维矩阵中提取信息并不是那么简单。

    让我们简单回顾下历史:

    传统的计算机视觉解决方案

    在早些时候,当使用机器学习的时候,计算机视觉问题取得了相当大的成功。这些问题主要通过使用手工设计的特征和传统的机器学习算法(例如 SVM,即支持向量机)解决。“手工设计的特征”是使用其他各种算法得出的图像属性。这类特征的一个常见示例是边和角的存在情况。基础的边缘检测器算法是通过寻找图像强度突然变化的区域(即与附近像素值存在巨大差异)来工作。一些算法的组合可以得到几个这样的基本属性和一些更复杂的特征,然后结果被送到一个有监督的机器学习算法(a supervised ML algorithm)中。

    这种方法虽然有效,结果却不是很令人鼓舞。首先,手工设计的特征所需的工作量是压倒性的;此外,它需要大量的领域知识,并且是非常特定于用例的。例如,为检测 X 射线图像中的骨折所创建的手工设计特征,可能无法用于识别写在快递包裹上的名字。

    图 1——使用机器学习的传统计算机视觉解决方案示意图

    为了减少手工设计特征的工作量,如果我们考虑以表格形式表示图像,即将每个像素值转换为一个特征,结果将非常令人失望。网络/机器学习算法几乎没有捕获到有关图像的任何信息,因此导致性能不佳。

    图 2——将图像为机器学习解决方案展平为表格数据示意图

    从以上的问题空间( problem-space)中,我们可以推断出一个重要的细节——图像特征提取是不可避免的,但很难解决。

    以下是一些示例,可以帮助您了解为什么计算机视觉任务难以解决。为了简单起见,让我们假设从图像中预测猫的问题是一个二值问题。

    请参考下面展示的两个图像。根据像素值,这两张图像在数字格式上将具有完全不同的表示形式。由于像素值仅表示每个像素应输出的颜色,因此基本表示(underlying representation)的语义含义将不会有任何直观的意义。

    同样的,在图片中,猫也可能和背景差异很小。看看下面的图片。传统的特征大多会产生没有意义的结果。因此,手工设计的特征在这里将不会太有效。

    Picture Credits — MIKHAIL VASILYEV, KiVEN Zhao,Hannah Troupe @ Unsplash.com

    此外,人们可能会以完全不同的方式为一只猫咪拍照,这使得识别的过程更加困难。猫这些不同的姿势也只是其中的一些。

    Picture Credits —Marko Bla ž evi ć, Timo Volz, Willian Justen de Vasconcellos @ Unsplash.com

    当将这些问题外推到代表更一般的用例时,比如在图像中检测多个对象,就会成倍地增加复杂性。

    显然,像素的表格表示,或者开发检测特定特征的手工设计的特征,亦或者将两者结合起来,并不是解决计算机视觉问题的最佳方法。

    那么,解决计算机视觉问题的更好方法是什么呢?

    从历史上看,我们发现手工设计的功能虽然费劲,但确实可以在一定程度上解决问题。但是此过程将非常昂贵,并且需要大量领域知识来解决特定问题。

    如果我们可以自动进行特征提取怎么办?

    幸运的是,这是有可能的,它最终使我们讨论的话题“卷积神经网络”(CNN)引起了人们的关注。CNN 通过使用通用、可扩展且可持续的方式提供了一种解决计算机视觉问题的高级方法,该方法可以在没有域先验知识的情况下跨域应用。有了足够的训练和数据,网络将学会自我提取强大的特征,因此不再需要手工设计特征了。

    深度卷积神经网络的想法最初由 Hinton,Krizevsky,Sutskever 发布的,并在当时用于 ImageNet 分类挑战,实现了最先进的性能。然后,这项研究彻底改变了计算机视觉领域。您可以从原始论文中了解更多内容。

    深入了解深度卷积神经网络

    CNN 的通用架构如下所示。目前细节可能有点抽象,但是稍等片刻,我们很快就会分别了解每个组件的细节。该架构中的特征提取组件将是“卷积 + 池化”的组合。您可能已经注意到该组件是重复使用的,并且在大多数现代架构中,您将看到该组件在一层中重复多次。这些特征提取器,首先提取低级特征(例如边缘,线条),然后是中级特征(例如形状)或者是多个低级特征的组合,并且最后会获得高级特征(例如在检测猫的例子中,可能会是耳朵、鼻子、眼睛等等)。最后,这些层(的特征)被展平并且连接到输出层。输出层使用了激活操作(类似于前馈神经网络)。

    图 3——卷积神经网络示意图

    首先,让我们从基础开始

    我们先花一点时间来了解人脑通常如何通过视觉识别物体。我们的大脑从视网膜接收有关从外部世界感知到的视觉的信号,这一步骤非常简单。首先,大脑对边缘进行检测,然后通过检测到的边缘来进一步检测曲线、以及更复杂的图案如形状。从边缘到线条、曲线、复杂形状甚至更复杂形状的神经活动的层次编排,最终有助于识别特定对象。当然,这只是人脑对视觉进行处理以及同时进行更复杂的操作的一个高度简化的过程,

    类似地,在卷积神经网络中,我们在浅层进行特征学习时学到了非常基本的特征。“深度卷积神经网络”中的“深度”是指网络中的层数。常规卷积神经网络中通常有 5–10 个甚至更多的特征学习层。前沿应用中使用的现代体系结构的网络深度超过 50-100 层。卷积神经网络的工作与人脑在通过视觉皮层识别视觉组件方面的简化后的工作非常相似。

    让我们来了解一下 CNN 组件的具体细节

    我们首先要了解什么是卷积。
    “卷积”是信号处理领域中的一种操作;在深度学习领域,它基本上是通过在图像(一个矩阵)上沿着宽和高滑动内核或过滤器(一个较小的矩阵),对原图中滑动到的像素和内核执行矩阵乘法。下面的动画演示了将[3x3]过滤器/内核在[5x5]图像上进行卷积的给 u 欧城。卷积运算的结果是尺寸为[3x3]的较小图像。

    本质上,这种矩阵乘法是特征提取的基础。在内核的值正确时,我们可以从图像中提取显著的特征。下面说明在实际图像上执行此操作的示例。我们可以看到,使用单位矩阵作为内核时,原始图像保持不变。但是,当我们使用不同的内核时,可以看到与使用其他边缘检测器/平滑/锐化/等其他图像处理技术类似的效果。

    这就完成了第一步,同一组件中的下一部分是池化。池化层有助于减小图像表示的空间大小,从而减少网络中参数的数量和计算量。通过对定义的内核尺寸使用求最大值来执行此操作。下图是一个简单的池化操作示例。对大小为[20 x 20]的卷积(另一个矩阵)输出,选定内核尺寸为[10 x 10]、执行池化操作。最终输出结果是[2 x 2]矩阵。

    我们使用卷积层和池化层(通常是最大池化)的组合,创建了 CNN 的基本构件。执行卷积和池化操作可以减少原始输入的大小,具体减小的程度取决于卷积核和池化大小。当我们对输入的图像使用 1 个内核进行卷积时,就会得到一个特征图。在 CNN 中,通常在一个卷积单元中使用多个卷积核。下图突出了卷积过程中从 n 个卷积核中提取的特征图的过程。

    多次重复这个过程,我们可以得到更深的卷积神经网络。每一层都从上一层提取特征。这些层的分层组织有助于逐步学习特征,如从小的边缘到由低级特征创建的更复杂的特征,再到高级特征,这些特征将捕获足够的信息,从而使网络能够准确地预测。
    最后一个卷积层连接到一个全连接层,该层用于应用相关的激活函数来预测结果;对于二元结果,我们使用 sigmoid 和或 softmax 激活函数来预测非二元结果。

    所讨论的整个架构可以简化为下图——

    到目前为止,我们忽略了复杂的 CNN 架构中的几个重要方面。但这是为了让事情简单化,来帮助你了解 CNN 中基本构件的基本概念。

    另外几个重要的关键概念是:

    步长--简单来说,  步长可以定义为过滤器的移动量。当我们讨论过滤器在输入图像上滑动时,我们假设运动只是在预定方向上移动 1 个单位。不过,我们可以来控制滑动运动的步长(不过常见的是用 1)。根据用例的需要,我们可以选择一个比较合适的步长。较大的步长往往有助于减少计算量,对特征的泛化学习等。

    填充--我们还看到,与输入图像的大小相比,应用卷积降低了特征图的大小。零填充是应用大于 1x1 的滤波器后控制尺寸收缩的通用方法,避免边界的信息损失。

    1.填充时没有任何步长(输入蓝色,输出绿色)

    Source and Credits -https://github.com/vdumoulin/conv_arithmetic

    2.零填充但是有步长(输入蓝色,输出绿色)

    Source and Credits — https://github.com/vdumoulin/conv_arithmetic

    其他几个我们到现在还没有接触到的重要内容是 Batch-Normalization 层和 Dropout 层。两者都是 CNN 中相关的重要内容。如进,我们大多会把卷积单元定义为(卷积 + 最大池化 + 批归一化)的组合,而不仅仅只有前两者。批归一化是一种技术,通过对每个批的输入进行标准化,帮助轻松训练非常深的神经网络。标准化的输入有助于稳定学习过程,从而大幅减少训练深度网络所需的训练纪元数。

    Dropout 则是一种正则化技术,对减少过拟合和泛化帮助最大。

    连接点

    现在我们已经对卷积神经网络内的基本构件有了大致的理解,我想你关于细枝末节可能还有一些问题。贯穿你的大脑的最重要的问题可能是 "我们如何决定使用什么过滤器","使用多少过滤器?"等等。

    我们来逐一解决这些问题。

    我们如何决定使用什么过滤器?

    这个问题的答案很简单。我们设置的过滤器的随机值是从正态分布或其他分布中抽取的。这个方法可能有点混乱,难以解释,但效果很好。在训练网络的过程中,会逐渐学到有助于提取准确预测标签所需的最多信息的最优过滤器。这就是神奇的地方,在技术上我们消除了手工特征的过程。在给定足够的训练轮数和数据的情况下,网络负责制作合适的过滤器,来提取最佳特征。

    我们在每个卷积单元中使用多少个滤波器?

    不存在一个标准的数量。过滤器的大小和数量是可以调整的超参数。一般的经验法则是使用尺寸为奇数的过滤器,比如 3x3、5x5 或 7x7。另外,与大过滤器相比,大多首选小过滤器,但这也有一个权衡,可以通过经验验证来解决。

    网络是如何学习的?

    学习过程类似于我们在之前的博客中研究的前馈神经网络。我们利用网络的反向传播技术来更新过滤器中的权重,从而学习图像中的底层特征。学习过程帮助网络发现最优的过滤器,它能最好地从输入图像中提取最多的信息。

    上面的图片是简单的 2D,大部分图片都是 3D 的,对于 3D 的图片,网络是怎么操作的呢?

    为了简洁,插图使用了二维图片。我们使用的大多数图像是三维的(RGB)颜色通道。在这种情况下,除了卷积核的尺寸,一切都保持不变。卷积核将会是一个三维内核,其中第三维为通道数。比如说,输入图像中包含 3 个颜色通道(红、绿、蓝),则卷积核尺寸为 5x5x3。

    卷积神经网络和深度卷积神经网络的区别是什么?

    它们都是一样的,这里的深度是指网路架构的层数。现代大多数 CNN 架构的深度为 30-100 层。

    我们是否需要一个 GPU 来训练 CNN?

    虽然没有规定,但是我们建议使用 GPU。利用 GPU 几乎可以使训练神经网络的速度提高 50 倍。另外,Kaggle 和 Google Colab 平台还免费提供了一个基于 GPU 的环境(每周有使用上限。

    好了,基本内容已经结束;我们看一个实际的例子

    让我们举一个实际的例子,演示如何使用 PyTorch 构建 ConvNet。

    我们将根据上面的内容回顾我们接触了的所有主题。

    首先,让我们导入所有必要的包。我们将导入必要的实用工具、神经网络核心模块以及少量来自于 Scikit-learn 的额外模块,以评估网络性能。

    图 6——上面代码片段的输出

    现在,我们已经加载了数据集,让我们将其转换为 PyTorch 适用的抽象。

    #Covert Train Images from pandas/numpy to tensor 

    and

     normalize the values    train_images_tensor = torch.tensor(train_images)/

    255.0

        train_images_tensor = train_images_tensor.view(

    -1

    ,

    1

    ,

    28

    ,

    28

    )    train_labels_tensor = torch.tensor(train_labels)    #Create a train TensorDataset    train_tensor = TensorDataset(train_images_tensor, train_labels_tensor)    #Covert Validation Images from pandas/numpy to tensor 

    and

     normalize the values    val_images_tensor = torch.tensor(val_images)/

    255.0

        val_images_tensor = val_images_tensor.view(

    -1

    ,

    1

    ,

    28

    ,

    28

    )    val_labels_tensor = torch.tensor(val_labels)    #Create a Validation TensorDataset    val_tensor = TensorDataset(val_images_tensor, val_labels_tensor)    print(

    "Train Labels Shape:"

    ,train_labels_tensor.shape)    print(

    "Train Images Shape:"

    ,train_images_tensor.shape)    print(

    "Validation Labels Shape:"

    ,val_labels_tensor.shape)    print(

    "Validation Images Shape:"

    ,val_images_tensor.shape)    #Load Train 

    and

     Validation TensorDatasets into the data generator 

    for

     Training iterations    train_loader = DataLoader(train_tensor, batch_size=

    64

    , num_workers=

    2

    , shuffle=True)    val_loader = DataLoader(val_tensor, batch_size=

    64

    , num_workers=

    2

    , shuffle=True)

    图 7——以上代码片段的输出

    现在,我们将定义 CNN 的结构,并定义其他函数。这些函数将有助于我们评估和生成预测。

    图 8——以上代码片段的输出

    最后,让我们训练模型。

    我们现在有了一个训练了 5 个周期的简单模型。对于大多数情况,您需要超过 30 个周期才能具有出色的性能。现在,让我们在验证数据集上计算准确率并绘制混淆矩阵。

    #

    Make Predictions on Validation Dataset    actual, predicted = make_predictions(val_loader)    actual,predicted = np.array(actual).reshape(-1,1),np.array(predicted).reshape(-1,1)    

    print

    (

    "Validation Accuracy-"

    ,round(accuracy_score(actual,predicted),4)*100)    

    print

    (

    "\n Confusion Matrix\n"

    ,confusion_matrix(actual,predicted))

    至此,对这个沉重主题的简短介绍就结束了。希望你喜欢。另外,我建议使用这个神奇的工具来理解每层如何为不同的输入图像生成滤波器和特征图。

    Tool - Visualize CNN in action

    您可以从我的 Git 仓库中访问和下载整个 notebook 文件——PyTorchExamples

    总结思考

    这篇文章的目的是用一种非常简单的语言让初学者轻松了解这一主题。保持数学的抽象化,并将重点从纯粹的函数方法转移到在现代企业项目中利用深度卷积神经网络上。

    在下一篇文章中,我将介绍“递归神经网络入门指南”,示例也将使用 PyTorch 展示。

    原文链接:https://www.yanxishe.com/TextTranslation/2579
    选题由雷锋字幕组提供

     本文为雷锋字幕组“触摸世界前沿科技 | 翻译征文 ”活动收录稿件

    相关文章

      网友评论

          本文标题:【征文精选】深度卷积网络通俗介绍(PyTorch)

          本文链接:https://www.haomeiwen.com/subject/itaxfktx.html