面向计算机视觉的深度学习:1~5(1)

简介: 面向计算机视觉的深度学习:1~5(1

一、入门

计算机视觉是理解或操纵图像和视频的科学。 计算机视觉具有许多应用,包括自动驾驶,工业检查和增强现实。 深度学习在计算机视觉中的使用可以分为多个类别:图像和视频中的分类,检测,分割和生成。 在本书中,您将学习如何为计算机视觉应用训练深度学习模型并将其部署在多个平台上。 我们将在本书中使用 TensorFlow,这是一个用于深入学习的流行 python 库,用于示例。 在本章中,我们将介绍以下主题:

  • 深度学习的基础知识和词汇
  • 深度学习如何满足计算机视觉?
  • 设置将用于本书所涵盖示例的开发环境
  • 体验 TensorFlow 及其强大的工具,例如 TensorBoard 和 TensorFlow Serving

了解深度学习

计算机视觉作为一个领域有着悠久的历史。 随着深度学习的出现,计算机视觉已被证明可用于各种应用。 深度学习是来自人工神经网络ANN)的技术的集合,这是机器学习的一个分支。 人工神经网络以人脑为模型。 有彼此链接的节点,它们彼此传递信息。 在以下各节中,我们将通过了解常用的基本术语来详细讨论深度学习的工作原理。

感知机

人工神经元或感知机接受多个输入并执行加权求和以产生输出。 感知机的权重是在训练过程中确定的,并基于训练数据。 以下是感知机的图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WRb765o6-1681567519349)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/1e292483-bf0f-4474-9ee4-9f18966861b6.png)]

如上图所示,对输入进行加权和求和。 然后,对于二分类问题,该总和然后通过单位步长函数传递。 感知机只能通过从示例中学习权重来学习简单函数。 学习权重的过程称为训练。 可以通过基于梯度的方法对感知机进行训练,这将在后面的部分中进行介绍。 感知机的输出可以通过 activation 函数或 transfer 函数传递,这将在下一部分中进行说明。

激活函数

activation函数使神经网络成为非线性。 激活函数决定是否应触发感知机。 在训练激活期间,函数在调整梯度中起着重要作用。 下一节所示的activation函数(如 Sigmoid)会衰减较大幅度的值。 activation函数的这种非线性行为为学习复杂函数提供了深层网络。 activation的大多数函数是连续和微分函数,但整流单元为 0 除外。输入的每一个小变化,连函数能的输出都会有很小的变化。 微分函数在域中的每个点都有一个导数。

为了训练神经网络,函数必须是可微的。 以下是一些activation函数。

如果您不了解诸如连续性和可微分性之类的术语,请不要担心。 在各章中将变得更加清楚。

Sigmoid

Sigmoid 可以看作是平滑的阶跃函数,因此可以微分。 Sigmoid 可用于将任何值转换为概率,并可用于二分类。 Sigmoid 映射将输入映射到 0 到 1 范围内的值,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wO8dZLOu-1681567519350)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/f171c6d5-67e5-4e9c-a168-be794c8e444b.png)]

相对于XY值的变化将很小,因此,梯度将消失。 经过一番学习之后,变化可能很小。 在下一节中介绍的另一个称为tanh的激活函数是 Sigmoid 曲线的缩放比例版本,避免了梯度消失的问题。

双曲正切函数

双曲正切函数或 tanh 是 Sigmoid 曲线的缩放形式。 像 Sigmoid 一样,它是光滑且可微分的。 tanh将输入映射到 -1 到 1 的值,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tGp85h1l-1681567519351)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/623bcab3-b4f7-4ce7-b817-a3f1bad2944d.png)]

梯度比 S 形更稳定,因此减少了消失的梯度问题。 Sigmoid 和tanh一直在发射,这使 ANN 变得很沉重。 下一节中介绍的整流线性单元ReLU)激活函数通过不触发而避免了这种陷阱。

整流线性单元(ReLU)

ReLu 可以让大量数字通过。 这会使一些神经元陈旧,并且它们不会发射。 这增加了稀疏性,因此很好。 ReLU将输入x映射到max(0, x),即,它们将负输入映射为 0,而正输入无任何变化,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OaNoqJyF-1681567519351)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/f869a450-2d05-4d78-9ad6-8cc941adcfff.png)]

由于 ReLU 不会一直触发,因此可以更快地进行训练。 由于功能简单,因此在计算上最便宜。 选择activation函数在很大程度上取决于应用。 尽管如此,ReLU 在许多问题上都运行良好。 在下一节中,您将学习如何将几个感知机堆叠在一起,这些感知机可以学习比感知机更复杂的函数。

人工神经网络(ANN)

ANN 是感知机函数的集合。 感知机连接形成隐藏的层或单元。 隐藏的单元形成了将低层空间中的输入层映射到输出层的非线性基础,这也称为人工神经网络。 ANN 是从输入到输出的映射。 该图是通过将输入与偏差进行加权相加来计算的。 权重和偏置值以及架构称为model

训练过程确定这些权重和偏置的值。 在训练开始时,使用随机值初始化模型值。 通过使用损失函数将误差与基本事实进行对比来计算误差。 根据计算出的损耗,在每一步调整权重。 如果无法进一步减少误差,则停止训练。 训练过程会在训练过程中学习特征。 这些特征比原始图像更好地表示。 以下是人工神经网络或多层感知机的示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bZj1qeQA-1681567519351)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/386212ca-7e62-482c-b6b3-d0d30426ca19.png)]

