TensorFlow 深度学习第二版:1~5(1)

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: TensorFlow 深度学习第二版:1~5

一、人工神经网络

人工神经网络利用了 DL 的概念 。它们是人类神经系统的抽象表示,其中包含一组神经元,这些神经元通过称为轴突的连接相互通信。

Warren McCulloch 和 Walter Pitts 在 1943 年根据神经活动的计算模型提出了第一个人工神经元模型。这个模型之后是 John von Neumann,Marvin Minsky,Frank Rosenblatt(所谓的感知器)和其他许多人提出的另一个模型。

生物神经元

看一下大脑的架构灵感。大脑中的神经元称为生物神经元。它们是看起来不寻常的细胞,主要存在于动物大脑中,由皮质组成。皮质本身由细胞体组成,细胞体包含细胞核和细胞的大部分复杂成分。有许多称为树突的分支延伸,加上一个称为轴突的非常长的延伸。

在它的极端附近,轴突分裂成许多分支称为终树突,并且在这些分支的顶部是称为突触末端(或简单的突触)的微小结构,连接到其他神经元的树突。生物神经元接收称为来自其他神经元的信号的短电脉冲,作为回应,它们发出自己的信号:

图 7:生物神经元的工作原理。

在生物学中,神经元由以下组成:

  • 细胞体或体细胞
  • 一个或多个树突,其职责是接收来自其他神经元的信号
  • 轴突,反过来将同一神经元产生的信号传递给其他连接的神经元

神经元的活动在发送/接收来自其他神经元的信号(活动状态)和休息(非活动状态)之间交替。从一个相到另一个相的转变是由外部刺激引起的,由树枝状晶体拾取的信号表示。每个信号具有兴奋或抑制作用,在概念上由与刺激相关的权重表示。

处于空闲状态的神经元累积它收到的所有信号,直到达到某个激活阈值。

人工神经元

基于生物神经元的概念,出现了人工神经元的术语和思想,它们已被用于构建基于 DL 的预测分析的智能机器。这是启发人工神经网络的关键理念。与生物神经元类似,人工神经元由以下部分组成:

  • 一个或多个传入连接,其任务是从其他神经元收集数字信号:为每个连接分配一个权重,用于考虑发送的每个信号
  • 一个或多个输出连接,将信号传递给其他神经元
  • 激活函数,基于一些信号确定输出信号的数值,信号从和其他神经元的输入连接接受,并从权重和神经元本身的激活阈值中适当地收集,权重与每个接收信号相关:

    图 8:人工神经元模型。

通过将激活函数(也称为传递函数)应用于输入的加权和来计算输出,即神经元传输的信号。这些函数的动态范围介于 -1 和 1 之间,或介于 0 和 1 之间。许多激活函数在复杂性和输出方面有所不同。在这里,我们简要介绍三种最简单的形式:

  • 阶跃函数:一旦我们确定阈值x(例如,x = 10),如果输入之和高于阈值,该函数将返回 1,否则则返回 0。
  • 线性组合:不管理阈值,而是从默认值中减去输入值的加权和。我们将得到二元结果,该结果将由减法的正(+b)或负(-b)输出表示。
  • Sigmoid:这会产生 Sigmoid 曲线,这是一条具有 S 趋势的曲线。通常,sigmoid 函数指的是逻辑函数的特殊情况。

从第一个人工神经元原型制作中使用的最简单的形式,我们转向更复杂的形式,可以更好地表征神经元的功能:

  • 双曲正切函数
  • 径向基函数
  • 圆锥截面函数
  • Softmax 函数

    图 9:最常用的人工神经元模型传递函数。(a)阶梯函数(b)线性函数(c)sigmoid 函数,计算值介于 0 和 1 之间(d)sigmoid 函数,计算值介于 -1 和 1 之间。

选择适当的激活函数(也是权重初始化)是使网络发挥最佳表现并获得良好训练的关键。这些主题正在进行大量研究,如果训练阶段正确进行,研究表明在产出质量方面存在微小差异。

注意

在神经网络领域没有经验法则。这一切都取决于您的数据以及在通过激活函数后希望数据转换的形式。如果要选择特定的激活函数,则需要研究函数的图形,以查看结果如何根据给定的值进行更改。

ANN 如何学习?

神经网络的学习过程被配置为权重优化的迭代过程,因此是监督类型。由于网络在属于训练集的一组示例上的表现(即,您知道示例所属的类的集合),因此修改权重。

目的是最小化损失函数,其表示网络行为偏离期望行为的程度。然后在由除了训练集中的对象之外的对象(例如,图像分类问题中的图像)组成的测试集上验证网络的表现。

人工神经网络和反向传播算法

常用的监督学习算法是反向传播算法。训练程序的基本步骤如下:

  1. 用随机权重初始化网络
  2. 对于所有训练案例,请按照下列步骤操作:
  • 正向传播:计算网络的误差,即所需输出与实际输出之间的差值
  • 向后传递:对于所有层,从输出层回到输入层:
    i:使用正确的输入显示网络层的输出(误差函数)。
    ii:调整当前层中的权重以最小化误差函数。这是反向传播的优化步骤。

当验证集上的误差开始增加时,训练过程结束,因为这可能标志着阶段过拟合的开始,即网络倾向于以牺牲训练数据为代价来内插训练数据的阶段。普遍性。

权重优化

因此, 优化权重的有效算法的可用性构成了构建神经网络的必要工具。该问题可以通过称为梯度下降(GD)的迭代数值技术来解决。该技术根据以下算法工作:

  1. 随机选择模型参数的初始值
  2. 根据模型的每个参数计算误差函数的梯度 G.
  3. 更改模型的参数,使它们朝着减小误差的方向移动,即沿 -G 方向移动
  4. 重复步骤 2 和 3,直到 G 的值接近零

误差函数 E 的梯度(G)提供了误差函数与当前值具有更陡斜率的方向;所以为了减少 E,我们必须在相反的方向上做一些小步骤,-G。

通过以迭代方式多次重复此操作,我们向下移动到 E 的最小值,以达到G = 0的点,从而无法进一步进展:

图 10:搜索误差函数 E 的最小值。我们沿着函数 E 的梯度 G 最小的方向移动。

随机梯度下降

在 GD 优化中,我们基于完整的训练集计算成本梯度,因此我们有时也将其称为批量 GD。在非常大的数据集的情况下,使用 GD 可能非常昂贵,因为我们在训练集上只进行一次传递。训练集越大,我们的算法更新权重的速度就越慢,并且在收敛到全局成本最小值之前可能需要的时间越长。

最快的梯度下降方法是随机梯度下降(SGD),因此,它被广泛应用于深度神经网络。在 SGD 中,我们仅使用来自训练集的一个训练样本来对特定迭代中的参数进行更新。

这里,术语随机来自这样的事实:基于单个训练样本的梯度是真实成本梯度的随机近似。由于其随机性,通向全局最小成本的路径并不像 GD 那样直接,但如果我们可视化 2D 空间中的成本表面,则可能会出现锯齿形:

图 11:GD 与 SGD:梯度下降(左图)确保权重中的每次更新都在正确的方向上完成:最小化成本函数的方向。随着数据集大小的增长以及每个步骤中更复杂的计算,SGD(右图)在这些情况下是首选。这里,在处理每个样本时完成权重的更新,因此,后续计算已经使用了改进的权重。尽管如此,这个原因导致了在最小化误差函数方面的一些误导。

神经网络架构

我们连接节点的方式和存在的层数(即输入和输出之间的节点级别以及每层神经元的数量)定义了神经网络的架构。

神经网络中存在各种类型的架构。我们可以将 DL 架构,分为四组:深度神经网络(DNN),卷积神经网络(CNN),循环神经网络(RNN)和紧急架构(EA)。本章的以下部分将简要介绍这些架构。更多详细分析,以及应用实例,将成为本书后续章节的主题。

深度神经网络(DNN)

DNN 是人工神经网络,它们强烈地面向 DL。在正常分析程序不适用的情况下,由于要处理的数据的复杂性,因此这种网络是一种极好的建模工具。 DNN 是与我们讨论过的神经网络非常相似的神经网络,但它们必须实现更复杂的模型(更多的神经元,隐藏层和连接),尽管它们遵循适用于所有 ML 问题的学习原则(例如作为监督学习)。每层中的计算将下面层中的表示转换为稍微更抽象的表示。

我们将使用术语 DNN 将具体指代多层感知器(MLP),堆叠自编码器(SAE)和深度信任网络(DBN)。 SAE 和 DBN 使用自编码器(AEs)和 RBM 作为架构的块。它们与 MLP 之间的主要区别在于,训练分两个阶段执行:无监督的预训练和监督微调:

图 12:分别使用 AE 和 RBM 的 SAE 和 DBN。

在无监督预训练中,如上图所示,这些层按顺序堆叠并以分层方式进行训练,如使用未标记数据的 AE 或 RBM。然后,在有监督的微调中,堆叠输出分类器层,并通过用标记数据重新训练来优化完整的神经网络。

在本章中,我们不讨论 SAE(详见第 5 章,优化 TensorFlow 自编码器),但将坚持使用 MLP 和 DBN 并使用这两种 DNN 架构。我们将看到如何开发预测模型来处理高维数据集。

多层感知器

在多层网络中,可以识别层的人工神经元,以便每个神经元连接到下一层中的所有神经元,确保:

  • 属于同一层的神经元之间没有连接
  • 属于非相邻层的神经元之间没有连接
  • 每层的层数和神经元数取决于要解决的问题

输入和输出层定义输入和输出,并且存在隐藏层,其复杂性实现网络的不同行为。最后,神经元之间的连接由与相邻层对相同的矩阵表示。

每个数组包含两个相邻层的节点对之间的连接的权重。前馈网络是层内没有环路的网络。

我们将在第 3 章,使用 TensorFlow 的前馈神经网络中更详细地描述前馈网络:

图 13:MLP 架构

深度信念网络(DBNs)

