提交 70de6394 编写于 作者: W wizardforcel

2020-09-14 11:52:03

上级 781ea579
......@@ -149,11 +149,11 @@ def my_conv_2d(input, kernel_size, num_filters, strides):
还有两个与各层一起工作的 API。 第一个是数据集 API,可轻松将数据加载和馈送到 TensorFlow 图。 第二个是指标 API,它提供工具来测试您训练有素的机器学习模型的运行状况。 我们将在本书的后面部分中学习所有这些内容。
API 堆栈的最后一层是 TensorFlow 提供的最高抽象层,这称为估计器 API。 就像使用`tf.layers`来构造权重并为单个层添加偏差一样,estimators API 封装了许多层的结构,以便我们可以将一个由多个不同层组成的整体模型定义为一个 函数调用。
API 堆栈的最后一层是 TensorFlow 提供的最高抽象层,这称为估计器 API。 就像使用`tf.layers`来构造权重并为单个层添加偏差一样,estimators API 封装了许多层的结构,以便我们可以将一个由多个不同层组成的整体模型定义为一个函数调用。
本书不会介绍 estimators API 的用法,但是如果读者希望了解有关 estimator 的更多信息,可以在 TensorFlow 网站上找到一些有用的教程。
本书将重点介绍如何使用低级 API 以及图层,数据集和指标 API 来构建,训练和评估自己的 ML 模型。 我们相信,通过使用这些较低级别的 API,读者将对 TensorFlow 的幕后工作方式有更深入的了解,并有能力更好地应对可能需要使用这些较低级别 API 的各种未来问题 级功能
本书将重点介绍如何使用低级 API 以及图层,数据集和指标 API 来构建,训练和评估自己的 ML 模型。 我们相信,通过使用这些较低级别的 API,读者将对 TensorFlow 的幕后工作方式有更深入的了解,并有能力更好地应对可能需要使用这些较低级别 API 的各种未来问题。
# 急于执行
......
......@@ -2,7 +2,7 @@
在开始本章之前,我们需要讨论一下 AI 和**机器学习****ML**)以及这两个组件如何组合在一起。 术语“人工”是指不真实或自然的事物,而“智能”是指能够理解,学习或能够解决问题的事物(在极端情况下,具有自我意识)。
正式地,人工智能研究始于 1956 年的达特茅斯会议,其中定义了 AI 及其使命。 在接下来的几年中,每个人都很乐观,因为机器能够解决代数问题和学习英语,并且在 1972 年制造了第一台机器人。但是在 1970 年代,由于过分的承诺但交付不足,出现了所谓的 AI 冬季 人工智能研究有限且资金不足。 此后,尽管 AI 通过专家系统重生,但可以显示人类水平的分析技能。 之后,第二次 AI 冬季机器学习在 1990 年代被认可为一个单独的领域,当时概率理论和统计学开始得到利用。
正式地,人工智能研究始于 1956 年的达特茅斯会议,其中定义了 AI 及其使命。 在接下来的几年中,每个人都很乐观,因为机器能够解决代数问题和学习英语,并且在 1972 年制造了第一台机器人。但是在 1970 年代,由于过分的承诺但交付不足,出现了所谓的 AI 冬季人工智能研究有限且资金不足。 此后,尽管 AI 通过专家系统重生,但可以显示人类水平的分析技能。 之后,第二次 AI 冬季机器学习在 1990 年代被认可为一个单独的领域,当时概率理论和统计学开始得到利用。
计算能力的提高和解决特定问题的决心促使 IBM 的 Deep Blue 的发展在 1997 年击败了国际象棋冠军。 迅速发展,时下的 AI 领域涵盖了许多领域,包括机器学习,计算机视觉,自然语言处理,计划调度和优化,推理/专家系统和机器人技术。
......@@ -296,7 +296,7 @@ dense_layer = tf.layers.dense(inputs=some_input_layer, units=1024, activation=tf
在这里,我们定义了一个具有 1,024 个输出的完全连接层,随后将激活 ReLU。
重要的是要注意,该层的输入必须仅具有二维,因此,如果您的输入是空间张量,例如形状为`[28 * 28 * 3]`的图像,则必须在输入之前将其重整为矢量
重要的是要注意,该层的输入必须仅具有二维,因此,如果您的输入是空间张量,例如形状为`[28 * 28 * 3]`的图像,则必须在输入之前将其重整为矢量:
```py
reshaped_input_to_dense_layer = tf.reshape(spatial_tensor_in, [-1, 28 * 28 * 3])
......@@ -602,7 +602,7 @@ tf.layers.max_pooling2d(inputs=some_input_layer, pool_size=[2, 2], strides=2)
在开始之前,有个好消息:使用 TensorFlow,您无需担心编写反向传播或梯度下降代码,而且所有常见类型的层都已实现,因此事情应该更轻松。
在此处的 TensorFlow 示例中,我们将根据您在第 1 章,“TensorFlow 简介和设置”中学到的内容进行一些更改,并使用`tf.layers` API 创建整个 我们的网络轻松自如
在此处的 TensorFlow 示例中,我们将根据您在第 1 章,“TensorFlow 简介和设置”中学到的内容进行一些更改,并轻松自如地使用`tf.layers` API 创建我们的整个网络
```py
import tensorflow as tf
......@@ -745,7 +745,7 @@ with tf.Session() as sess:
现在,我们将仅按名称和使用位置提及它们:
* **深度卷积**:用于 MobileNets,旨在使卷积对移动平台友好
* **膨胀卷积(Atrous Convolution)**:它们具有称为膨胀率的额外参数,可让您以相同的计算成本获得更大的视野(例如 3x3 CONV 可以具有相同的视野 作为 5x5 CONV
* **膨胀卷积(Atrous Convolution)**:它们具有称为膨胀率的额外参数,可让您以相同的计算成本获得更大的视野(例如 3x3 CONV 可以和 5x5 CONV 具有相同的视野
* **转置卷积(Deconvolutions)**:通常用于 CNN 自编码器和语义分割问题
# 摘要
......
......@@ -2,7 +2,7 @@
图像分类是指根据图像内容将图像分类的问题。 让我们从分类的示例任务开始,其中图片可能是狗的图像,也可能不是。 某人可能要完成此任务的一种简单方法是,像在第 1 章中所做的那样,获取输入图像,将其重塑为矢量,然后训练线性分类器(或其他某种分类器)。 ],设置和 TensorFlow 简介。 但是,您很快就会发现此主意不好,原因有几个。 除了不能很好地缩放到输入图像的大小之外,线性分类器将很难将一个图像与另一个图像分开。
与可以在图像中看到有意义的图案和内容的人类相反,计算机只能看到从 0 到 255 的数字数组。对于同一类的不同图像,这些数字在相同位置的广泛波动导致无法直接使用它们 作为分类器的输入。 从**加拿大高级研究学院****CIFAR**)数据集中获取的这 10 张示例狗图像完美地说明了此问题。 狗的外观不仅有所不同,而且它们在镜头前的姿势和位置也有所不同。 对于机器来说,每个图像一目了然,完全没有共同点,而我们人类却可以清楚地看到它们都是狗:
与可以在图像中看到有意义的图案和内容的人类相反,计算机只能看到从 0 到 255 的数字数组。对于同一类的不同图像,这些数字在相同位置的广泛波动导致无法直接将它们使用为分类器的输入。 从**加拿大高级研究学院****CIFAR**)数据集中获取的这 10 张示例狗图像完美地说明了此问题。 狗的外观不仅有所不同,而且它们在镜头前的姿势和位置也有所不同。 对于机器来说,每个图像一目了然,完全没有共同点,而我们人类却可以清楚地看到它们都是狗:
![](img/b2fdaadf-a05d-427b-9d59-32dfd2b8f848.png)
......@@ -71,7 +71,7 @@
这在直觉上是正确的,因为当`y=1`时,我们要最小化`L(y, y_hat) = - log(y_hat)`,需要最大化`y_hat`;当`y=0`时,我们要最小化`L(y, y_hat) = - log(1 - y_hat)`,需要最小化`y_hat`
在 TensorFlow 中,可以在`tf.losses`模块中找到二进制交叉熵损失。 知道我们模型的原始输出`y_hat`的名称是 logits 很有用。 在将其传递给交叉熵损失之前,我们需要对其应用 **Sigmoid** 函数,以便我们的输出在 0 到 1 之间缩放。TensorFlow 实际上将所有这些步骤组合为一个操作,如 下面的代码。 TensorFlow 还将为我们平均分批处理损失。
在 TensorFlow 中,可以在`tf.losses`模块中找到二进制交叉熵损失。 知道我们模型的原始输出`y_hat`的名称是 logits 很有用。 在将其传递给交叉熵损失之前,我们需要对其应用 **Sigmoid** 函数,以便我们的输出在 0 到 1 之间缩放。TensorFlow 实际上将所有这些步骤组合为一个操作,如下面的代码。 TensorFlow 还将为我们平均分批处理损失。
```py
loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=labels_in, logits=model_prediction)
......@@ -95,11 +95,11 @@ loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=model_logit
我们必须使用`tf.reduce_mean`,因为我们将获得批次中每个图像的损失值。 我们使用`tf.reduce_mean`来获取批次的平均损失。
我们可以像上面一样再次使用`tf.losses`模块,特别是`tf.losses.softmax_cross_entropy`模块,然后我们不需要`tf.reduce_mean`,但我们决定向您展示一种不同的方式,以便您可以看到有很多方法可以使用 在 TensorFlow 中也是如此。 随着 TensorFlow 的发展,实现相同结果的不同方法也越来越多,而且通常没有比其他方法差很多的方法。
我们可以像上面一样再次使用`tf.losses`模块,特别是`tf.losses.softmax_cross_entropy`模块,然后我们不需要`tf.reduce_mean`,但我们决定向您展示一种不同的方式,以便您可以看到,在 TensorFlow 中也有很多方法可以使用。 随着 TensorFlow 的发展,实现相同结果的不同方法也越来越多,而且通常没有比其他方法差很多的方法。
# 训练/测试数据集拆分
暂时请注意,我们需要将数据集分为两组:训练和测试。 正如第 1 章,“TensorFlow 简介和设置”中所述,这是因为我们需要以某种方式检查模型是否能够从其自身的训练样本中进行概括(是否 能够正确识别训练中从未见过的图像)。 如果我们的模型不能做到这一点,对我们来说就没有太大用处。
暂时请注意,我们需要将数据集分为两组:训练和测试。 正如第 1 章,“TensorFlow 简介和设置”中所述,这是因为我们需要以某种方式检查模型是否能够从其自身的训练样本中进行概括(是否能够正确识别训练中从未见过的图像)。 如果我们的模型不能做到这一点,对我们来说就没有太大用处。
还有一些其他要记住的重要点:
......@@ -389,7 +389,7 @@ decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps)
self.__saver = tf.train.Saver(max_to_keep=None)
```
另外,我们可以指定`tf.GPUOptions`要使用的 GPU 内存比例。 对象会话封装了执行 op 和评估张量的环境。 创建`FileWriter`对象以将摘要和事件存储到文件后,`__session.run(init)`方法运行 TensorFlow 计算的一个步骤,方法是运行必要的图形片段以执行每个操作并评估在 init 中初始化的每个张量作为部分 图的
另外,我们可以指定`tf.GPUOptions`要使用的 GPU 内存比例。 对象会话封装了执行 op 和评估张量的环境。 创建`FileWriter`对象以将摘要和事件存储到文件后,`__session.run(init)`方法运行 TensorFlow 计算的一个步骤,方法是运行必要的图形片段以执行每个操作,并评估在 init 中初始化的每个张量作为图的一部分
```py
# Avoid allocating the whole memory
......@@ -546,7 +546,7 @@ decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps)
# Xavier-Bengio 和初始化器
在了解*训练深度前馈神经网络*的难度时,Xavier Glorot 和 Yoshua Bengio 表明,如果从均匀分布`U ~ [-1/√n, 1/√n]`初始化每一层的权重,其中`n`大小 在上一层中,对于乙状结肠激活函数,顶层(更靠近输出)的神经元迅速饱和为 0。我们知道,由于乙状结肠函数的形式,激活值 0 表示权重非常大,并且 反向传播的梯度接近零。 较小的梯度值会减慢学习过程,因为早期图层中的权重停止更新或停止学习。
在了解*训练深度前馈神经网络*的难度时,Xavier Glorot 和 Yoshua Bengio 表明,如果从均匀分布`U ~ [-1/√n, 1/√n]`初始化每一层的权重,其中`n`上一层中的大小,对于乙状结肠激活函数,顶层(更靠近输出)的神经元迅速饱和为 0。我们知道,由于乙状结肠函数的形式,激活值 0 表示权重非常大,并且反向传播的梯度接近零。 较小的梯度值会减慢学习过程,因为早期图层中的权重停止更新或停止学习。
因此,我们想要的是使权重在最初确定的时间间隔内均匀分布,也就是说,权重的方差应该在我们从底层移动到顶层时保持不变。 这将使错误平稳地流到顶层,从而使网络在训练期间收敛更快。
......
......@@ -26,7 +26,7 @@
因此,用简单的话来说,将较小的卷积级联在一起可以获得与使用较大卷积相同的感受域。 这意味着我们可以用级联的小卷积代替大卷积。
请注意,由于第一卷积层和输入文件深度之间的深度不匹配(输出的深度需要保持一致),因此无法在作用于输入图像的第一个卷积层上进行此替换:还应在图像上观察我们如何 计算每层参数的数量。
请注意,由于第一卷积层和输入文件深度之间的深度不匹配(输出的深度需要保持一致),因此无法在作用于输入图像的第一个卷积层上进行此替换:还应在图像上观察我们如何计算每层参数的数量。
![](img/b41b8fa0-33ef-41f1-bf8e-7b9d3a4ede88.png)
......
......@@ -617,7 +617,7 @@ BEGAN 的一些优点如下:
在这里,我们依赖于额外输入`y`,它是输入图像的类标签。
合并`x``y`,或`z``y`的最简单方法是将它们串联在一起,这样我们的输入向量就更长。 这将创建一个更加受控制的数据集扩充系统。 这是 TensorFlow 代码中的一个示例:
合并`x``y`,或`z``y`的最简单方法是将它们串联在一起,这样我们的输入向量就更长。 这将创建一个更加受控制的数据集扩充系统。 这是 TensorFlow 代码中的一个示例:
![](img/63ca28dd-5605-482d-95b3-4e1c027f3c89.jpg)
......
......@@ -4,7 +4,7 @@
一个非常有趣的观察结果是,由于您冻结了所有其余部分(无论是检测还是分类),最终的层可以用于完成不同的任务,最终权重看起来非常相似。
这导致了迁移学习的想法。 这意味着在大量数据上训练的深度架构(例如 ImageNet)可以很好地概括化,以至于其卷积权重可以充当特征提取器,类似于常规的视觉表示,并且可以用于训练线性分类器以用于 各种任务
这导致了迁移学习的想法。 这意味着在大量数据上训练的深度架构(例如 ImageNet)可以很好地概括化,以至于其卷积权重可以充当特征提取器,类似于常规的视觉表示,并且可以用于为各种任务训练线性分类器
本章旨在教读者如何在 TensorFlow 中采用现成的训练有素的模型,更改其结构以及为特定任务重新训练某些层。 我们将看到迁移学习将如何帮助改善结果并加快训练时间。
......@@ -17,7 +17,7 @@
研究表明,在 ImageNet 上训练的卷积网络权重中的特征提取优于常规特征提取方法,例如 SURF,可变形部分描述符(**DPD**),**直方图定向梯度****HOG**)和**词袋****BoW**)。 这意味着无论常规视觉表示如何工作,卷积特征都可以同样好地使用,唯一的缺点是更深的架构可能需要更长的时间来提取特征。
当在 ImageNet 上训练深层卷积神经网络时,第一层中的卷积滤波器的可视化(请参见下图)显示,他们学习了*低层*特征,类似于边缘检测滤波器,而卷积滤波器 在最后一层学习*高级*功能,这些功能捕获特定于类的信息。 因此,如果我们在第一个池化层之后提取 ImageNet 的特征并将其嵌入 2D 空间(例如,使用 t-SNE),则可视化将显示数据中存在一些无政府状态,而如果执行 在全连接层上相同,我们将注意到具有相同语义信息的数据被组织成簇。 这意味着网络可以在更高层次上很好地概括,并且有可能将这种知识转移到看不见的类别中。
当在 ImageNet 上训练深层卷积神经网络时,第一层中的卷积滤波器的可视化(请参见下图)显示,他们学习了*低层*特征,类似于边缘检测滤波器,而卷积滤波器在最后一层学习*高级*功能,这些功能捕获特定于类的信息。 因此,如果我们在第一个池化层之后提取 ImageNet 的特征并将其嵌入 2D 空间(例如,使用 t-SNE),则可视化将显示数据中存在一些无中心状态,而如果在全连接层上执行相同操作,我们将注意到具有相同语义信息的数据被组织成簇。 这意味着网络可以在更高层次上很好地概括,并且有可能将这种知识转移到看不见的类别中。
![](img/b7b186d6-7803-4517-add9-f559586b2576.png)
......
......@@ -48,11 +48,11 @@
# 开发和测试集不匹配
除了拆分数据之外,数据的分布还对神经网络的性能产生巨大影响。 应用深度学习中的大多数问题来自开发人员和测试集数据分布的不匹配。 我们需要记住,开发和测试数据应该来自类似的分发。 例如,如果我们以如下方式收集和分割人员检测数据,即从网页上收集人员的训练图像,而使用移动电话收集测试集图像,则会出现分布不匹配的情况。 这里的问题是,在训练模型时,我们会根据其在 dev 数据上的性能来微调网络的参数和体系结构,如果 dev 数据与训练数据相似且与测试数据不同,则 dev 数据中存在很高的偏差 对训练集。 在开发集上获得良好的评估结果并不一定意味着该模型可以很好地推广。 在这种情况下,对分布完全不同的集合进行测试可能会导致不良结果。 这是浪费时间和精力。 解决方案是首先合并开发集和测试集,随机将它们洗牌,最后将洗过的数据再次拆分为开发集和测试集。 这有助于在将机器学习算法成功训练到最终应用程序方面取得更快的进展。
除了拆分数据之外,数据的分布还对神经网络的性能产生巨大影响。 应用深度学习中的大多数问题来自开发人员和测试集数据分布的不匹配。 我们需要记住,开发和测试数据应该来自类似的分发。 例如,如果我们以如下方式收集和分割人员检测数据,即从网页上收集人员的训练图像,而使用移动电话收集测试集图像,则会出现分布不匹配的情况。 这里的问题是,在训练模型时,我们会根据其在 dev 数据上的性能来微调网络的参数和体系结构,如果 dev 数据与训练数据相似且与测试数据不同,则与训练集相比 dev 数据中存在很高的偏差。 在开发集上获得良好的评估结果并不一定意味着该模型可以很好地推广。 在这种情况下,对分布完全不同的集合进行测试可能会导致不良结果。 这是浪费时间和精力。 解决方案是首先合并开发集和测试集,随机将它们洗牌,最后将洗过的数据再次拆分为开发集和测试集。 这有助于在将机器学习算法成功训练到最终应用程序方面取得更快的进展。
# 何时更改开发/测试集
根据评估指标对开发/测试集执行良好但不满足客户要求(即在部署时执行不佳)的算法,表明我们在数据集中缺少正确的目标数据。 在这种情况下,我们需要对数据集进行更改,因为它对于目标应用程序而言不够代​​表性。 考虑对猫图像进行分类。 如果训练/开发/测试集使用的是高分辨率,高质量的图像(姿势完美的猫),而目标应用正在查看具有不同视角的猫或运动中的图像(模糊),则可以期望 算法在部署时表现不佳。
根据评估指标对开发/测试集执行良好但不满足客户要求(即在部署时执行不佳)的算法,表明我们在数据集中缺少正确的目标数据。 在这种情况下,我们需要对数据集进行更改,因为它对于目标应用程序而言不够代​​表性。 考虑对猫图像进行分类。 如果训练/开发/测试集使用的是高分辨率,高质量的图像(姿势完美的猫),而目标应用正在查看具有不同视角的猫或运动中的图像(模糊),则可以期望算法在部署时表现不佳。
![](img/d33ade2f-7c16-473c-974d-7ba1a204b47d.png)
......@@ -64,7 +64,7 @@
![](img/00d0d711-3009-4542-bb6e-3988f1007b50.png)
最好的方法是根据上图将其拆分。 分配 1 被拆分为训练集,其一部分用作开发集。 在这里,我们称其为“训练开发集”(因为开发集与火车集具有相同的分布)。 分布 1 主要用于训练,因为它是一个大型数据集。 发行版 2 分为测试集和开发集,它们与发行版 1 中的任一集无关。这里要强调的一点是,测试和开发集应来自同一发行版,并且属于我们实际上关心的应用程序,即 目标应用程序。 开发集和测试集通常是小的数据集,因为它们的目的是给出模型/算法的无偏性能估计。
最好的方法是根据上图将其拆分。 分配 1 被拆分为训练集,其一部分用作开发集。 在这里,我们称其为“训练开发集”(因为开发集与火车集具有相同的分布)。 分布 1 主要用于训练,因为它是一个大型数据集。 发行版 2 分为测试集和开发集,它们与发行版 1 中的任一集无关。这里要强调的一点是,测试和开发集应来自同一发行版,并且属于我们实际上关心的应用程序,即目标应用程序。 开发集和测试集通常是小的数据集,因为它们的目的是给出模型/算法的无偏性能估计。
模型在不同数据集分区上的误差差异,以及查看人为误差可为我们提供诊断偏见和方差问题的见解
......@@ -223,7 +223,7 @@ Tensorflow 已经具有其损失功能,并内置了加权选项:
这些示例很好地警告了我们的目标是在测试数据中进行均衡分配,尤其是当您使用准确性指标比较不同模型的有效性时。
比较不同算法的其他有用方法是精确调用和接收器操作特性曲线。 如果我们针对不同的阈值计算上述指标,则可以绘制这些图。 如果我们算法的输出不是二进制的(0 表示负数,1 表示正数),但分数在测试为正时接近 1,而在测试为负时接近零,那么 TP,TN,FP,FN 的数量将取决于 在我们选择的阈值上
比较不同算法的其他有用方法是精确调用和接收器操作特性曲线。 如果我们针对不同的阈值计算上述指标,则可以绘制这些图。 如果我们算法的输出不是二进制的(0 表示负数,1 表示正数),但分数在测试为正时接近 1,而在测试为负时接近零,那么 TP,TN,FP,FN 的数量将取决于我们选择的阈值
让我们以图像中猫检测为例。 对于每个区域,分类器输出一个分数,该分数显示出它对检测的信心。 如果将阈值设置为 0.5,则 0.6 的分数表示检测为阳性,而 0.45 的分数表示阴性。 如果阈值降低到 0.4,则两次检测都将变为阳性。 下表说明了前面的指标随阈值而变化的情况。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册