x 的多个输入通过感知机的隐藏层传递并求和。 通用逼近定理表明,这样的神经网络可以逼近任何函数。 隐藏层也可以称为密集层。 每个层都可以具有上一节中描述的activation函数之一。 可以根据问题选择隐藏层和感知机的数量。 还有更多的事情可以使此多层感知机适用于多类分类问题。 一个多类别的分类问题试图区分十多个类别。 我们将在以下各节中探讨这些术语。

单热编码

单热编码是在出现分类问题时表示目标变量或类的一种方式。 目标变量可以从字符串标签转换为一键编码的向量。 单热向量在目标类别的索引处填充有1,但在其他所有地方填充有0。 例如,如果目标类别是猫和狗,则可以分别用[1, 0][0, 1]。 对于 1,000 个类别,单热向量的大小为 1,000 整数,全为零,但有一个1。 它不假设目标变量的相似性。 通过在下一节中说明的一键编码和 softmax 的组合,可以在 ANN 中实现多类分类。

Softmax

Softmax 是一种强制神经网络输出 1 之和的方法。因此,softmax函数的输出值可以视为概率分布的一部分。 这在多类分类问题中很有用。 Softmax 是一种activation函数,其特征是输出求和为 1。通过将输出除以所有其他值的总和,可以将输出转换为概率。 欧几里德距离可以在 softmax 概率和一键编码之间进行计算,以进行优化。 但是下一部分将说明的交叉熵是一个更好的成本函数,可以进行优化。

交叉熵

交叉熵比较 softmax 和一键编码输出之间的距离。 交叉熵是一种损失函数,必须将其误差降至最低。 神经网络估计每个类别给定数据的概率。 必须将概率最大化到正确的目标标签。 交叉熵是负对数概率的总和。 对数值用于数值稳定性。 最大化一个函数等同于最小化相同函数的负数。 在下一节中,我们将看到以下正则化方法,以避免 ANN 的过拟合:

  • 丢弃法
  • 批量规范化
  • L1 和 L2 归一化

丢弃法

丢弃法是规整神经网络以避免 ANN 过拟合的有效方法。 在训练期间,丢弃层通过随机删除隐藏的单元来破坏神经网络,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jah9re7t-1681567519352)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/9eae1f1c-0308-4516-9cda-3e9531220150.png)]

请注意如何随机训练神经元。 丢弃也是组合多个神经网络的有效方法。 对于每个训练案例,我们随机选择一些隐藏的单元,以便最终为每个案例使用不同的架构。 这是装袋和模型平均的极端情况。 推断期间不应使用丢弃层,因为没有必要。

批量规范化

批量规范化或批量规范可提高神经网络训练的稳定性和表现。 它将平均值为零且标准差为 1 的层的输出归一化。这减少了过拟合,并使网络训练更快。 这对于训练复杂的神经网络非常有用。

L1 和 L2 正则化

L1 惩罚权重的绝对值,并趋于使权重为零。 L2 惩罚权重的平方值,并且在训练过程中倾向于使权重更小。 两个正则化均假设权重较小的模型更好。

训练神经网络

训练 ANN 非常棘手,因为它包含多个要优化的参数。 权重的更新过程称为反向传播。 最小化误差的过程称为优化。 我们将在下一节中详细介绍这两个方面。

反向传播

反向传播算法通常用于训练人工神经网络。 权重根据计算的误差从后向更新,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sryo3KzC-1681567519352)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/91e3b72c-6258-41b8-a8dc-3a471bd1da38.png)]

在计算了误差之后,可以使用梯度下降来计算权重更新,如下一节中所述。

梯度下降

梯度下降算法执行多维优化。 目标是达到全局最高水平。 梯度下降是许多机器学习模型中使用的一种流行的优化技术。 它用于改善或优化模型预测。 梯度下降的一种实现称为随机梯度下降SGD),在神经网络中正变得越来越流行(在下一节中说明)。 优化涉及计算误差值并更改权重以实现最小误差。 找到最小值的方向是loss函数的梯度的负值。 下图定性显示了梯度下降过程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-stJY8koy-1681567519352)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/13375e63-ff4f-46e6-a64b-4f01435f18e1.png)]

学习速度决定了每个步骤应该多大。 注意,具有非线性激活的 ANN 将具有局部最小值。 SGD 在实践中更好地用于优化非凸成本函数。

随机梯度下降

SGD 与梯度下降相同,区别在于 SGD 每次仅用于部分数据训练。 该参数称为小批量大小。 从理论上讲,甚至可以使用一个示例进行训练。 在实践中,最好尝试各种数字。 在下一部分中,我们将讨论比标准 ANN 在图像数据上更有效的卷积神经网络。

访问这里,可以很好地看到凸面和非凸面的梯度下降情况。

玩转 TensorFlow 游乐场

TensorFlow 游乐场是神经网络的交互式可视化。 访问这里,方法是通过更改参数来查看前面提到的项如何协同工作。 这是操场的屏幕截图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FTv6hlrx-1681567519353)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/2a57f080-1ddb-4c9d-b3d0-201bc792caad.png)]

TensorFlow 游乐场中的仪表板

如前所示,读者可以更改学习率,激活,正则化,隐藏单元和层,以了解其如何影响训练过程。 您可以花费一些时间来调整参数,以直观了解神经网络如何处理各种数据。

卷积神经网络

卷积神经网络CNN)与前面各节中描述的神经网络相似。 CNN 具有权重,偏差和通过非线性激活产生的输出。 规则的神经网络接受输入,并且神经元完全连接到下一层。 同一层中的神经元不共享任何连接。 如果我们对图像使用常规的神经网络,由于神经元数量众多,它们的大小将非常大,从而导致过拟合。 我们不能将其用于图像,因为图像尺寸较大。 增加模型大小,因为它需要大量的神经元。 可以将图像视为具有高度,宽度和深度尺寸的体积。 深度是图像的通道,它是红色,蓝色和绿色。 CNN 的神经元以体积方式排列,以利用体积。 每个层都将输入体积转换为输出体积,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H3DcHbpZ-1681567519353)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/42b70af2-d682-4f56-8b6c-fe90ac4a02c9.jpeg)]