为了克服 MLP 中的过拟合问题,我们建立了一个 DBN,做了无监督预训练,为输入获得了一组不错的特征表示,然后微调训练集从网络获得实际预测。虽然 MLP 的权重是随机初始化的,但 DBN 使用贪婪的逐层预训练算法通过概率生成模型初始化网络权重。模型由可见层和多层随机和潜在变量组成,称为隐藏单元或特征检测器。

DBN 是深度生成模型,它们是神经网络模型,可以复制您提供的数据分布。这允许您从实际数据点生成“虚假但逼真”的数据点。

DBN 由可见层和多层随机潜在变量组成,这些变量称为隐藏单元或特征检测器。前两层在它们之间具有无向的对称连接并形成关联存储器,而较低层从前一层接收自上而下的有向连接。 DBN 的构建块是受限玻尔兹曼机(RBM)。如下图所示,几个 RBM 一个接一个地堆叠形成 DBN:

图 14:配置用于半监督学习的 DBN

单个 RBM 由两层组成。第一层由可见神经元组成,第二层由隐藏神经元组成。下图显示了简单 RBM 的结构。可见单元接受输入,隐藏单元是非线性特征检测器。每个可见神经元都连接到所有隐藏的神经元,但同一层中的神经元之间没有内部连接。

RBM 由可见层节点和隐藏层节点组成,但没有可见 - 隐藏和隐藏 - 隐藏连接,因此项受限制。它们允许更有效的网络训练,可以监督或监督。这种类型的神经网络能够表示输入的大量特征,然后隐藏的节点可以表示多达 2n 个特征。可以训练网络回答单个问题(例如,问题是或否:它是猫吗?),直到它能够(再次以二元的方式)响应总共 2n 个问题(它是猫吗? ,这是暹罗人?,它是白色的吗?)。

RBM 的架构如下,神经元根据对称的二分图排列:

图 15:RBM 架构。

由于无法对变量之间的关系进行建模,因此单个隐藏层 RBM 无法从输入数据中提取所有特征。因此,一层接一层地使用多层 RBM 来提取非线性特征。在 DBN 中,首先使用输入数据训练 RBM,并且隐藏层表示使用贪婪学习方法学习的特征。这些第一 RBM 的学习特征,即第一 RBM 的隐藏层,被用作第二 RBM 的输入,作为 DBN 中的另一层。

类似地,第二层的学习特征用作另一层的输入。这样,DBN 可以从输入数据中提取深度和非线性特征。最后一个 RBM 的隐藏层代表整个网络的学习特征。

卷积神经网络(CNNs)

CNN 已经专门用于图像识别。学习中使用的每个图像被分成紧凑的拓扑部分,每个部分将由过滤器处理以搜索特定模式。形式上,每个图像被表示为像素的三维矩阵(宽度,高度和颜色),并且每个子部分可以与滤波器组卷积在一起。换句话说,沿着图像滚动每个滤镜计算相同滤镜和输入的内积。

此过程为各种过滤器生成一组特征图(激活图)。将各种特征图叠加到图像的相同部分上,我们得到输出量。这种类型的层称为卷积层。下图是 CNN 架构的示意图:

图 16:CNN 架构。

虽然常规 DNN 适用于小图像(例如,MNIST 和 CIFAR-10),但由于需要大量参数,它们会因较大的图像而崩溃。例如,100×100图像具有 10,000 个像素,并且如果第一层仅具有 1,000 个神经元(其已经严格限制传输到下一层的信息量),则这意味着 1000 万个连接。另外,这仅适用于第一层。

CNN 使用部分连接的层解决了这个问题。由于相邻层仅部分连接,并且因为它重复使用其权重,因此 CNN 的参数远远少于完全连接的 DNN,这使得训练速度更快。这降低了过拟合的风险,并且需要更少的训练数据。此外,当 CNN 已经学习了可以检测特定特征的内核时,它可以在图像上的任何地方检测到该特征。相反,当 DNN 在一个位置学习一个特征时,它只能在该特定位置检测到它。由于图像通常具有非常重复的特征,因此 CNN 在图像处理任务(例如分类)和使用较少的训练示例方面能够比 DNN 更好地推广。

重要的是,DNN 没有关于如何组织像素的先验知识;它不知道附近的像素是否接近。 CNN 的架构嵌入了这一先验知识。较低层通常识别图像的单元域中的特征,而较高层将较低层特征组合成较大特征。这适用于大多数自然图像,使 CNN 在 DNN 上具有决定性的先机:

图 17:常规 DNN 与 CNN。

例如,在上图中,在左侧,您可以看到常规的三层神经网络。在右侧,CNN 以三维(宽度,高度和深度)排列其神经元,如在其中一个层中可视化。 CNN 的每一层都将 3D 输入音量转换为神经元激活的 3D 输出音量。红色输入层保持图像,因此其宽度和高度将是图像的尺寸,深度将是三个(红色,绿色和蓝色通道)。

因此,我们所看到的所有多层神经网络都有由长线神经元组成的层,我们不得不将输入图像或数据平铺到 1D,然后再将它们馈送到神经网络。但是,当您尝试直接为它们提供 2D 图像时会发生什么?答案是在 CNN 中,每个层都用 2D 表示,这样可以更容易地将神经元与其相应的输入进行匹配。我们将在接下来的部分中看到这方面的示例。

自编码器

AE 是具有三层或更多层的网络 ,其中输入层和输出具有相同数量的神经元,并且那些中间(隐藏层)具有较少数量的神经元。对网络进行训练,以便在输出中简单地为每条输入数据再现输入中相同的活动模式。

AE 是能够在没有任何监督的情况下学习输入数据的有效表示的 ANN(即,训练集是未标记的)。它们通常具有比输入数据低得多的维度,使得 AE 可用于降低维数。更重要的是,AE 作为强大的特征检测器,它们可用于 DNN 的无监督预训练。

该问题的显着方面在于,由于隐藏层中神经元的数量较少,如果网络可以从示例中学习并推广到可接受的程度,则它执行数据压缩;对于每个示例,隐藏神经元的状态为输入和输出公共状态的压缩版本提供。 AEs 的有用应用是数据可视化的数据去噪和降维。

下图显示了 AE 通常如何工作;它通过两个阶段重建接收的输入:编码阶段,其对应于原始输入的尺寸减小;以及解码阶段,其能够从编码(压缩)表示重建原始输入:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kNiZcHjM-1681565849691)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-tf-2e-zh/img/B09698_01_19.jpg)]

图 18:自编码器的编码和解码阶段。

作为无监督神经网络,自编码器的主要特征是其对称结构。 自编码器有两个组件:将输入转换为内部表示的编码器,然后是将内部表示转换为输出的解码器。

换句话说, 自编码器可以看作是编码器的组合,其中我们将一些输入编码为代码,以及解码器,其中我们将代码解码/重建为其原始输入作为输出。因此,MLP 通常具有与自编码器相同的架构,除了输出层中的神经元的数量必须等于输入的数量。

如前所述,训练自编码器的方法不止一种。第一种方法是一次训练整个层,类似于 MLP。但是,在计算成本函数时,不像在监督学习中使用某些标记输出,我们使用输入本身。因此,成本函数显示实际输入和重建输入之间的差异。

循环神经网络(RNNs)

RNN 的基本特征是网络包含至少一个反馈连接,因此激活可以在循环中流动。它使网络能够进行时间处理和学习序列,例如执行序列识别/再现或时间关联/预测。

RNN 架构可以有许多不同的形式。一种常见类型包括标准 MLP 加上添加的循环。这些可以利用 MLP 强大的非线性映射功能,并具有某种形式的内存。其他人具有更均匀的结构,可能与每个神经元连接到所有其他神经元,并且可能具有随机激活函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9bwsXdl8-1681565849691)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-tf-2e-zh/img/B09698_01_20.jpg)]

图 19:RNN 架构。

对于简单的架构和确定性激活函数,可以使用类似的 GD 过程来实现学习,这些过程导致用于前馈网络的反向传播算法。

上图查看了 RNN 的一些最重要的类型和功能。 RNN 被设计成利用输入数据的顺序信息,与诸如感知器,长短期存储器单元(LSTM)或门控循环单元(GRU)之类的构件块之间的循环连接。后两者用于消除常规 RNN 的缺点,例如梯度消失/爆炸问题和长短期依赖性。我们将在后面的章节中讨论这些架构。

前沿架构

已经提出了许多其他前沿 DL 架构 ,例如深度时空神经网络(DST-NN),多维循环神经网络(MD-RNN),和卷积自编码器(CAE)。

然而,人们正在谈论和使用其他新兴网络,例如 CapsNets(CNN 的改进版本,旨在消除常规 CNN 的缺点),用于个性化的分解机和深度强化学习。

深度学习框架

在本节中,我们介绍了一些最流行的 DL 框架。简而言之,几乎所有的库都提供了使用图形处理器加速学习过程的可能性,在开放许可下发布,并且是大学研究小组的结果。

TensorFlow 是数学软件,是一个开源软件库,用 Python 和 C++ 编写,用于机器智能。 Google Brain 团队在 2011 年开发了它,它可以用来帮助我们分析数据,预测有效的业务成果。构建神经网络模型后,在必要的特征工程之后,您可以使用绘图或 TensorBoard 以交互方式执行训练。

最新版 TensorFlow 提供的主要功能包括更快的计算,灵活性,可移植性,易于调试,统一的 API,GPU 计算的透明使用,易用性和可扩展性。其他好处包括它被广泛使用,支持,并且可以大规模生产。

Keras 是一个深度学习库,位于 TensorFlow 和 Theano 之上,提供了一个直观的 API,受到了 Torch(可能是现有的最佳 Python API)的启发。 Deeplearning4j 依赖于 Keras 作为其 Python API,并从 Keras 和 Keras,Theano 和 TensorFlow 导入模型。

Google 的软件工程师 FrançoisChollet 创建了 Keras。它可以在 CPU 和 GPU 上无缝运行。这样可以通过用户友好性,模块化和可扩展性轻松快速地进行原型设计。 Keras 可能是增长最快的框架之一,因为构建 NN 层太容易了。因此,Keras 很可能成为 NN 的标准 Python API。