卷积神经网络过滤器通过变换进行编码。 学到的滤镜可以检测图像中的特征或图案。 层越深,图案越抽象。 一些分析表明,这些层具有检测边缘,角和图案的能力。 CNN 层中的可学习参数小于上一节中描述的密集层。

内核是用于对图像进行卷积的参数卷积层。 卷积操作如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z3NAHEvP-1681567519353)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/0b5c0e8a-edbf-42ed-b858-2788b7e281b9.png)]

内核有两个参数,称为步幅和大小。 大小可以是矩形的任何尺寸。 步幅是每次移动的像素数。 长度为 1 的步幅产生几乎相同大小的图像,长度为 2 的步幅产生一半大小。 填充图像将有助于获得相同的输入大小。

最大池

池化层位于卷积层之间。 合并层通过采样减小了跨层图像的大小。 通过在窗口中选择最大值来完成采样。 窗口中的平均池平均值。 池化还可以作为一种正则化技术来避免过拟合。 在特征的所有通道上进行池化。 合并也可以进行各种步骤。

窗口的大小是 CNN 接收场的量度。 下图显示了最大池化的示例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-npTyHXoz-1681567519353)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/9fb61e22-8dbd-46cc-87a2-c325197bf504.png)]

CNN 是任何计算机视觉深度学习模型中最重要的组成部分。 毫不夸张地说,没有 CNN,任何计算机都不可能拥有视觉。 在下一部分中,我们将讨论几个可用于一些应用的高级层。

访问这里,以获取有关 CNN 和最大池操作的出色可视化。

循环神经网络(RNN)

循环神经网络RNN)可以对顺序信息进行建模。 他们不假定数据点密集。 它们从一系列序列数据的先前数据的输出执行相同的任务。 这也可以被视为记忆。 RNN 无法记住更长的序列或更长的时间。 在训练过程中将其展开,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ed6QVs1a-1681567519354)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/74621d85-d8ff-4532-a793-8eda53ef7651.png)]

如上图所示,该步骤每次都展开和训练。 在反向传播期间,梯度会随着时间消失。 为了克服此问题,可以使用较长的短期记忆来记忆较长的时间。

长短期记忆(LSTM)

长短期记忆LSTM)可以存储较长时间的信息,因此,它可以有效地捕获长期效率。 下图说明了如何设计 LSTM 单元:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KBSD6yKU-1681567519354)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/e166af85-c2c6-4046-bf30-4984795eff8f.png)]

LSTM 有几个门:忘记,输入和输出。 忘记门保持信息先前的状态。 输入门使用输入更新当前状态。 输出门决定将信息传递到下一个状态。 忘记和保留重要内容的能力使 LSTM 可以在更长的时间内记住。 您已经学习了将在整本书中使用的深度学习词汇。 在下一节中,我们将了解如何在计算机视觉的背景下使用深度学习。

用于计算机视觉的深度学习

计算机视觉在计算机上实现了人类视觉的特性。 计算机可以是智能手机,无人机,闭路电视,MRI 扫描仪等形式,并带有各种感知传感器。 传感器产生数字形式的图像,必须由计算机解释。 下一部分将说明这种解释或智能的基本构成部分。 使用深度学习技术可以有效解决计算机视觉中出现的各种问题。

分类

图像分类是充满信心地用对象或概念标记整个图像的任务。 这些应用包括给定人脸图像的性别分类,识别宠物的类型,为照片添加标签等。 以下是此类分类任务的输出:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tb3kftVo-1681567519358)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/0ac5cf28-7641-47ed-a19f-af886508aae7.png)]

第 2 章, “图像分类”详细介绍了可用于分类任务的方法,在第 3 章“图像检索”,我们使用分类模型对深度学习模型进行可视化并检索相似的图像。

检测或定位和分割

检测或定位是一项在图像中找到对象并使用边界框定位该对象的任务。 这项任务有许多应用,例如为自动驾驶汽车寻找行人和招牌。 下图是检测的示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ta0PQiZk-1681567519359)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/eebafaa9-de29-4acc-aa17-e39010013809.png)]

分割是进行像素分类的任务。 这样可以很好地分离对象。 这对于处理医学图像和卫星图像很有用。 更多示例和说明可以在第 4 章,对象检测和第 5 章,“图像分割”中找到。

相似性学习

相似性学习是学习两个图像如何相似的过程。 可以基于语义含义在两个图像之间计算分数,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Go0oohJI-1681567519360)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/55f91a2f-3104-4dee-8feb-81aebcea95c3.png)]

从发现相似产品到执行人脸识别,此方法有多种应用。 第 6 章,“相似性学习”处理相似性学习技术。

图片字幕

图像标题是用文本描述图像的任务,如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7TTgu6FV-1681567519360)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/407ec761-30e5-41da-8b72-69b17212196c.png)]

经 Vinyals 等人许可复制。

第 8 章,“图像字幕生成”详细介绍了图像字幕生成。 这是将自然语言处理NLP)和计算机视觉技术相结合的独特情况。

生成模型

生成模型在生成图像时非常有趣。 以下是样式转换应用的示例,其中使用该图像的内容和其他图像的样式生成图像:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zl7qboBR-1681567519360)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/1a581deb-0956-44e2-bf7c-fc63e591160a.jpeg)]

经 Gatys 等人许可复制。

可以出于其他目的生成图像,例如新的训练示例,超分辨率图像等。 第 7 章“生成模型”详细介绍了生成模型。

视频分析

与以前的情况相比,视频分析处理的是整个视频,而不是图像。 它具有多种应用,例如运动跟踪,入侵检测和监视摄像机。 第 9 章“视频分类”处理特定于视频的应用。 时间数据的新维度带来了许多有趣的应用。 在下一节中,我们将看到如何设置开发环境。

开发环境设置

在本节中,我们将设置编程环境,该环境对于遵循本书其余部分中的示例非常有用。 读者可以选择以下操作系统:

  • 开发操作系统OS),例如 Mac,Ubuntu 或 Windows
  • 部署操作系统(例如 Mac,Windows,Android,iO 或 Ubuntu)安装在云平台(例如 Amazon Web ServicesAWS), 谷歌云平台GCP),Azure,Tegra,Raspberry Pi

无论使用哪种平台,本书中开发的所有代码均应运行无任何问题。 在本章中,我们将介绍开发环境的安装过程。 在第 10 章“部署”中,我们将介绍在各种其他环境(例如 AWS,GCP,Azure,Tegra 和 Raspberry Pi)中的部署安装。

硬件和操作系统 - OS

对于开发环境,您需要具有很多计算能力,因为训练在计算上非常昂贵。 Mac 用户相当受限于计算能力。 Windows 和 Ubuntu 用户可以使用更多处理器和通用图形处理单元GP-GPU),来增强其开发环境。 下一节将对此进行说明。

通用图形处理单元 - GP-GPU

GP-GPU 是一种特殊的硬件,可加快训练深度学习模型的训练过程。 NVIDIA 公司提供的 GP-GPU 由于具有完善的软件和社区支持,因此在深度学习训练和部署中非常受欢迎。 读者可以设置带有此类 GP-GPU 的机器以进行更快的训练。 有很多选择,读者可以根据预算选择一个。 选择与 GP-GPU 功率相对应的 RAM,CPU 和硬盘也很重要。 安装硬件后,必须安装以下驱动程序和库。 使用 Mac 或不使用 GP-GPU 的 Windows/Ubuntu 的读者可以跳过安装。

以下是设置环境所需的库:

  • 计算机统一设备架构CUDA
  • CUDA 深度神经网络CUDNN

计算机统一设备架构 - CUDA

CUDA 是 NVIDIA 使用 GPU 的并行特性提供的 API 层。 安装此驱动程序后,还将安装硬件驱动程序。 首先,从 NVIDIA 门户网站下载CUDA

按照页面上的说明进行操作,下载驱动程序,然后按照安装说明进行操作。 这是 Ubuntu CUDA 的屏幕截图和安装说明:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OJxFQ9hd-1681567519360)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/e042367c-385d-481f-a9f0-7b9e64db394f.png)]

这些命令将安装所需的cuda-drivers和其他 CUDA API。

您可以通过在命令提示符下键入nvidia-smi来检查驱动程序是否正确安装。

CUDA 深度神经网络 - CUDNN

CUDNN库为深度学习算法提供了原语。 由于此包由 NVIDIA 提供,因此对其硬件进行了高度优化,并且运行速度更快。 该包提供了几种用于深度学习的标准例程。 著名的深度学习库(例如tensorflowcaffe等)使用这些包。 在下一节中,将提供安装CUDNN的说明。 您可以从 NVIDIA 门户网站下载CUDNN

用户帐户是必需的(免费注册)。

将相关文件复制到CUDA文件夹,使其更快地在 GPU 上运行。 我们不会直接使用CUDACUDNN库。 Tensorflow 使用这些来优化例程在 GP-GPU 上工作。

安装包

训练有素的深度学习模型需要几个库。 我们将安装以下库,并查看在竞争包中选择以下包的原因:

  • Python 和其他依赖项
  • OpenCV
  • TensorFlow
  • Keras

Python

Python 是任何数据科学应用的实际选择。 它拥有最大的社区和库支持生态系统。 用于 Python 的 TensorFlow API 是最完整的,因此,Python 是首选的自然语言。 Python 有两个版本-Python2.x 和 Python3.x。 在本书中,我们将讨论 Python3.x。 这种选择有几个原因:

  • 到 2020 年,Python 2.x 的开发将停止,因此,Python3.x 是 Python 的未来
  • Python 3.x 避免了原始实现中的许多设计缺陷
  • 与普遍的看法相反,Python3.x 具有与 Python 2.x 一样多的数据科学支持库。

在本书中,我们将使用 Python 版本 3。 转到这里,然后根据操作系统下载版本 3。 按照下载链接中给出的步骤安装 Python。 安装 Python 后,必须安装 PIP3,以方便安装 Python 包。 然后通过输入以下命令安装几个 Python 包,以便以后可以安装OpenCVtensorflow

sudo pip3 install numpy scipy  scikit-learn  pillow  h5py

先前安装的包的说明如下:

  • numpy 是高度优化的数值计算包。 它具有强大的 N 维封装数组对象,并且numpy库的矩阵运算针对速度进行了高度优化。 图像可以存储为 3 维numpy对象。
  • scipy 有一些用于科学和工程计算的例程。 在本书的后面,我们将使用一些优化包。
  • scikit-learn 是一个机器学习库,我们将使用其中的许多辅助函数。
  • Ppillow对于图像加载和基本操作很有用。
  • H5py包是 HDF5 二进制数据格式的 Pythonic 接口。 这是存储使用 Keras 训练的模型的格式。

开放式计算机视觉 - OpenCV

OpenCV是著名的计算机视觉库。 该库中有许多可用的图像处理例程,这些例程很有用。 以下是在 Ubuntu 中安装 OpenCV 的步骤。

sudo apt-get install python-opencv