Theano 可能是最常见的库。 Theano 是用 Python 编写的,它是 ML 领域中使用最广泛的语言之一(Python 也用于 TensorFlow)。此外,Theano 允许使用 GPU,比单 CPU 快 24 倍。 Theano 允许您有效地定义,优化和求值复杂的数学表达式,例如多维数组。不幸的是,Yoshua Bengio 于 2017 年 9 月 28 日宣布,Theano 的发展将停止。这意味着 Theano 实际上已经死了。

Neon 是由 Nirvana 开发的基于 Python 的深度学习框架。 Neon 的语法类似于 Theano 的高级框架(例如,Keras)。目前,Neon 被认为是基于 GPU 的最快工具,特别是对于 CNN。虽然它的基于 CPU 的实现比大多数其他库相对更差。

Torch 是 ML 的巨大生态系统,提供大量算法和函数,包括 DL 和处理各种类型的多媒体数据,特别关注并行计算。它为 C 语言提供了出色的接口, 拥有庞大的用户社区。 Torch 是一个扩展脚本语言 Lua 的库,旨在为设计和训练 ML 系统提供灵活的环境。 Torch 是各种平台(Windows,Mac,Linux 和 Android)上的独立且高度可移植的框架,脚本可以在这些平台上运行而无需修改。 Torch 为不同的应用提供了许多用途。

Caffe,主要由伯克利远景和学习中心(BVLC)开发 ,是一个框架 ,因其表达,速度和模块性而脱颖而出。其独特的架构鼓励应用和创新,使计算更容易从 CPU 转换到 GPU。庞大的用户群意味着最近发生了相当大的发展。它是用 Python 编写的,但由于需要编译的众多支持库,安装过程可能很长。

MXNet 是一个支持多种语言的 DL 框架,例如 R,Python,C++ 和 Julia。这很有帮助,因为如果你知道这些语言中的任何一种,你根本不需要走出自己的舒适区来训练你的 DL 模型。它的后端用 C++ 和 CUDA 编写,它能够以与 Theano 类似的方式管理自己的内存。

MXNet 也很受欢迎,因为它可以很好地扩展,并且可以与多个 GPU 和计算机一起使用,这使它对企业非常有用。这就是为什么亚马逊将 MXNet 作为 DL 的参考库。 2017 年 11 月,AWS 宣布推出 ONNX-MXNet,这是一个开源 Python 包,用于将开放式神经网络交换(ONNX) DL 模型导入 Apache MXNet。

Microsoft Cognitive Toolkit(CNTK)是 Microsoft Research 的统一 DL 工具包,可以轻松训练, 将多种 GPU 和服务器中的流行模型类型组合在一起。 CNTK 为语音,图像和文本数据实现高效的 CNN 和 RNN 训练。它支持 cuDNN v5.1 进行 GPU 加速。 CNTK 还支持 Python,C++ ,C#和命令行接口。

这是一个总结这些框架的表:

框架 支持的编程语言 训练教材和社区 CNN 建模能力 RNN 建模能力 可用性 多 GPU 支持
Theano Python,C++ ++ 丰富的 CNN 教程和预建模型 丰富的 RNN 教程和预建模型 模块化架构
Neon Python, + CNN 最快的工具 资源最少 模块化架构
Torch Lua,Python + 资源最少 丰富的 RNN 教程和预建模型 模块化架构
Caffe C++ ++ 丰富的 CNN 教程和预建模型 资源最少 创建层需要时间
MXNet R,Python,Julia,Scala ++ 丰富的 CNN 教程和预建模型 资源最少 模块化架构
CNTK C++ + 丰富的 CNN 教程和预建模型 丰富的 RNN 教程和预建模型 模块化架构
TensorFlow Python,C++ +++ 丰富的 RNN 教程和预建模型 丰富的 RNN 教程和预建模型 模块化架构
DeepLearning4j Java,Scala +++ 丰富的 RNN 教程和预建模型 丰富的 RNN 教程和预建模型 模块化架构
Keras Python +++ 丰富的 RNN 教程和预建模型 丰富的 RNN 教程和预建模型 模块化架构

除了前面的库之外,最近还有一些关于云计算的 DL 项目。这个想法是将 DL 功能带到大数据,拥有数十亿个数据点和高维数据。例如,Amazon Web Services(AWS),Microsoft Azure,Google Cloud Platform 和 NVIDIA GPU Cloud(NGC)都提供机器和深度学习服务,它们是公共云的原生。

2017 年 10 月,AWS 针对 Amazon Elastic Compute Cloud(EC2)P3 实例发布了深度学习 AMI(亚马逊机器映像) 。这些 AMI 预装了深度学习框架,如 TensorFlow,Gluon 和 Apache MXNet,这些框架针对 Amazon EC2 P3 实例中的 NVIDIA Volta V100 GPU 进行了优化。深度学习服务目前提供三种类型的 AMI:Conda AMI,Base AMI 和带源代码的 AMI。

Microsoft Cognitive Toolkit 是 Azure 的开源深度学习服务。与 AWS 的产品类似,它侧重于可以帮助开发人员构建和部署深度学习应用的工具。该工具包安装在 Python 2.7 的根环境中。 Azure 还提供了一个模型库,其中包含代码示例等资源,以帮助企业开始使用该服务。

另一方面,NGC 为 AI 科学家和研究人员提供 GPU 加速容器。 NGC 采用容器化的深度学习框架,如 TensorFlow,PyTorch 和 MXNet,经过 NVIDIA 的调整,测试和认证,可在参与的云服务提供商的最新 NVIDIA GPU 上运行。尽管如此,还有通过各自市场提供的第三方服务。

总结

在本章中,我们介绍了 DL 的一些基本主题。 DL 由一组方法组成,这些方法允许 ML 系统获得多个级别上的数据的分层表示。这是通过组合简单单元来实现的,每个简单单元从输入级别开始,以更高和抽象级别的表示,在其自己的级别上转换表示。

最近,这些技术提供了许多应用中从未见过的结果,例如图像识别和语音识别。这些技术普及的主要原因之一是 GPU 架构的发展,这大大减少了 DNN 的训练时间。

有不同的 DNN 架构,每个架构都是针对特定问题而开发的。我们将在后面的章节中更多地讨论这些架构,并展示使用 TensorFlow 框架创建的应用示例。本章最后简要介绍了最重要的 DL 框架。

在下一章中,我们将开始我们的 DL 之旅,介绍 TensorFlow 软件库。我们将介绍 TensorFlow 的主要功能,并了解如何安装它并设置我们的第一个工作再营销数据集。

二、TensorFlow v1.6 的新功能是什么?

2015 年,Google 开源了 TensorFlow,包括其所有参考实现。所有源代码都是在 Apache 2.0 许可下在 GitHub 上提供的。从那以后,TensorFlow 已经在学术界和工业研究中被广泛采用,最稳定的版本 1.6 最近已经发布了统一的 API。

值得注意的是,TensorFlow 1.6(及更高版本)中的 API 并非都与 v1.5 之前的代码完全向后兼容。这意味着一些在 v1.5 之前工作的程序不一定适用于 TensorFlow 1.6。

现在让我们看看 TensorFlow v1.6 具有的新功能和令人兴奋的功能。

Nvidia GPU 支持的优化

从 TensorFlow v1.5 开始,预构建的二进制文件现在针对 CUDA 9.0 和 cuDNN 7 构建。但是,从 v1.6 版本开始,TensorFlow 预构建的二进制文件使用 AVX 指令,这可能会破坏旧 CPU 上的 TensorFlow。尽管如此,自 v1.5 以来,已经可以在 NVIDIA Tegra 设备上增加对 CUDA 的支持。

TensorFlow Lite

TensorFlow Lite 是 TensorFlow 针对移动和嵌入式设备的轻量级解决方案。它支持具有小二进制大小和支持硬件加速的快速表现的设备上机器学习模型的低延迟推理。

TensorFlow Lite 使用许多技术来实现低延迟,例如优化特定移动应用的内核,预融合激活,允许更小和更快(定点数学)模型的量化内核,以及将来利用杠杆专用机器学习硬件在特定设备上获得特定模型的最佳表现。

图 1:使用 TensorFlow Lite 在 Android 和 iOS 设备上使用训练模型的概念视图

机器学习正在改变计算范式,我们看到了移动和嵌入式设备上新用例的新趋势。在相机和语音交互模型的推动下,消费者的期望也趋向于与其设备进行自然的,类似人的交互。

因此,用户的期望不再局限于计算机,并且移动设备的计算能力也因硬件加速以及诸如 Android 神经网络 API 和 iOS 的 C++ API 之类的框架而呈指数级增长。如上图所示,预训练模型可以转换为较轻的版本,以便作为 Android 或 iOS 应用运行。

因此,广泛使用的智能设备为设备智能创造了新的可能性。这些允许我们使用我们的智能手机来执行实时计算机视觉和自然语言处理(NLP)。

急切执行

急切执行是 TensorFlow 的一个接口,它提供了一种命令式编程风格。启用预先执行时,TensorFlow 操作(在程序中定义)立即执行。

需要注意的是,从 TensorFlow v1.7 开始,急切执行将被移出contrib。这意味着建议使用tf.enable_eager_execution()。我们将在后面的部分中看到一个例子。

优化加速线性代数(XLA)

v1.5 之前的 XLA 不稳定并且具有非常有限的特性。但是,v1.6 对 XLA 的支持更多。这包括以下内容:

  • 添加了对 XLA 编译器的 Complex64 支持
  • 现在为 CPU 和 GPU 添加了快速傅里叶变换(FFT)支持
  • bfloat支持现已添加到 XLA 基础结构中
  • 已启用 ClusterSpec 传播与 XLA 设备的工作
  • Android TF 现在可以在兼容的 Tegra 设备上使用 CUDA 加速构建
  • 已启用对添加确定性执行器以生成 XLA 图的支持

开源社区报告的大量错误已得到修复,并且此版本已集成了大量 API 级别的更改。

但是,由于我们尚未使用 TensorFlow 进行任何研究,我们将在后面看到如何利用这些功能开发真实的深度学习应用。在此之前,让我们看看如何准备您的编程环境。

安装和配置 TensorFlow

您可以在许多平台上安装和使用 TensorFlow,例如 Linux, macOS 和 Windows。此外,您还可以从 TensorFlow 的最新 GitHub 源构建和安装 TensorFlow。此外,如果您有 Windows 机器,您可以通过原生点或 Anacondas 安装 TensorFlow。 TensorFlow 在 Windows 上支持 Python 3.5.x 和 3.6.x.

此外,Python 3 附带了 PIP3 包管理器,它是用于安装 TensorFlow 的程序。因此,如果您使用此 Python 版本,则无需安装 PIP。根据我们的经验,即使您的计算机上集成了 NVIDIA GPU 硬件,也值得安装并首先尝试仅使用 CPU 的版本,如果您没有获得良好的表现,那么您应该切换到 GPU 支持。

支持 GPU 的 TensorFlow 版本有几个要求,例如 64 位 Linux,Python 2.7(或 Python 3 的 3.3+),NVIDIACUDA®7.5 或更高版本(Pascal GPU 需要 CUDA 8.0)和 NVIDIA cuDNN(这是 GPU 加速深度学习)v5.1(建议使用更高版本)。有关详情,请参阅此链接

更具体地说,TensorFlow 的当前开发仅支持使用 NVIDIA 工具包和软件的 GPU 计算。因此,必须在您的计算机上安装以下软件才能获得预测分析应用的 GPU 支持:

  • NVIDIA 驱动程序
  • 具有计算能力的CUDA >= 3.0
  • CudNN

NVIDIA CUDA 工具包包括(详见此链接):

  • GPU 加速库,例如用于 FFT 的 cuFFT
  • 基本线性代数子程序(BLAS)的 cuBLAS
  • cuSPARSE 用于稀疏矩阵例程
  • cuSOLVER 用于密集和稀疏的直接求解器
  • 随机数生成的 cuRAND,图像的 NPP 和视频处理原语
  • 适用于 NVIDIA Graph Analytics 库的 nvGRAPH
  • 对模板化并行算法和数据结构以及专用 CUDA 数学库的推动

但是,我们不会介绍 TensorFlow 的安装和配置,因为 TensorFlow 上提供的文档非常丰富,可以遵循并采取相应的措施。另一个原因是该版本将定期更改。因此,使用 TensorFlow 网站保持自己更新将是一个更好的主意。

如果您已经安装并配置了编程环境,那么让我们深入了解 TensorFlow 计算图。

TensorFlow 计算图

在考虑执行 TensorFlow 程序时,我们应该熟悉图创建和会话执行的概念。基本上,第一个用于构建模型,第二个用于提供数据并获得结果。

有趣的是,TensorFlow 在 C++ 引擎上执行所有操作,这意味着在 Python 中甚至不会执行一些乘法或添加操作。 Python 只是一个包装器。从根本上说,TensorFlow C++ 引擎包含以下两件事:

  • 有效的操作实现,例如 CNN 的卷积,最大池化和 sigmoid
  • 前馈模式操作的衍生物

TensorFlow 库在编码方面是一个非凡的库,它不像传统的 Python 代码(例如,你可以编写语句并执行它们)。 TensorFlow 代码由不同的操作组成。甚至变量初始化在 TensorFlow 中也很特殊。当您使用 TensorFlow 执行复杂操作(例如训练线性回归)时,TensorFlow 会在内部使用数据流图表示其计算。该图称为计算图,它是由以下组成的有向图:

  • 一组节点,每个节点代表一个操作
  • 一组有向弧,每个弧代表执行操作的数据

TensorFlow 有两种类型的边:

  • 正常:它们携带节点之间的数据结构。一个操作的输出,即来自一个节点的输出,成为另一个操作的输入。连接两个节点的边缘带有值。
  • 特殊:此边不携带值,但仅表示两个节点之间的控制依赖关系,例如 X 和 Y。这意味着只有在 X 中的操作已经执行时才会执行节点 Y,但之前关于数据的操作之间的关系。

TensorFlow 实现定义控制依赖性,以强制规定执行其他独立操作的顺序,作为控制峰值内存使用的方式。

计算图基本上类似于数据流图。图 2 显示了简单计算的计算图,如z = d × c = (a + b) × c

图 2:一个计算简单方程的非常简单的执行图

在上图中,图中的圆圈表示操作,而矩形表示计算图。如前所述,TensorFlow 图包含以下内容:

  • tf.Operation对象:这些是图中的节点。这些通常简称为操作。 操作仅为 TITO(张量 - 张量 - 张量)。一个或多个张量输入和一个或多个张量输出。
  • tf.Tensor对象:这些是图的边缘。这些通常简称为张量。

张量对象在图中的各种操作之间流动。在上图中,d也是操作。它可以是“常量”操作,其输出是张量,包含分配给d的实际值。

也可以使用 TensorFlow 执行延迟执行。简而言之,一旦您在计算图的构建阶段中编写了高度复合的表达式,您仍然可以在运行会话阶段对其进行求值。从技术上讲,TensorFlow 安排工作并以有效的方式按时执行。

例如,使用 GPU 并行执行代码的独立部分如下图所示:

图 3:要在 CPU 或 GPU 等设备上的会话上执行的 TensorFlow 图中的边和节点

在创建计算图之后,TensorFlow 需要具有以分布式方式由多个 CPU(以及 GPU,如果可用)执行的活动会话。通常,您实际上不需要明确指定是使用 CPU 还是 GPU,因为 TensorFlow 可以选择使用哪一个。

默认情况下,将选择 GPU 以进行尽可能多的操作;否则,将使用 CPU。然而,通常,它会分配所有 GPU 内存,即使它不消耗它。

以下是 TensorFlow 图的主要组成部分:

  • 变量:用于 TensorFlow 会话之间的值,包含权重和偏置。
  • 张量:一组值,在节点之间传递以执行操作(也称为操作)。
  • 占位符:用于在程序和 TensorFlow 图之间发送数据。
  • 会话:当会话启动时,TensorFlow 会自动计算图中所有操作的梯度,并在链式规则中使用它们。实际上,在执行图时会调用会话。

不用担心,前面这些组件中的每一个都将在后面的章节中讨论。从技术上讲,您将要编写的程序可以被视为客户。然后,客户端用于以符号方式在 C/C++ 或 Python 中创建执行图,然后您的代码可以请求 TensorFlow 执行此图。整个概念从下图中变得更加清晰:

图 4:使用客户端主架构来执行 TensorFlow 图

计算图有助于使用 CPU 或 GPU 在多个计算节点上分配工作负载。这样,神经网络可以等同于复合函数,其中每个层(输入,隐藏或输出层)可以表示为函数。要了解在张量上执行的操作,需要了解 TensorFlow 编程模型的良好解决方法。

TensorFlow 代码结构

TensorFlow 编程模型表示如何构建预测模型。导入 TensorFlow 库时, TensorFlow 程序通常分为四个阶段:

  • 构建涉及张量运算的计算图(我们将很快看到张量)
  • 创建会话
  • 运行会话;执行图中定义的操作
  • 执行数据收集和分析

这些主要阶段定义了 TensorFlow 中的编程模型。请考虑以下示例,其中我们要将两个数相乘:

import tensorflow as tf # Import TensorFlow
x = tf.constant(8) # X op
y = tf.constant(9) # Y op
z = tf.multiply(x, y) # New op Z
sess = tf.Session() # Create TensorFlow session
out_z = sess.run(z) # execute Z op
sess.close() # Close TensorFlow session
print('The multiplication of x and y: %d' % out_z)# print result

前面的代码段可以用下图表示:

图 5:在客户端主架构上执行并返回的简单乘法

为了使前面的程序更有效,TensorFlow 还允许通过占位符交换图变量中的数据(稍后讨论)。现在想象一下代码段之后的可以做同样的事情,但效率更高:

import tensorflow as tf
# Build a graph and create session passing the graph
with tf.Session() as sess:
    x = tf.placeholder(tf.float32, name="x")
    y = tf.placeholder(tf.float32, name="y")
    z = tf.multiply(x,y)
# Put the values 8,9 on the placeholders x,y and execute the graph
z_output = sess.run(z,feed_dict={x: 8, y:9})
print(z_output)

TensorFlow 不是乘以两个数字所必需的。此外,这个简单的操作有很多行代码。该示例的目的是阐明如何构造代码,从最简单的(如在本例中)到最复杂的。此外,该示例还包含一些基本指令,我们将在本书中给出的所有其他示例中找到这些指令。

第一行中的单个导入为您的命令导入 TensorFlow;如前所述,它可以用tf实例化。然后,TensorFlow 运算符将由tf和要使用的运算符的名称表示。在下一行中,我们通过tf.Session()指令构造session对象:

with tf.Session() as sess:

提示

会话对象(即sess)封装了 TensorFlow 的环境,以便执行所有操作对象,并求值Tensor对象。我们将在接下来的部分中看到它们。

该对象包含计算图,如前所述,它包含要执行的计算。以下两行使用placeholder定义变量xy。通过placeholder,您可以定义输入(例如我们示例的变量x)和输出变量(例如变量y):

x = tf.placeholder(tf.float32, name="x")
y = tf.placeholder(tf.float32, name="y")

提示

占位符提供图元素和问题计算数据之间的接口。它们允许我们创建我们的操作并构建我们的计算图而不需要数据,而不是使用它的引用。

要通过placeholder函数定义数据或张量(我们将很快向您介绍张量的概念),需要三个参数:

  • 数据类型是要定义的张量中的元素类型。
  • 占位符的形状是要进给的张量的形状(可选)。如果未指定形状,则可以提供任何形状的张量。
  • 名称对于调试和代码分析非常有用,但它是可选的。

注意

有关张量的更多信息,请参阅此链接