对于其他操作系统,可以在这里找到类似的步骤。 它是跨平台的,针对 CPU 密集型应用进行了优化。 它具有多种编程语言的接口,并且受 Windows,Ubuntu 和 Mac 支持。

TensorFlow 库

tensorflow是一个用于开发和部署深度学习模型的开源库。 TensorFlow 使用计算图进行数据流和数值计算。 换句话说,数据或张量流经图,因此名称为tensorflow。 该图具有可进行任何数值计算的节点,因此适用于深度学习操作。 它为各种平台和硬件提供了一个 API。 TensorFlow 在后端处理扩展和优化的所有复杂性。 它最初是为在 Google 上进行研究而开发的。 它是最著名的深度学习库,拥有大型社区,并提供用于生产中的可视化和部署的工具。

安装 TensorFlow

使用以下命令,使用 PIP3 为 CPU 安装tensorflow

sudo pip3 install tensorflow

如果您使用的是 GPU 硬件,并且已安装CUDACUDNN,请使用以下命令安装tensorflow的 GPU 版本:

sudo pip3 install tensorflow-gpu

现在tensorflow已安装并可以使用。 我们将尝试一些示例以了解 TensorFlow 的工作原理。

打印 Hello,TensorFlow 的 TensorFlow 示例

我们将直接在 Python Shell 中使用 TensorFlow 进行示例。 在此示例中,我们将使用 TensorFlow 打印您好,TensorFlow 。

  1. 通过在命令提示符下键入以下命令,从 shell 调用 Python:
python3
  1. 通过输入以下命令导入tensorflow库:
>>> import tensorflow as tf
  1. 接下来,使用字符串Hello, TensorFlow定义一个常量。 这与通常的 Python 赋值操作不同,因为该值尚未初始化:
>>> hello = tf.constant('Hello, TensorFlow!')
  1. 创建一个会话以初始化计算图,并为该会话命名:
>>> session = tf.Session()

可以使用变量hello作为参数运行会话。

  1. 现在,该图执行并返回打印的特定变量:
>>> print(session.run(hello))

它应该打印以下内容:

Hello, TensorFlow!

让我们再看一个示例,以了解会话和图的工作方式。

访问这里获取本书中所有示例的代码。 该代码将根据章节进行组织。 您可以提出问题并在存储库中获得帮助。

将两个数字相加 的 TensorFlow 示例

这是如何使用 TensorFlow 将两个数字相加的另一个简单示例。

  1. 创建一个 Python 文件并使用以下代码导入tensorflow
import tensorflow as tf

对于所有后面的示例,前面的导入都是必需的。 假定读者已经为所有示例导入了库。 可以通过以下方式定义placeholder。 占位符在分配时不会加载。 在此,将变量定义为类型为float32placeholderplaceholder是一个空声明,并且在运行会话时可以采用值。

  1. 现在我们定义一个placeholder,如以下代码所示:
x = tf.placeholder(tf.float32)
 y = tf.placeholder(tf.float32)
  1. 现在,可以将占位符的求和运算定义为通常的加法运算。 在这里,不执行操作,而只是使用以下代码定义:
z = x + y
  1. 可以如前面的示例所示创建会话。 如下所示定义时,该图即可执行计算:
session = tf.Session()
  1. 以字典格式定义placeholder的值:
values = {x: 5.0, y: 4.0}
  1. 使用变量c和值运行会话。 该图将值提供给适当的占位符,并为变量c取回值:
result = session.run([z], values) print(result)

作为添加结果,该程序应打印[ 9.0 ]。

可以理解,这不是将两个数字相加的最佳方法。 该示例旨在了解 TensorFlow 中如何定义张量和操作。 想象一下使用一万亿个数字并将它们相加会多么困难。 TensorFlow 可以使用相同的 API 轻松实现这种扩展。 在下一节中,我们将看到如何安装和使用 TensorBoard 和 TensorFlow 服务。

TensorBoard

TensorBoard 是一套可视化工具,用于使用 TensorFlow 训练基于深度学习的模型。 可以在 TensorBoard 中可视化以下数据:

  • :计算图,设备位置和张量详细信息
  • 标量:指标,例如损失,迭代精度
  • 图像:用于查看带有相应标签的图像
  • 音频:用于收听训练或生成的音频
  • 分布:用于查看某些标量的分布
  • 直方图:包括权重和偏置的直方图
  • 投影器:帮助可视化 3 维空间中的数据
  • 文本:打印训练文本数据
  • 配置文件:查看用于训练的硬件资源

Tensorboard 与 TensorFlow 一起安装。 转到 python3 提示符并输入以下命令(类似于上一个示例)以开始使用 Tensorboard:

x = tf.placeholder(tf.float32, name='x')
y = tf.placeholder(tf.float32, name='y')
z = tf.add(x, y, name='sum')

请注意,已将参数名称作为占位符和操作的附加参数提供。 这些是我们可视化图时可以看到的名称。 现在我们可以在 TensorBoard 中使用以下命令将图写入特定的文件夹:

session = tf.Session()
summary_writer = tf.summary.FileWriter('/tmp/1', session.graph)

此命令将图写入磁盘到参数中给定的特定文件夹中。 现在可以使用以下命令调用 Tensorboard:

tensorboard --logdir=/tmp/1

可以将任何目录作为logdir选项的参数传递,该选项用于存储文件。 转到浏览器并粘贴以下 URL 以开始可视化以访问 TensorBoard:

http://localhost:6006/

浏览器应显示如下内容:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n1iGq2tL-1681567519361)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/5c0dfa38-1cd4-4e1c-8d90-6e9bbc31129e.png)]

浏览器窗口中的 TensorBoard 可视化