因此,我们可以使用先前定义的两个参数(占位符和常量)来引入我们想要计算的模型。接下来,我们定义计算模型。

会话内的以下语句构建xy的乘积的数据结构,并随后将操作结果分配给张量z。然后它如下:

z = tf.multiply(x, y)

由于结果已由占位符z保存,我们通过sess.run语句执行图。在这里,我们提供两个值来将张量修补为图节点。它暂时用张量值替换操作的输出:

z_output = sess.run(z,feed_dict={x: 8, y:9})

在最后的指令中,我们打印结果:

print(z_output)

这打印输出72.0

用 TensorFlow 急切执行

如前所述,在启用 TensorFlow 的急切执行时,我们可以立即执行 TensorFlow 操作,因为它们是以命令方式从 Python 调用的。

启用急切执行后,TensorFlow 函数会立即执行操作并返回具体值。这与tf.Session相反,函数添加到图并创建计算图中的节点的符号引用。

TensorFlow 通过tf.enable_eager_execution提供急切执行的功能,其中包含以下别名:

  • tf.contrib.eager.enable_eager_execution
  • tf.enable_eager_execution

tf.enable_eager_execution具有以下签名:

tf.enable_eager_execution(
        config=None,
        device_policy=None
)

在上面的签名中,configtf.ConfigProto,用于配置执行操作的环境,但这是一个可选参数。另一方面,device_policy也是一个可选参数,用于控制关于特定设备(例如 GPU0)上需要输入的操作如何处理不同设备(例如,GPU1 或 CPU)上的输入的策略。

现在调用前面的代码将启用程序生命周期的急切执行。例如,以下代码在 TensorFlow 中执行简单的乘法运算:

import tensorflow as tf
x = tf.placeholder(tf.float32, shape=[1, 1]) # a placeholder for variable x
y = tf.placeholder(tf.float32, shape=[1, 1]) # a placeholder for variable y
m = tf.matmul(x, y)
with tf.Session() as sess:
    print(sess.run(m, feed_dict={x: [[2.]], y: [[4.]]}))

以下是上述代码的输出:

>>>
8.

然而,使用急切执行,整体代码看起来更简单:

import tensorflow as tf
# Eager execution (from TF v1.7 onwards):
tf.eager.enable_eager_execution()
x = [[2.]]
y = [[4.]]
m = tf.matmul(x, y)
print(m)

以下是上述代码的输出:

>>>
tf.Tensor([[8.]], shape=(1, 1), dtype=float32)

你能理解在执行前面的代码块时会发生什么吗?好了,在启用了执行后,操作在定义时执行,Tensor对象保存具体值,可以通过numpy()方法作为numpy.ndarray访问。

请注意,在使用 TensorFlow API 创建或执行图后,无法启用急切执行。通常建议在程序启动时调用此函数,而不是在库中调用。虽然这听起来很吸引人,但我们不会在即将到来的章节中使用此功能,因为这是一个新功能,尚未得到很好的探索。

TensorFlow 中的数据模型

TensorFlow 中的数据模型由张量表示。在不使用复杂的数学定义的情况下,我们可以说张量(在 TensorFlow 中)识别多维数值数组。我们将在下一小节中看到有关张量的更多细节。

张量

让我们看一下来自维基百科:张量的形式定义:

“张量是描述几何向量,标量和其他张量之间线性关系的几何对象。这种关系的基本例子包括点积,叉积和线性映射。几何向量,通常用于物理和工程应用,以及标量他们自己也是张量。“

该数据结构的特征在于三个参数:秩,形状和类型,如下图所示:

图 6:张量只是具有形状,阶数和类型的几何对象,用于保存多维数组

因此,张量可以被认为是指定具有任意数量的索引的元素的矩阵的推广。张量的语法与嵌套向量大致相同。

提示

张量只定义此值的类型以及在会话期间应计算此值的方法。因此,它们不代表或保留操作产生的任何值。

有些人喜欢比较 NumPy 和 TensorFlow。然而,实际上,TensorFlow 和 NumPy 在两者都是 Nd 数组库的意义上非常相似!

嗯,NumPy 确实有 n 维数组支持,但它不提供方法来创建张量函数并自动计算导数(并且它没有 GPU 支持)。下图是 NumPy 和 TensorFlow 的简短一对一比较:

图 7:NumPy 与 TensorFlow:一对一比较

现在让我们看一下在 TensorFlow 图之前创建张量的替代方法(我们将在后面看到其他的进给机制):

>>> X = [[2.0, 4.0],
        [6.0, 8.0]] # X is a list of lists
>>> Y = np.array([[2.0, 4.0],
                 [6.0, 6.0]], dtype=np.float32)#Y is a Numpy array
>>> Z = tf.constant([[2.0, 4.0],
                    [6.0, 8.0]]) # Z is a tensor

这里,X是列表,Y是来自 NumPy 库的 n 维数组,Z是 TensorFlow 张量对象。现在让我们看看他们的类型:

>>> print(type(X))
>>> print(type(Y))
>>> print(type(Z))
#Output
<class 'list'>
<class 'numpy.ndarray'>
<class 'tensorflow.python.framework.ops.Tensor'>

好吧,他们的类型打印正确。但是,与其他类型相比,我们正式处理张量的更方便的函数是tf.convert_to_tensor()函数如下:

t1 = tf.convert_to_tensor(X, dtype=tf.float32)
t2 = tf.convert_to_tensor(Z, dtype=tf.float32)

现在让我们使用以下代码查看它们的类型:

>>> print(type(t1))
>>> print(type(t2))
#Output:
<class 'tensorflow.python.framework.ops.Tensor'>
<class 'tensorflow.python.framework.ops.Tensor'>

太棒了!关于张量的讨论已经足够了。因此,我们可以考虑以术语秩为特征的结构。

秩和形状

称为秩的维度单位描述每个张量。它识别张量的维数。因此,秩被称为张量的阶数或维度。阶数零张量是标量,阶数 1 张量是向量,阶数 2 张量是矩阵。

以下代码定义了 TensorFlow scalarvectormatrixcube_matrix。在下一个示例中,我们将展示秩如何工作:

import tensorflow as tf
scalar = tf.constant(100)
vector = tf.constant([1,2,3,4,5])
matrix = tf.constant([[1,2,3],[4,5,6]])
cube_matrix = tf.constant([[[1],[2],[3]],[[4],[5],[6]],[[7],[8],[9]]])
print(scalar.get_shape())
print(vector.get_shape())
print(matrix.get_shape())
print(cube_matrix.get_shape())

结果打印在这里:

>>>
()
(5,)
(2, 3)
(3, 3, 1)
>>>

张量的形状是它具有的行数和列数。现在我们将看看如何将张量的形状与其阶数联系起来:

>>scalar.get_shape()
TensorShape([])
>>vector.get_shape()
TensorShape([Dimension(5)])
>>matrix.get_shape()
TensorShape([Dimension(2), Dimension(3)])
>>cube.get_shape()
TensorShape([Dimension(3), Dimension(3), Dimension(1)])

数据类型

除了阶数和形状,张量具有数据类型。以下是数据类型列表:

数据类型 Python 类型 描述
DT_FLOAT tf.float32 32 位浮点
DT_DOUBLE tf.float64 64 位浮点
DT_INT8 tf.int8 8 位有符号整数
DT_INT16 tf.int16 16 位有符号整数
DT_INT32 tf.int32 32 位有符号整数
DT_INT64 tf.int64 64 位有符号整数
DT_UINT8 tf.uint8 8 位无符号整数
DT_STRING tf.string 可变长度字节数组。张量的每个元素都是一个字节数组
DT_BOOL tf.bool 布尔
DT_COMPLEX64 tf.complex64 由两个 32 位浮点组成的复数:实部和虚部
DT_COMPLEX128 tf.complex128 由两个 64 位浮点组成的复数:实部和虚部
DT_QINT8 tf.qint8 量化操作中使用的 8 位有符号整数
DT_QINT32 tf.qint32 量化操作中使用的 32 位有符号整数
DT_QUINT8 tf.quint8 量化操作中使用的 8 位无符号整数

上表是不言自明的,因此我们没有提供有关数据类型的详细讨论。 TensorFlow API 用于管理与 NumPy 数组之间的数据。

因此,要构建具有常量值的张量,将 NumPy 数组传递给tf.constant()运算符,结果将是具有该值的张量:

import tensorflow as tf
import numpy as np
array_1d = np.array([1,2,3,4,5,6,7,8,9,10])
tensor_1d = tf.constant(array_1d)
with tf.Session() as sess:
    print(tensor_1d.get_shape())
    print(sess.run(tensor_1d))

运行该示例,我们获得以下内容:

>>>
 (10,)
 [ 1  2  3  4  5  6  7  8  9 10]

要构建具有变量值的张量,请使用 NumPy 数组并将其传递给tf.Variable构造器。结果将是具有该初始值的变量张量:

import tensorflow as tf
import numpy as np
# Create a sample NumPy array
array_2d = np.array([(1,2,3),(4,5,6),(7,8,9)])
# Now pass the preceding array to tf.Variable()
tensor_2d = tf.Variable(array_2d)
# Execute the preceding op under an active session
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(tensor_2d.get_shape())
    print sess.run(tensor_2d)
# Finally, close the TensorFlow session when you're done
sess.close()

在前面的代码块中,tf.global_variables_initializer()用于初始化我们之前创建的所有操作。如果需要创建一个初始值取决于另一个变量的变量,请使用另一个变量的initialized_value()。这可确保以正确的顺序初始化变量。

结果如下:

>>>
 (3, 3)
 [[1 2 3]
 [4 5 6]
 [7 8 9]]

为了便于在交互式 Python 环境中使用,我们可以使用InteractiveSession类,然后将该会话用于所有Tensor.eval()Operation.run()调用:

import tensorflow as tf # Import TensorFlow
import numpy as np # Import numpy
# Create an interactive TensorFlow session
interactive_session = tf.InteractiveSession()
# Create a 1d NumPy array 
array1 = np.array([1,2,3,4,5]) # An array
# Then convert the preceding array into a tensor
tensor = tf.constant(array1) # convert to tensor
print(tensor.eval()) # evaluate the tensor op
interactive_session.close() # close the session

提示

tf.InteractiveSession()只是方便的语法糖,用于在 IPython 中保持默认会话打开。

结果如下:

>>>
   [1 2 3 4 5]

在交互式设置中,例如 shell 或 IPython 笔记本,这可能会更容易,因为在任何地方传递会话对象都很繁琐。

注意

IPython 笔记本现在称为 Jupyter 笔记本。它是一个交互式计算环境,您可以在其中组合代码执行,富文本,数学,绘图和富媒体。有关更多信息,感兴趣的读者请参阅此链接

定义张量的另一种方法是使用tf.convert_to_tensor语句:

import tensorflow as tf
import numpy as np
tensor_3d = np.array([[[0, 1, 2], [3, 4, 5], [6, 7, 8]],
                      [[9, 10, 11], [12, 13, 14], [15, 16, 17]],
                      [[18, 19, 20], [21, 22, 23], [24, 25, 26]]])
tensor_3d = tf.convert_to_tensor(tensor_3d, dtype=tf.float64)
with tf.Session() as sess:
    print(tensor_3d.get_shape())
    print(sess.run(tensor_3d))
# Finally, close the TensorFlow session when you're done
sess.close()

以下是上述代码的输出:

>>>
(3, 3, 3)
[[[  0\.   1\.   2.]
  [  3\.   4\.   5.]
  [  6\.   7\.   8.]]
 [[  9\.  10\.  11.]
  [ 12\.  13\.  14.]
  [ 15\.  16\.  17.]]
 [[ 18\.  19\.  20.]
  [ 21\.  22\.  23.]
  [ 24\.  25\.  26.]]]

变量

变量是用于保存和更新参数的 TensorFlow 对象。必须初始化变量,以便您可以保存并恢复它以便稍后分析代码。使用tf.Variable()tf.get_variable()语句创建变量。而tf.get_varaiable()被推荐但tf.Variable()是低标签抽象。

在下面的示例中,我们要计算从 1 到 10 的数字,但让我们先导入 TensorFlow:

import tensorflow as tf

我们创建了一个将初始化为标量值 0 的变量:

value = tf.get_variable("value", shape=[], dtype=tf.int32, initializer=None, regularizer=None, trainable=True, collections=None)

assign()add()运算符只是计算图的节点,因此在会话运行之前它们不会执行赋值:

one = tf.constant(1)
update_value = tf.assign_add(value, one)
initialize_var = tf.global_variables_initializer()

我们可以实例化计算图:

with tf.Session() as sess:
    sess.run(initialize_var)
    print(sess.run(value))
    for _ in range(5):
        sess.run(update_value)
        print(sess.run(value))
# Close the session

让我们回想一下,张量对象是操作结果的符号句柄,但它实际上并不保存操作输出的值:

>>>
0
1
2
3
4
5

运行

要获取操作的输出,可以通过调用会话对象上的run()并传入张量来执行图。除了获取单个张量节点,您还可以获取多个张量。

在下面的示例中,使用run()调用一起提取summultiply张量:

import tensorflow as tf
constant_A = tf.constant([100.0])
constant_B = tf.constant([300.0])
constant_C = tf.constant([3.0])
sum_ = tf.add(constant_A,constant_B)
mul_ = tf.multiply(constant_A,constant_C)
with tf.Session() as sess:
    result = sess.run([sum_,mul_])# _ means throw away afterwards
    print(result)

输出如下:

>>>
[array(400.],dtype=float32),array([ 300.],dtype=float32)]

应该注意的是,所有需要执行的操作(即,为了产生张量值)都运行一次(每个请求的张量不是一次)。

馈送和占位符

有四种方法将数据输入 TensorFlow 程序(更多信息,请参阅此链接):

  • 数据集 API:这使您能够从简单和可重用的分布式文件系统构建复杂的输入管道,并执行复杂的操作。如果您要处理不同数据格式的大量数据,建议使用数据集 API。数据集 API 为 TensorFlow 引入了两个新的抽象,用于创建可馈送数据集:tf.contrib.data.Dataset(通过创建源或应用转换操作)和tf.contrib.data.Iterator
  • 馈送:这允许我们将数据注入计算图中的任何张量。
  • 从文件中读取:这允许我们使用 Python 的内置机制开发输入管道,用于从图开头的数据文件中读取数据。
  • 预加载数据:对于小数据集,我们可以使用 TensorFlow 图中的常量或变量来保存所有数据。

在本节中,我们将看到馈送机制的例子。我们将在接下来的章节中看到其他方法。 TensorFlow 提供了一种馈送机制,允许我们将数据注入计算图中的任何张量。您可以通过feed_dict参数将源数据提供给启动计算的run()eval()调用。

提示

使用feed_dict参数进行馈送是将数据提供到 TensorFlow 执行图中的最低效方法,并且仅应用于需要小数据集的小型实验。它也可以用于调试。

我们还可以用馈送数据(即变量和常量)替换任何张量。最佳做法是使用tf.placeholder()使用 TensorFlow 占位符节点。占位符专门用作馈送的目标。空占位符未初始化,因此不包含任何数据。

因此,如果在没有馈送的情况下执行它,它将始终生成错误,因此您不会忘记提供它。以下示例显示如何提供数据以构建随机2×3矩阵:

import tensorflow as tf
import numpy as np
a = 3
b = 2
x = tf.placeholder(tf.float32,shape=(a,b))
y = tf.add(x,x)
data = np.random.rand(a,b)
sess = tf.Session()
print(sess.run(y,feed_dict={x:data}))
sess.close()# close the session

输出如下:

>>>
[[ 1.78602004  1.64606333]
 [ 1.03966308  0.99269408]
 [ 0.98822606  1.50157797]]
>>>

通过 TensorBoard 可视化计算

TensorFlow 包含函数 ,允许您在名为 TensorBoard 的可视化工具中调试和优化程序。使用 TensorBoard,您可以以图形方式观察有关图任何部分的参数和详细信息的不同类型的统计数据。

此外,在使用复杂的 DNN 进行预测建模时,图可能很复杂且令人困惑。为了更容易理解,调试和优化 TensorFlow 程序,您可以使用 TensorBoard 可视化 TensorFlow 图,绘制有关图执行的量化指标,并显示其他数据,例如通过它的图像。

因此,TensorBoard 可以被认为是一个用于分析和调试预测模型的框架。 TensorBoard 使用所谓的摘要来查看模型的参数:一旦执行了 TensorFlow 代码,我们就可以调用 TensorBoard 来查看 GUI 中的摘要。

TensorBoard 如何运作?

TensorFlow 使用计算图来执行应用。在计算图中,节点表示操作,弧是操作之间的数据。

TensorBoard 的主要思想是将摘要与图上的节点(操作)相关联。代码运行时,摘要操作将序列化节点的数据并将数据输出到文件中。稍后,TensorBoard 将可视化汇总操作。有关更详细的讨论,读者可以参考此链接

简而言之,TensorBoard 是一套 Web 应用,用于检查和理解您的 TensorFlow 运行和图。使用 TensorBoard 时的工作流程如下:

  1. 构建计算图/代码
  2. 将摘要操作附加到您要检查的节点
  3. 像往常一样开始运行图
  4. 运行摘要操作
  5. 执行完成后,运行 TensorBoard 以显示摘要输出
file_writer = tf.summary.FileWriter('/path/to/logs', sess.graph)

对于步骤 2(即,在运行 TensorBoard 之前),请确保通过创建摘要编写器在日志目录中生成摘要数据:

sess.graph包含图定义;启用图可视化工具

现在,如果你在终端中键入$ which tensorboard,如果你用 pip 安装它,它应该存在:

root@ubuntu:~$ which tensorboard
/usr/local/bin/tensorboard

你需要给它一个日志目录。当您在运行图的目录中时,可以使用以下内容从终端启动它:

tensorboard --logdir path/to/logs

当 TensorBoard 配置完全时,可以通过发出以下命令来访问它:

# Make sure there's no space before or after '="
$ tensorboard –logdir=<trace_file_name>

现在您只需输入http://localhost:6006/即可从浏览器访问localhost:6006。然后它应该是这样的:

图 8:在浏览器上使用 TensorBoard

注意

TensorBoard 可用于谷歌浏览器或 Firefox。其他浏览器可能有效,但可能存在错误或表现问题。

这已经太过分了吗?不要担心,在上一节中,我们将结合前面解释的所有想法构建单个输入神经元模型并使用 TensorBoard 进行分析。

线性回归及更多

在本节中,我们将仔细研究 TensorFlow 和 TensorBoard 的主要概念,并尝试做一些基本操作来帮助您入门。我们想要实现的模型模拟线性回归。

在统计和 ML 中,线性回归是一种经常用于衡量变量之间关系的技术。这是一种非常简单但有效的算法,也可用于预测建模。

线性回归模拟因变量y[i],自变量x[i],和随机项b。这可以看作如下:

使用 TensorFlow 的典型线性回归问题具有以下工作流程,该工作流程更新参数以最小化给定成本函数(参见下图):

图 9:在 TensorFlow 中使用线性回归的学习算法

现在,让我们尝试按照前面的图,通过概念化前面的等式将其重现为线性回归。为此,我们将编写一个简单的 Python 程序,用于在 2D 空间中创建数据。然后我们将使用 TensorFlow 来寻找最适合数据点的线(如下图所示):

# Import libraries (Numpy, matplotlib)
import numpy as np
import matplotlib.pyplot as plot
# Create 1000 points following a function y=0.1 * x + 0.4z
(i.e. # y = W * x + b) with some normal random distribution:
num_points = 1000
vectors_set = []
# Create a few random data points 
for i in range(num_points):
    W = 0.1 # W
   b = 0.4 # b
    x1 = np.random.normal(0.0, 1.0)#in: mean, standard deviation
    nd = np.random.normal(0.0, 0.05)#in:mean,standard deviation
    y1 = W * x1 + b
 # Add some impurity with normal distribution -i.e. nd 
    y1 = y1 + nd
 # Append them and create a combined vector set:
    vectors_set.append([x1, y1])
# Separate the data point across axises:
x_data = [v[0] for v in vectors_set]
y_data = [v[1] for v in vectors_set]
# Plot and show the data points in a 2D space
plot.plot(x_data, y_data, 'ro', label='Original data')
plot.legend()
plot.show()

如果您的编译器没有报错,您应该得到以下图表:

图 10:随机生成(但原始)数据

好吧,到目前为止,我们刚刚创建了一些数据点而没有可以通过 TensorFlow 执行的相关模型。因此,下一步是创建一个线性回归模型,该模型可以获得从输入数据点估计的输出值y,即x_data。在这种情况下,我们只有两个相关参数,Wb

现在的目标是创建一个图,允许我们根据输入数据x_data,通过将它们调整为y_data来找到这两个参数的值。因此,我们的目标函数如下:

如果你还记得,我们在 2D 空间中创建数据点时定义了W = 0.1b = 0.4。 TensorFlow 必须优化这两个值,使W趋于 0.1 和b为 0.4。

解决此类优化问题的标准方法是迭代数据点的每个值并调整Wb的值,以便为每次迭代获得更精确的答案。要查看值是否确实在改善,我们需要定义一个成本函数来衡量某条线的优质程度。

在我们的例子中,成本函数是均方误差,这有助于我们根据实际数据点与每次迭代的估计距离函数之间的距离函数找出误差的平均值。我们首先导入 TensorFlow 库:

import tensorflow as tf
W = tf.Variable(tf.zeros([1]))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b

在前面的代码段中,我们使用不同的策略生成一个随机点并将其存储在变量W中。现在,让我们定义一个损失函数loss = mean[(y - y_data)^2],这将返回一个标量值,其中包含我们之间所有距离的均值。数据和模型预测。就 TensorFlow 约定而言,损失函数可表示如下:

loss = tf.reduce_mean(tf.square(y - y_data))

前一行实际上计算均方误差(MSE)。在不进一步详述的情况下,我们可以使用一些广泛使用的优化算法,例如 GD。在最低级别,GD 是一种算法,它对我们已经拥有的一组给定参数起作用。

它以一组初始参数值开始,并迭代地移向一组值,这些值通过采用另一个称为学习率的参数来最小化函数。通过在梯度函数的负方向上采取步骤来实现这种迭代最小化:

optimizer = tf.train.GradientDescentOptimizer(0.6)
train = optimizer.minimize(loss)

在运行此优化函数之前,我们需要初始化到目前为止所有的变量。让我们使用传统的 TensorFlow 技术,如下所示:

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

由于我们已经创建了 TensorFlow 会话,我们已准备好进行迭代过程,帮助我们找到Wb的最佳值:

for i in range(6):
  sess.run(train)
  print(i, sess.run(W), sess.run(b), sess.run(loss))

您应该观察以下输出:

>>>
0 [ 0.18418592] [ 0.47198644] 0.0152888
1 [ 0.08373772] [ 0.38146532] 0.00311204
2 [ 0.10470386] [ 0.39876288] 0.00262051
3 [ 0.10031486] [ 0.39547175] 0.00260051
4 [ 0.10123629] [ 0.39609471] 0.00259969
5 [ 0.1010423] [ 0.39597753] 0.00259966
6 [ 0.10108326] [ 0.3959994] 0.00259966
7 [ 0.10107458] [ 0.39599535] 0.00259966

你可以看到算法从W = 0.18418592b = 0.47198644的初始值开始,损失非常高。然后,算法通过最小化成本函数来迭代地调整值。在第八次迭代中,所有值都倾向于我们期望的值。

现在,如果我们可以绘制它们怎么办?让我们通过在for循环下添加绘图线来实现 ,如下所示:

for i in range(6):
       sess.run(train)
       print(i, sess.run(W), sess.run(b), sess.run(loss))
       plot.plot(x_data, y_data, 'ro', label='Original data')
       plot.plot(x_data, sess.run(W)*x_data + sess.run(b))
       plot.xlabel('X')
       plot.xlim(-2, 2)
       plot.ylim(0.1, 0.6)
       plot.ylabel('Y')
       plot.legend()
       plot.show()

前面的代码块应该生成下图(虽然合并在一起):

图 11:在第六次迭代后优化损失函数的线性回归

现在让我们进入第 16 次迭代:

>>>
0 [ 0.23306453] [ 0.47967502] 0.0259004
1 [ 0.08183448] [ 0.38200468] 0.00311023
2 [ 0.10253634] [ 0.40177572] 0.00254209
3 [ 0.09969243] [ 0.39778906] 0.0025257
4 [ 0.10008509] [ 0.39859086] 0.00252516
5 [ 0.10003048] [ 0.39842987] 0.00252514
6 [ 0.10003816] [ 0.39846218] 0.00252514
7 [ 0.10003706] [ 0.39845571] 0.00252514
8 [ 0.10003722] [ 0.39845699] 0.00252514
9 [ 0.10003719] [ 0.39845672] 0.00252514
10 [ 0.1000372] [ 0.39845678] 0.00252514
11 [ 0.1000372] [ 0.39845678] 0.00252514
12 [ 0.1000372] [ 0.39845678] 0.00252514
13 [ 0.1000372] [ 0.39845678] 0.00252514
14 [ 0.1000372] [ 0.39845678] 0.00252514
15 [ 0.1000372] [ 0.39845678] 0.00252514

好多了,我们更接近优化的值,对吧?现在,如果我们通过 TensorFlow 进一步改进我们的可视化分析,以帮助可视化这些图中发生的事情,该怎么办? TensorBoard 提供了一个网页,用于调试图并检查变量,节点,边缘及其相应的连接。

此外,我们需要使用变量标注前面的图,例如损失函数,Wby_datax_data等。然后,您需要通过调用tf.summary.merge_all()函数生成所有摘要。

现在,我们需要对前面的代码进行如下更改。但是,最好使用tf.name_scope()函数对图上的相关节点进行分组。因此,我们可以使用tf.name_scope()来组织 TensorBoard 图表视图中的内容,但让我们给它一个更好的名称:

with tf.name_scope("LinearRegression") as scope:
   W = tf.Variable(tf.zeros([1]))
   b = tf.Variable(tf.zeros([1]))
   y = W * x_data + b

然后,让我们以类似的方式标注损失函数,但使用合适的名称,例如LossFunction

with tf.name_scope("LossFunction") as scope:
  loss = tf.reduce_mean(tf.square(y - y_data))

让我们标注 TensorBoard 所需的损失,权重和偏置:

loss_summary = tf.summary.scalar("loss", loss)
w_ = tf.summary.histogram("W", W)
b_ = tf.summary.histogram("b", b)

一旦您标注了图,就可以通过合并来配置摘要了:

merged_op = tf.summary.merge_all()

在运行训练之前(初始化之后),使用tf.summary.FileWriter() API 编写摘要,如下所示:

writer_tensorboard = tf.summary.FileWriter('logs/', tf.get_default_graph())

然后按如下方式启动 TensorBoard:

$ tensorboard –logdir=<trace_dir_name>

在我们的例子中,它可能类似于以下内容:

$ tensorboard --logdir=/home/root/LR/

现在让我们转到http://localhost:6006并单击 GRAPH 选项卡。您应该看到以下图表:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qe42IjO0-1681565849695)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-tf-2e-zh/img/B09698_02_11.jpg)]

图 12:TensorBoard 上的主图和辅助节点

提示

请注意,Ubuntu 可能会要求您安装python-tk包。您可以通过在 Ubuntu 上执行以下命令来执行此操作:

$ sudo apt-get install python-tk
# For Python 3.x, use the following
$ sudo apt-get install python3-tk

真实数据集的线性回归回顾

在上一节中,我们看到线性回归的一个例子。我们看到了如何将 TensorFlow 与随机生成的数据集一起使用,即假数据。我们已经看到回归是一种用于预测连续(而非离散)输出的监督机器学习。

然而,对假数据进行线性回归就像买一辆新车但从不开车。这个令人敬畏的机器需要在现实世界中使用!幸运的是,许多数据集可在线获取,以测试您新发现的回归知识。

其中一个是波士顿住房数据集,可以从 UCI 机器学习库下载。它也可以作为 scikit-learn 的预处理数据集使用。

所以,让我们开始导入所有必需的库,包括 TensorFlow,NumPy,Matplotlib 和 scikit-learn:

import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
from numpy import genfromtxt
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split

接下来,我们需要准备由波士顿住房数据集中的特征和标签组成的训练集。read_boston_data ()方法从 scikit-learn 读取并分别返回特征和标签:

def read_boston_data():
    boston = load_boston()
    features = np.array(boston.data)
    labels = np.array(boston.target)
    return features, labels

现在我们已经拥有特征和标签,我们还需要使用normalizer()方法对特征进行标准化。这是方法的签名:

def normalizer(dataset):
    mu = np.mean(dataset,axis=0)
    sigma = np.std(dataset,axis=0)
    return(dataset - mu)/sigma

bias_vector()用于将偏差项(即全 1)附加到我们在前一步骤中准备的标准化特征。它对应于前一个例子中直线方程中的b项:

def bias_vector(features,labels):
    n_training_samples = features.shape[0]
    n_dim = features.shape[1]
    f = np.reshape(np.c_[np.ones(n_training_samples),features],[n_training_samples,n_dim + 1])
    l = np.reshape(labels,[n_training_samples,1])
    return f, l

我们现在将调用这些方法并将数据集拆分为训练和测试,75% 用于训练和休息用于测试:

features,labels = read_boston_data()
normalized_features = normalizer(features)
data, label = bias_vector(normalized_features,labels)
n_dim = data.shape[1]
# Train-test split
train_x, test_x, train_y, test_y = train_test_split(data,label,test_size = 0.25,random_state = 100)

现在让我们使用 TensorFlow 的数据结构(例如占位符,标签和权重):

learning_rate = 0.01
training_epochs = 100000
log_loss = np.empty(shape=[1],dtype=float)
X = tf.placeholder(tf.float32,[None,n_dim]) #takes any number of rows but n_dim columns
Y = tf.placeholder(tf.float32,[None,1]) # #takes any number of rows but only 1 continuous column
W = tf.Variable(tf.ones([n_dim,1])) # W weight vector

做得好!我们已经准备好构建 TensorFlow 图所需的数据结构。现在是构建线性回归的时候了,这非常简单:

y_ = tf.matmul(X, W)
cost_op = tf.reduce_mean(tf.square(y_ - Y))
training_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost_op)