显示加法图,并为占位符指定名称。 单击它们时,我们可以在右侧看到该操作的所有张量细节。 使自己熟悉选项卡和选项。 此窗口有几个部分。 我们将在不同的章节中了解它们。 TensorBoard 是 TensorFlow 中最好的区分工具之一,这使其比其他任何深度学习框架都更好。

TensorFlow Serving 工具

TensorFlow Serving 是 TensorFlow 中的工具,专为灵活的部署环境而开发,可提供高延迟和吞吐量的环境。 使用 TensorFlow 训练的任何深度学习模型都可以与服务一起部署。 通过运行以下命令来安装 Serving:

sudo apt-get install tensorflow-model-server

有关如何使用服务的逐步说明,将在第 3 章,“图像检索”中进行介绍。 请注意,仅在 Ubuntu 中即可轻松安装 Serving; 对于其他操作系统,请参考这里。 下图说明了 TensorFlow Serving 和 TensorFlow 在生产环境中如何交互:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LDv5TRod-1681567519361)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/54fe6552-5ba5-4270-ab85-74a753389c05.png)]

训练过程可以产生许多模型,Serving 会无缝切换它们,而不会造成任何停机。 除了第 3 章,“图像检索”和第 10 章,“部署”之外,以下各章均不需要 TensorFlow Serving。

Keras

Keras是一个用 Python 编写的用于深度学习的开源库。 它提供了一个简单的接口来使用 TensorFlow 作为后端。 Keras 还可以与 Theano,深度学习 4j 或 CNTK 一起用作后端。 Keras 通过专注于友好性,模块化和可扩展性而设计用于轻松快速地进行实验。 它是一个独立的框架,可以在 CPU 和 GPU 之间无缝运行。 Keras 可以单独安装,也可以使用tf.keras API 在 TensorFlow 本身中使用。 在本书中,我们将使用tf.keras API。 我们已经看到了安装开发环境所需的库的步骤。 顺利安装 CUDA,CUDNN,OpenCV,TensorFlow 和 Keras 并对以下章节至关重要。

总结

本章涵盖了深度学习的基础知识。 本章介绍的词汇将在整本书中使用,因此,您可以经常参考本章。 示例还显示了计算机视觉的应用。 还介绍了用于开发环境的各种平台的所有包的安装。

在下一章中,我们将讨论如何在数据集上使用 Keras 和 TensorFlow 训练分类模型。 我们将研究如何使用更大的模型和其他技术(例如增强和微调)来提高准确率。 然后,我们将看到由世界各地的几个人提出的几种先进模型,它们在比赛中达到了最佳准确率。

二、图像分类

图像分类是将整个图像分类为单个标签的任务。 例如,给定图像是狗还是猫,图像分类任务可以将图像标记为狗或猫。 在本章中,我们将了解如何使用 TensorFlow 建立这样的图像分类模型,并学习提高准确率的技术。

我们将在本章介绍以下主题:

  • 在 TensorFlow 中训练 MNIST 模型
  • 在 Keras 中训练 MNIST 模型
  • 其他流行的图像测试数据集
  • 更大的深度学习模型
  • 训练猫与狗的模型
  • 开发实际应用

在 TensorFlow 中训练 MNIST 模型

在本节中,我们将了解混合国家标准技术研究所数据库MNIST)的数据,并建立一个简单的分类模型。 本部分的目的是学习深度学习的通用框架,并将其用于 TensorFlow。 首先,我们将建立一个感知机或逻辑回归模型。 然后,我们将训练 CNN 以获得更高的准确率。 我们还将看到 TensorBoard 如何帮助可视化训练过程并了解参数。

MNIST 数据集

MNIST数据具有从 0 到 9 的手写数字,其中 60,000 张用于训练的图像和 10,000 张用于测试的图像。 该数据库被广泛用于尝试使用最少预处理的算法。 这是一个学习机器学习算法的好而紧凑的数据库。 这是最著名的图像分类问题数据库。 这里显示了一些示例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JUDyVYJ7-1681567519361)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/fe1a0746-bfbb-445f-949c-8787df44e2ec.png)]

从上图中可以看出,这些手写字符有 10 个标签。 将图像标准化为 28 个图像像素乘以 28 个图像像素的尺寸,转换为灰度尺寸,并居中为固定尺寸。 这是一个很小的数据集,可以在上面快速测试算法。 在下一节中,我们将看到如何加载此数据集以在 TensorFlow 中使用。

加载 MNIST 数据

直接从 TensorFlow 加载MNIST数据。 请注意,在加载数据时,我们指定单热编码作为参数。 标签存储为整数,但为了进行训练,应将其加载为一键编码。 从现在开始,假设读者正在使用导入了 TensorFlow tf的编辑器运行代码。 以下是要加载MNIST_data的代码段:

from tensorflow.examples.tutorials.mnist import input_data
mnist_data = input_data.read_data_sets('MNIST_data', one_hot=True)

对于首次运行,将下载数据,并且可能需要一些时间。 从第二次运行开始,将使用缓存的数据。 在下一节中,我们将构建一个感知机来对数字进行分类。

建立一个感知机

感知机是单层神经网络。 本章介绍的概念(例如,完全连接的层,activation函数,随机梯度下降,logits,单热编码,softmax 和交叉熵)在这里将很有用。 您将学习如何在 TensorFlow 中定义神经网络的这些组件,并使用该网络训练MNIST数据。

为输入数据和目标定义占位符

占位符是传递数据的张量。 占位符不是特定值,但将在计算过程中接收输入。 首先声明感知机的输入大小,类数,批量大小以及迭代或批量的总数。 x_input是稍后将在其中输入图像的输入。 y_input是占位符,将在其中提供一键式标签或目标,如下所示:

input_size = 784 no_classes = 10 batch_size = 100 total_batches = 200   x_input = tf.placeholder(tf.float32, shape=[None, input_size])
y_input = tf.placeholder(tf.float32, shape=[None, no_classes])

shape参数中的None表示它可以是任意大小,因为我们尚未定义批量大小。 第二个参数是x_input的张量大小和y_input的类数。 根据占位符的类型,我们以浮点数形式发送了数据。 接下来,我们可以定义感知机。

定义全连接层的变量

让我们通过解释weightsbias等变量来定义一个简单的线性分类器或感知机。 这些变量的值将在计算过程中获悉。 这些也称为模型参数。 权重变量使用具有输入大小和类数形状的正态随机分布进行初始化。 由于图像被整形为单个向量,因此输入大小为784。 类的数量是 10,它等于数据集中的位数。 偏差变量还使用大小等于类数的随机正态分布进行初始化。 weightsbias定义如下:

weights = tf.Variable(tf.random_normal([input_size, no_classes]))
bias = tf.Variable(tf.random_normal([no_classes]))

变量的初始化可以为零,但随机正态分布可提供稳定的训练。 然后对输入进行加权,并加上偏置以产生logits,如下所示:

logits = tf.matmul(x_input, weights) + bias

必须将感知机产生的logits与单热标签y_input进行比较。 正如在第 1 章“入门”中所了解的,最好使用 softmax 和交叉熵来比较logits和单热标签。

TensorFlow 的 tf.nn.softmax_cross_entropy_with_logits API 为我们做到了。 可以通过平均交叉熵来计算损耗。 然后,交叉熵通过tf.train.GradientDescentOptimizer完成的梯度下降优化得到馈送。 优化器接受损失,并以0.5的学习率将其最小化。 接下来显示 softmax,交叉熵,损耗,优化的计算:

softmax_cross_entropy = tf.nn.softmax_cross_entropy_with_logits(
    labels=y_input, logits=logits)
loss_operation = tf.reduce_mean(softmax_cross_entropy)
optimiser = tf.train.GradientDescentOptimizer(
    learning_rate=0.5).minimize(loss_operation)

softmax 和交叉熵是从tf.nn包一起计算的,该包还有其他几种有用的方法。 tf.train有几个优化器,在这里,我们使用原始梯度下降。 您可以访问 TensorFlow API 文档以了解其他可选参数。 到目前为止,已定义了占位符,变量和操作,但尚未填充张量。

阅读 TensorFlow 中提供的优化器列表。 Adam 优化器对于计算机视觉应用特别有用。 它通常会收敛得更快,因此我们不需要定义学习率。 有关优化器的理论总结,请访问这里

用数据训练模型

现在,您已经定义了模型和训练操作。 下一步是开始使用数据训练模型。 在训练过程中,计算梯度并更新权重。 变量尚未初始化。 接下来,启动会话并使用全局变量初始化程序初始化变量:

session = tf.Session()
session.run(tf.global_variables_initializer())

本书中的大多数示例都需要前两行。 假定读者将在需要的地方使用这两行。 现在,该图已准备好填充数据并开始训练。 通过循环,批量读取数据并训练模型。 通过使用所需的张量运行会话来进行模型训练。 为了使图更新权重,必须调用优化器:

for batch_no in range(total_batches):
    mnist_batch = mnist_data.train.next_batch(batch_size)
    _, loss_value = session.run([optimiser, loss_operation], feed_dict={
        x_input: mnist_batch[0],
  y_input: mnist_batch[1]
    })
    print(loss_value)

run方法的第一个参数可以具有一个数组,要求为其提供值的输出。 我们通过损失是因为打印损失会告诉我们模型是否正在训练中。 随着我们将损失降至最低,预计损失将减少。 feed_dict是一个 Python 字典,用于直接将输入和目标标签提供给占位符。 一旦该循环结束,损耗通常应低于 0.46。 接下来,我们可以通过计算精度来评估模型的工作效果,如下所示:

predictions = tf.argmax(logits, 1)
correct_predictions = tf.equal(predictions, tf.argmax(y_input, 1))
accuracy_operation = tf.reduce_mean(tf.cast(correct_predictions, 
                                            tf.float32))
test_images, test_labels = mnist_data.test.images, mnist_data.test.labels
accuracy_value = session.run(accuracy_operation, feed_dict={
    x_input: test_images,
  y_input: test_labels
})
print('Accuracy : ', accuracy_value)
session.close()

该预测应该是最大激活的索引。 应该将其与 MNIST 标签上的基本事实进行比较,以进行正确的预测。 使用正确预测的平均值计算准确率。 可以通过将测试数据作为提要字典运行会话来评估数据的准确率。 当整个程序运行时,最终应产生 90% 左右的精度。 如果没有用于训练和测试的更简单的 API,该模型的定义似乎太明确了。 此基本定义水平为 TensorFlow 赋予了表达能力。 在下一部分中,我们将看到更高级别的 API。 感知机获得的精度不是很高,在下一节中,我们将使用具有卷积层的更深的网络来提高精度。

建立多层卷积网络

在本节中,我们将看到如何在 TensorFlow 中创建多层卷积网络,并观察更深的网络如何提高分类准确率。 我们将使用 TensorFlow 层的 API 定义层,而不是从头开始定义它们。 最佳实践方法已根植于这些方法中。 可以从上一节开始导入库,数据集和占位符。 这次,我们将使用 TensorBoard 可视化训练过程。 为了可视化变量的统计信息,必须将变量统计信息的值添加到tf.summary中。

摘要将被写入 TensorBoard 可以解释的文件夹中。 我们定义一个函数来编写摘要,以便可以使用 TensorBoard 可视化它们:

def add_variable_summary(tf_variable, summary_name):
  with tf.name_scope(summary_name + '_summary'):
    mean = tf.reduce_mean(tf_variable)
    tf.summary.scalar('Mean', mean)
    with tf.name_scope('standard_deviation'):
        standard_deviation = tf.sqrt(tf.reduce_mean(
            tf.square(tf_variable - mean)))
    tf.summary.scalar('StandardDeviation', standard_deviation)
    tf.summary.scalar('Maximum', tf.reduce_max(tf_variable))
    tf.summary.scalar('Minimum', tf.reduce_min(tf_variable))
    tf.summary.histogram('Histogram', tf_variable)

变量summary函数写入变量的摘要。 摘要中添加了五个统计量:平均值,标准差,最大值,最小值和直方图。 汇总可以是scalarhistogram。 当记录多个变量时,我们将看到如何在 TensorBoard 中可视化这些值。 与以前的模型不同,我们将MNIST数据的大小调整为一个正方形,并像二维图像一样使用它。 以下是将图像整形为 28 个图像像素乘 28 个图像像素的命令:

x_input_reshape = tf.reshape(x_input, [-1, 28, 28, 1], 
    name='input_reshape')

尺寸-1表示批量大小可以是任何数字。 请注意,有一个名为name的自变量会在 TensorBoard 图形中反映出来,以便于理解。 我们将定义一个 2D 卷积层,其中定义了输入,过滤器,内核和激活。 可以在任何地方调用此方法以获取更多示例,并且在激活函数必须具有整流线性单元ReLU)的情况下很有用。 convolution函数层定义如下:

def convolution_layer(input_layer, filters, kernel_size=[3, 3],
  activation=tf.nn.relu):
    layer = tf.layers.conv2d(
        inputs=input_layer,
  filters=filters,
  kernel_size=kernel_size,
  activation=activation,
  )
    add_variable_summary(layer, 'convolution')
    return layer

kernel_sizeactivation的默认参数。 汇总将添加到函数中的层,然后返回该层。 每当调用该函数时,都必须将input_layer作为参数传递。 这个定义将使我们的其他代码变得简单而小巧。 以非常相似的方式,我们将为pooling_layer定义一个函数,如下所示:

def pooling_layer(input_layer, pool_size=[2, 2], strides=2):
    layer = tf.layers.max_pooling2d(
        inputs=input_layer,
  pool_size=pool_size,
  strides=strides
    )
    add_variable_summary(layer, 'pooling')
    return layer

该层的pool_sizestrides的默认参数分别为[2, 2]2。 这些参数通常工作良好,但可以在必要时进行更改。 也为该层添加了摘要。 接下来,我们将定义一个密集层,如下所示:

def dense_layer(input_layer, units, activation=tf.nn.relu):
    layer = tf.layers.dense(
        inputs=input_layer,
  units=units,
  activation=activation
    )
    add_variable_summary(layer, 'dense')
    return layer

面向计算机视觉的深度学习:1~5(2)https://developer.aliyun.com/article/1426859

相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
3月前
|
机器学习/深度学习 算法 数据可视化
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)-2
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)
100 0
|
3月前
|
机器学习/深度学习 Ubuntu Linux
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)-1
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)
56 1
|
4月前
|
机器学习/深度学习 人工智能 监控
探索深度学习在计算机视觉领域的应用
计算机视觉是人工智能领域的重要分支之一,而深度学习技术在这个领域中的应用已经成为了一个热门话题。深度学习的出现,不仅使得计算机视觉的准确性得到了极大的提升,还为我们提供了更多的可能性。本文将探讨深度学习技术在计算机视觉领域中的应用,并讨论其未来的发展前景。
32 0
|
4月前
|
机器学习/深度学习 人工智能 算法
深度学习引领计算机视觉革命
随着深度学习技术的快速发展,计算机视觉领域迎来了一场革命。本文将探讨深度学习在计算机视觉中的应用,包括图像分类、目标检测、图像生成等方面。通过深度学习的强大能力,计算机视觉正在实现更高精度、更广泛的应用,为人们的生活带来了巨大的影响。
|
4月前
|
机器学习/深度学习 算法 TensorFlow
面向计算机视觉的深度学习:6~10
面向计算机视觉的深度学习:6~10
123 0
|
4月前
|
机器学习/深度学习 算法 TensorFlow
面向计算机视觉的深度学习:1~5(4)
面向计算机视觉的深度学习:1~5(4
61 0
|
4月前
|
机器学习/深度学习 数据可视化 算法
面向计算机视觉的深度学习:1~5(3)
面向计算机视觉的深度学习:1~5(3
65 0
|
4月前
|
机器学习/深度学习 数据可视化 API
面向计算机视觉的深度学习:1~5(2)
面向计算机视觉的深度学习:1~5(2
95 0
|
4月前
|
机器学习/深度学习 编解码 监控
深度学习掀起计算机视觉革命
计算机视觉是一门涵盖了图像处理、模式识别、机器学习等多个领域的交叉学科。近年来,随着深度学习技术的发展,计算机视觉得到了飞速的发展,取得了令人瞩目的成果。本文将探讨深度学习在计算机视觉中的应用,以及它所带来的变革。
|
9月前
|
机器学习/深度学习 自然语言处理 算法
深度学习在计算机视觉和自然语言处理中的应用
深度学习在计算机视觉和自然语言处理领域的应用为我们带来了更多可能性,不断推动着人工智能技术的发展。无论是从理论还是实际应用来看,深度学习都在为计算机视觉和自然语言处理领域的发展注入了无限的活力。随着技术的不断创新,我们有理由相信,深度学习将在未来继续刷新我们的认知和想象。
145 0
深度学习在计算机视觉和自然语言处理中的应用