在前面的代码段中,第一行将特征矩阵乘以可用于预测的权重矩阵。第二行计算损失,即回归线的平方误差。最后,第三行执行 GD 优化的一步以最小化平方误差。

提示

使用哪种优化器:使用优化器的主要目的是最小化成本;因此,我们必须定义一个优化器。使用最常见的优化器(如 SGD),学习率必须以1 / T进行缩放才能获得收敛,其中T是迭代次数。

Adam 或 RMSProp 尝试通过调整步长来自动克服此限制,以使步长与梯度具有相同的比例。此外,在前面的示例中,我们使用了 Adam 优化器,它在大多数情况下都表现良好。

然而,如果您正在训练神经网络计算梯度是必须的,使用实现 RMSProp 算法的RMSPropOptimizer函数是一个更好的主意,因为它是在小批量设置中学习的更快的方式。研究人员还建议在训练深度 CNN 或 DNN 时使用 Momentum 优化器。

从技术上讲,RMSPropOptimizer 是一种先进的梯度下降形式,它将学习率除以指数衰减的平方梯度平均值。衰减参数的建议设置值为 0.9,而学习率的良好默认值为 0.001。

例如在 TensorFlow 中,tf.train.RMSPropOptimizer()帮助我们轻松使用它:

optimizer = tf.train.RMSPropOptimizer(0.001, 0.9).minimize(cost_op)

现在,在我们开始训练模型之前,我们需要使用initialize_all_variables()方法初始化所有变量,如下所示:

init = tf.initialize_all_variables()

太棒了!现在我们已经设法准备好所有组件,我们已经准备好训练实际的训练了。我们首先创建 TensorFlow 会话,如下所示:

sess = tf.Session()
sess.run(init_op)
for epoch in range(training_epochs):
    sess.run(training_step,feed_dict={X:train_x,Y:train_y})
    log_loss = np.append(log_loss,sess.run(cost_op,feed_dict={X: train_x,Y: train_y}))

训练完成后,我们就可以对看不见的数据进行预测。然而,看到完成训练的直观表示会更令人兴奋。因此,让我们使用 Matplotlib 将成本绘制为迭代次数的函数:

plt.plot(range(len(log_loss)),log_loss)
plt.axis([0,training_epochs,0,np.max(log_loss)])
plt.show()

以下是上述代码的输出:

>>>

图 13:作为迭代次数函数的成本

对测试数据集做一些预测并计算均方误差:

pred_y = sess.run(y_, feed_dict={X: test_x})
mse = tf.reduce_mean(tf.square(pred_y - test_y))
print("MSE: %.4f" % sess.run(mse))

以下是上述代码的输出:

>>>
MSE: 27.3749

最后,让我们展示最佳拟合线:

fig, ax = plt.subplots()
ax.scatter(test_y, pred_y)
ax.plot([test_y.min(), test_y.max()], [test_y.min(), test_y.max()], 'k--', lw=3)
ax.set_xlabel('Measured')
ax.set_ylabel('Predicted')
plt.show()

以下是上述代码的输出:

>>>

图 14:预测值与实际值

总结

TensorFlow 旨在通过 ML 和 DL 轻松地为每个人进行预测分析,但使用它确实需要对一些通用原则和算法有一个正确的理解。 TensorFlow 的最新版本带有许多令人兴奋的新功能,所以我们试图覆盖它们,以便您可以轻松使用它们。总之,这里简要回顾一下本章已经解释过的 TensorFlow 的关键概念:

  • 图:每个 TensorFlow 计算可以表示为数据流图,其中每个图构建为一组操作对象。有三种核心图数据结构:tf.Graphtf.Operationtf.Tensor )。
  • 操作:图节点将一个或多个张量作为输入,并产生一个或多个张量作为输出。节点可以由操作对象表示,用于执行诸如加法,乘法,除法,减法或更复杂操作的计算单元。
  • 张量:它们就像高维数组对象。换句话说,它们可以表示为数据流图的边缘,并且是不同操作的输出。
  • 会话:会话对象是一个实体,它封装了执行操作对象的环境,以便在数据流图上运行计算。结果,在run()eval()调用内部求值张量对象。

在本章的后面部分,我们介绍了 TensorBoard,它是分析和调试神经网络模型的强大工具。最后,我们看到了如何在假数据集和真实数据集上实现最简单的基于 TensorFlow 的线性回归模型之一。

在下一章中,我们将讨论不同 FFNN 架构的理论背景,如深度信念网络(DBN)和多层感知器(MLP)。

然后,我们将展示如何训练和分析评估模型所需的表现指标,然后通过一些方法调整 FFNN 的超参数以优化表现。最后,我们将提供两个使用 MLP 和 DBN 的示例,说明如何为银行营销数据集建立非常强大和准确的预测分析模型。

TensorFlow 深度学习第二版:1~5(2)https://developer.aliyun.com/article/1426792

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
5天前
|
机器学习/深度学习 TensorFlow 算法框架/工具
深度学习之格式转换笔记(三):keras(.hdf5)模型转TensorFlow(.pb) 转TensorRT(.uff)格式
将Keras训练好的.hdf5模型转换为TensorFlow的.pb模型,然后再转换为TensorRT支持的.uff格式,并提供了转换代码和测试步骤。
26 3
深度学习之格式转换笔记(三):keras(.hdf5)模型转TensorFlow(.pb) 转TensorRT(.uff)格式
|
1月前
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
80 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
1天前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
9 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
1月前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
67 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
5天前
|
机器学习/深度学习 移动开发 TensorFlow
深度学习之格式转换笔记(四):Keras(.h5)模型转化为TensorFlow(.pb)模型
本文介绍了如何使用Python脚本将Keras模型转换为TensorFlow的.pb格式模型,包括加载模型、重命名输出节点和量化等步骤,以便在TensorFlow中进行部署和推理。
25 0
|
1月前
|
机器学习/深度学习 供应链 TensorFlow
深度学习实战营:TensorFlow+Python,打造你的数据驱动决策引擎
【9月更文挑战第13天】在数据爆炸时代,企业日益依赖精准分析进行决策。深度学习凭借其卓越的特征提取与模式识别能力,成为构建数据驱动决策引擎的关键技术。本项目通过TensorFlow和Python,利用LSTM构建零售业销量预测模型,优化库存管理和营销策略。首先确保安装TensorFlow,然后使用Keras API搭建模型,并通过训练、评估和部署流程,展示深度学习在数据驱动决策中的强大应用潜力,助力企业提升经营效率。
37 3
|
1月前
|
机器学习/深度学习 数据挖掘 TensorFlow
解锁Python数据分析新技能,TensorFlow&PyTorch双引擎驱动深度学习实战盛宴
在数据驱动时代,Python凭借简洁的语法和强大的库支持,成为数据分析与机器学习的首选语言。Pandas和NumPy是Python数据分析的基础,前者提供高效的数据处理工具,后者则支持科学计算。TensorFlow与PyTorch作为深度学习领域的两大框架,助力数据科学家构建复杂神经网络,挖掘数据深层价值。通过Python打下的坚实基础,结合TensorFlow和PyTorch的强大功能,我们能在数据科学领域探索无限可能,解决复杂问题并推动科研进步。
50 0
|
1月前
|
机器学习/深度学习 数据挖掘 TensorFlow
从数据小白到AI专家:Python数据分析与TensorFlow/PyTorch深度学习的蜕变之路
【9月更文挑战第10天】从数据新手成长为AI专家,需先掌握Python基础语法,并学会使用NumPy和Pandas进行数据分析。接着,通过Matplotlib和Seaborn实现数据可视化,最后利用TensorFlow或PyTorch探索深度学习。这一过程涉及从数据清洗、可视化到构建神经网络的多个步骤,每一步都需不断实践与学习。借助Python的强大功能及各类库的支持,你能逐步解锁数据的深层价值。
53 0
|
2月前
|
持续交付 测试技术 jenkins
JSF 邂逅持续集成,紧跟技术热点潮流,开启高效开发之旅,引发开发者强烈情感共鸣
【8月更文挑战第31天】在快速发展的软件开发领域,JavaServer Faces(JSF)这一强大的Java Web应用框架与持续集成(CI)结合,可显著提升开发效率及软件质量。持续集成通过频繁的代码集成及自动化构建测试,实现快速反馈、高质量代码、加强团队协作及简化部署流程。以Jenkins为例,配合Maven或Gradle,可轻松搭建JSF项目的CI环境,通过JUnit和Selenium编写自动化测试,确保每次构建的稳定性和正确性。
51 0
|
2月前
|
测试技术 数据库
探索JSF单元测试秘籍!如何让您的应用更稳固、更高效?揭秘成功背后的测试之道!
【8月更文挑战第31天】在 JavaServer Faces(JSF)应用开发中,确保代码质量和可维护性至关重要。本文详细介绍了如何通过单元测试实现这一目标。首先,阐述了单元测试的重要性及其对应用稳定性的影响;其次,提出了提高 JSF 应用可测试性的设计建议,如避免直接访问外部资源和使用依赖注入;最后,通过一个具体的 `UserBean` 示例,展示了如何利用 JUnit 和 Mockito 框架编写有效的单元测试。通过这些方法,不仅能够确保代码质量,还能提高开发效率和降低维护成本。
46 0