提交 64d045a0 编写于 作者: W wizardforcel

2020-09-09 18:19:24

上级 70f4bf4f
......@@ -22,11 +22,11 @@ TensorFlow 是 Python 中最受欢迎的机器学习框架之一。 通过这本
第 6 章,“使用 TensorFlow 2 识别图像”,首先查看 Google Quick Draw 1 图像数据集,其次查看 CIFAR 10 图像数据集。
第 7 章,“TensorFlow 2 和神经风格迁移”,说明如何拍摄内容图像和样式图像,然后生成混合图像。 我们将使用经过训练的 VGG19 模型中的图层来完成此任务。
第 7 章,“TensorFlow 2 和神经风格迁移”,说明如何拍摄内容图像和风格图像,然后生成混合图像。 我们将使用经过训练的 VGG19 模型中的图层来完成此任务。
第 8 章,“TensorFlow 2 和循环神经网络”首先讨论了 RNN 的一般原理,然后介绍了如何获取和准备一些文本以供模型使用。
第 9 章, “TensorFlow 估计器和 TensorFlow Hub”首先介绍了用于训练时装数据集的估器。 我们将看到估计器如何为 TensorFlow 提供简单直观的 API。 我们还将研究用于分析电影反馈数据库 IMDb 的神经网络。
第 9 章, “TensorFlow 估计器和 TensorFlow Hub”首先介绍了用于训练时装数据集的估器。 我们将看到估计器如何为 TensorFlow 提供简单直观的 API。 我们还将研究用于分析电影反馈数据库 IMDb 的神经网络。
附录,“从 tf1.12 转换为 tf2”包含一些将 tf1.12 文件转换为 tf2 的技巧。
......
......@@ -33,7 +33,7 @@ image1 = tf.zeros([7, 28, 28, 3]) # example-within-batch by height by width by
* `Dataset`由记录组成,这些记录是至少一个文本文件(`TFRecordDataset`)中的行
* 还有一个类表示通过`Dataset``tf.data.Iterator`)进行迭代的状态
让我们继续进行**估计器**,这是一个高级 API,可让您构建大大简化的机器学习程序。 估员负责培训,评估,预测和导出服务。
让我们继续进行**估计器**,这是一个高级 API,可让您构建大大简化的机器学习程序。 估员负责培训,评估,预测和导出服务。
**TensorFlow.js** 是 API 的集合,可让您使用底层 JavaScript 线性代数库或高层 API 来构建和训练模型。 因此,可以训练模型并在浏览器中运行它们。
......@@ -75,7 +75,7 @@ TensorFlow 有两种不同的版本-一个用于在 CPU 上执行,另一个用
# 内务和急切的操作
我们将首先介绍如何导入 TensorFlow,然后介绍 TensorFlow 编码样式,以及如何进行一些基本的整理工作。 之后,我们将看一些基本的 TensorFlow 操作。 您可以为这些代码片段创建 Jupyter Notebook,也可以使用自己喜欢的 IDE 创建源代码。 该代码在 GitHub 存储库中都可用。
我们将首先介绍如何导入 TensorFlow,然后介绍 TensorFlow 编码风格,以及如何进行一些基本的整理工作。 之后,我们将看一些基本的 TensorFlow 操作。 您可以为这些代码片段创建 Jupyter Notebook,也可以使用自己喜欢的 IDE 创建源代码。 该代码在 GitHub 存储库中都可用。
# 导入 TensorFlow
......@@ -88,9 +88,9 @@ print("Eager execution is: {}".format(tf.executing_eagerly()))
print("Keras version: {}".format(tf.keras.__version__))
```
# TensorFlow 的编码样式约定
# TensorFlow 的编码风格约定
对于 Python 应用程序,Google 遵守 PEP8 标准约定。 特别是,他们将 CamelCase 用于类(例如`hub.LatestModuleExporter`),将`snake_case`用于功能,方法和属性(例如`tf.math.squared_difference`)。 Google 还遵守《 Google Python 样式指南》,该指南可在[这个页面](https://github.com/google/styleguide/blob/gh-pages/pyguide.md)中找到。
对于 Python 应用程序,Google 遵守 PEP8 标准约定。 特别是,他们将 CamelCase 用于类(例如`hub.LatestModuleExporter`),将`snake_case`用于功能,方法和属性(例如`tf.math.squared_difference`)。 Google 还遵守《 Google Python 风格指南》,该指南可在[这个页面](https://github.com/google/styleguide/blob/gh-pages/pyguide.md)中找到。
# 使用急切的执行
......@@ -579,7 +579,7 @@ tf.reduce_mean(input_tensor=numbers, axis=1, keepdims=True)
开发神经网络时,例如初始化权重和偏差时,经常需要随机值。 TensorFlow 提供了多种生成这些随机值的方法。
# 使用 tf.random.normal()
# 使用`tf.random.normal()`
`tf.random.normal()`输出给定形状的张量,其中填充了来自正态分布的`dtype`类型的值。
......@@ -603,7 +603,7 @@ print(ran)
<tf.Tensor: id=13, shape=(3, 2), dtype=float32, numpy= array([[ 8.537131 , 7.6625767], [10.925293 , 11.804686 ], [ 9.3763075, 6.701221 ]], dtype=float32)>
```
# 使用 tf.random.uniform()
# 使用`tf.random.uniform()`
所需的签名是这样的:
......
......@@ -52,7 +52,7 @@ Keras 可能是不寻常的,因为它具有作为独立开源项目维护的
尽管 TensorFlow 在`tf.keras`模块中确实具有 Keras 的完整实现,但它独立于 TensorFlow 进行维护。 默认情况下,该实现具有 TensorFlow 特定的增强功能,包括对急切执行的支持。
急切的执行意味着代码的执行是命令式编程环境,而不是基于图的环境,这是在 TensorFlow(v1.5 之前)的初始产品中工作的唯一方法。 这种命令式(即刻)样式允许直观的调试,快速的开发迭代,支持 TensorFlow `SavedModel`格式,并内置支持对 CPU,GPU 甚至 Google 自己的硬件**张量处理单元****TPU**)进行分布式训练。
急切的执行意味着代码的执行是命令式编程环境,而不是基于图的环境,这是在 TensorFlow(v1.5 之前)的初始产品中工作的唯一方法。 这种命令式(即刻)风格允许直观的调试,快速的开发迭代,支持 TensorFlow `SavedModel`格式,并内置支持对 CPU,GPU 甚至 Google 自己的硬件**张量处理单元****TPU**)进行分布式训练。
TensorFlow 实施还支持`tf.data`,分发策略,导出模型(可通过 TensorFlow Lite 部署在移动和嵌入式设备上)以及用于表示和分类结构化数据的功能列。
......@@ -145,7 +145,7 @@ Keras **数据类型**(`dtypes`)与 TensorFlow Python 数据类型相同,
| `tf.string` | 可变长度字节数组 |
| `tf.bool` | 布尔型 |
| `tf.complex64` | 由两个 32 位浮点组成的复数-一个实部和虚部 |
| `tf.complex128` | 复数由两个 64 位浮点组成-一个实部和一个虚部 |
| `tf.complex128` | 由两个 64 位浮点组成的复数-一个实部和一个虚部 |
| `tf.qint8` | 量化运算中使用的 8 位有符号整数 |
| `tf.qint32` | 量化运算中使用的 32 位有符号整数 |
| `tf.quint8` | 量化运算中使用的 8 位无符号整数 |
......@@ -321,7 +321,7 @@ model3 = tf.keras.Model(inputs=inputs, outputs=predictions)
![](img/16862498-ba29-45b2-8070-4bda783bf422.png)
“无”出现在这里是因为我们没有指定我们有多少输入项(即批处理大小)。 这确实意味着*未提供*
`None`出现在这里是因为我们没有指定我们有多少输入项(即批处理大小)。 这确实意味着*未提供*
其余代码与前面的示例相同:
......@@ -340,11 +340,11 @@ model3.evaluate(test_x, test_y)
# 子类化 Keras 模型类
Keras `Model`类可以被子类化,如下面的代码所示。 Google 指出,*纯*功能样式(如前面的示例所示)比子类样式更可取(我们在此包括其内容是出于完整性的考虑,因为它很有趣)。
Keras `Model`类可以被子类化,如下面的代码所示。 Google 指出,*纯*功能风格(如前面的示例所示)比子类风格更可取(我们在此包括其内容是出于完整性的考虑,因为它很有趣)。
首先,请注意如何在构造函数(`.__init__()`)中分别声明和命名图层。
然后,注意在`call()`方法中各层如何以功能样式链接在一起。 此方法封装了*前向传播*
然后,注意在`call()`方法中各层如何以功能风格链接在一起。 此方法封装了*前向传播*
```py
class MyModel(tf.keras.Model):
......@@ -384,7 +384,7 @@ model4.fit(train_x, train_y, batch_size=batch_size, epochs=epochs)
model4.evaluate(test_x, test_y)
```
结果是`0.068`的损失,准确性为`0.982`; 再次与本章中其他三种模型构建样式产生的结果几乎相同。
结果是`0.068`的损失,准确性为`0.982`; 再次与本章中其他三种模型构建风格产生的结果几乎相同。
# 使用数据管道
......
......@@ -334,7 +334,7 @@ plt.show()
# 创建编码层
接下来,我们创建编码和解码层。 我们将使用 Keras 功能 API 样式来设置模型。 我们从一个占位符开始,以(下一个)卷积层所需的格式输入:
接下来,我们创建编码和解码层。 我们将使用 Keras 功能 API 风格来设置模型。 我们从一个占位符开始,以(下一个)卷积层所需的格式输入:
```py
input_image = Input(shape=(28, 28, 1))
......
......@@ -7,7 +7,7 @@
* 快速绘图–使用 TensorFlow 进行图像分类
* 使用 TensorFlow 的 CIFAR 10 图像分类
在第一部分中,我们将使用在前几章中学到的技术开发 TensorFlow 2 模型以进行图像识别,尤其是第 2 章, *Keras,TensorFlow 的高级 API 2* 。 这将使我们能够看到如何使用 TensorFlow 2 将所有相关技术结合在一起来创建,训练和评估完整的模型。我们将利用 Quick Draw! Google 提供的图片数据集可帮助您解决此问题。
在第一部分中,我们将使用在前几章中学到的技术开发 TensorFlow 2 模型以进行图像识别,尤其是第 2 章, “Keras,TensorFlow 2 的高级 API”。 这将使我们能够看到如何使用 TensorFlow 2 将所有相关技术结合在一起来创建,训练和评估完整的模型。我们将利用 Quick Draw! Google 提供的图片数据集可帮助您解决此问题。
# 快速绘图–使用 TensorFlow 进行图像分类
......@@ -84,7 +84,7 @@ print(filenames)
```py
num_images = 1000000 ### was 100000, reduce this number if memory issues.
num_files = len(filenames) # *** we have 10 files ***
num_files = len(filenames) # we have 10 files
images_per_category = num_images//num_files
seed = np.random.randint(1, 10e7)
i=0
......@@ -359,7 +359,7 @@ with tf.device('/cpu:0'):
# 使用 TensorFlow 的 CIFAR 10 图像分类
在第二部分中,我们将研究训练模型以识别 CIFAR10 图像数据集中的图像。 这将使我们有机会举例说明顺序模型创建的稍有不同的样式
在第二部分中,我们将研究训练模型以识别 CIFAR10 图像数据集中的图像。 这将使我们有机会举例说明顺序模型创建的稍有不同的风格
# 介绍
......@@ -656,4 +656,4 @@ deer dog
在第二部分中,我们训练了一个模型来识别 CIFAR 10 图像数据集中的图像。 该数据集包含 10 类图像,是用于测试体系结构和进行超参数研究的流行数据集。 我们的准确度刚刚超过 81%。
在下一章中,我们将研究神经样式转移,其中涉及获取一个图像的内容并将第二个图像的样式强加于其上,以生成第三个混合图像。
\ No newline at end of file
在下一章中,我们将研究神经风格转移,其中涉及获取一个图像的内容并将第二个图像的风格强加于其上,以生成第三个混合图像。
\ No newline at end of file
# 使用 TensorFlow 2 进行神经风格传递
神经风格转换是一种使用神经网络将一幅图像的艺术风格施加到另一幅图像的内容上的技术,因此最终得到的是两种图像的混合体。 您开始使用的图像称为**内容图像**。 您在内容图像上加上样式的图像称为**样式参考图像**。 Google 将转换后的图像称为**输入图像**,这似乎令人困惑(输入是从两个不同来源获取输入的意思); 让我们将其称为**混合图像**。 因此,混合图像是具有样式参考图像样式的内容图像。
神经风格转换是一种使用神经网络将一幅图像的艺术风格施加到另一幅图像的内容上的技术,因此最终得到的是两种图像的混合体。 您开始使用的图像称为**内容图像**。 您在内容图像上加上风格的图像称为**风格参考图像**。 Google 将转换后的图像称为**输入图像**,这似乎令人困惑(输入是从两个不同来源获取输入的意思); 让我们将其称为**混合图像**。 因此,混合图像是具有风格参考图像风格的内容图像。
神经风格迁移通过定义两个损失函数来工作-一个描述两个图像的内容之间的差异,另一个描述两个图像之间的样式差异。
神经风格迁移通过定义两个损失函数来工作-一个描述两个图像的内容之间的差异,另一个描述两个图像之间的风格差异。
为了开始该过程,用内容图像初始化混合图像。 然后,使用反向传播将内容和内容以及混合图像的样式之间的差异(也称为损失或距离)最小化。 这将创建具有样式参考图像样式和内容图像内容的新图像(即混合图像)。
为了开始该过程,用内容图像初始化混合图像。 然后,使用反向传播将内容和内容以及混合图像的风格之间的差异(也称为损失或距离)最小化。 这将创建具有风格参考图像风格和内容图像内容的新图像(即混合图像)。
此过程中涉及一些技术-使用功能性 API,使用预训练的模型及其功能图以及使用自定义训练循环以最小化`loss`功能。 我们将在下面的代码中满足所有这些要求。
......@@ -22,7 +22,7 @@
* 使用 VGG19 架构
* 建立模型
* 计算损失
* 执行样式转换
* 执行风格转换
# 设置导入
......@@ -100,7 +100,7 @@ def show_image(image, title=None):
# 查看原始图像
接下来,我们使用对前面两个函数的调用来显示内容和样式图像,请记住图像像素必须是无符号 8 位整数类型。 `plt.subplot(1,2,1)`功能意味着在位置 1 使用一排两列的网格; `plt.subplot(1,2,2)`表示在位置 2 使用一排两列的网格:
接下来,我们使用对前面两个函数的调用来显示内容和风格图像,请记住图像像素必须是无符号 8 位整数类型。 `plt.subplot(1,2,1)`功能意味着在位置 1 使用一排两列的网格; `plt.subplot(1,2,2)`表示在位置 2 使用一排两列的网格:
```py
channel_means = [103.939, 116.779, 123.68] # means of the BGR channels, for VGG processing
......@@ -172,9 +172,9 @@ def deprocess_image(processed_image):
对于内容层,我们使用`block5`中的第二个卷积层。 之所以使用这个最高的块,是因为较早的块具有更能代表单个像素的特征图。 网络中的高层会根据对象及其在输入图像中的排列来捕获高级内容,[但不会限制重建的实际精确像素值](https://arxiv.org/abs/1508.06576)
对于样式层,我们将在每个层块中使用第一个卷积层,即`block1_conv1``block5_conv5`
对于风格层,我们将在每个层块中使用第一个卷积层,即`block1_conv1``block5_conv5`
然后保存内容和样式层的长度,以供以后使用:
然后保存内容和风格层的长度,以供以后使用:
```py
# The feature maps are obtained from this content layer
......@@ -194,17 +194,17 @@ number_of_style_layers = len(style_layers)
# 建立模型
现在,接下来是一系列功能,这些功能最终导致执行样式转换(`run_style_transfer()`)的主要功能。
现在,接下来是一系列功能,这些功能最终导致执行风格转换(`run_style_transfer()`)的主要功能。
此序列中的第一个函数`get_model()`创建我们将要使用的模型。
它首先加载训练后的`vgg_model`(已在`ImageNet`上进行训练),而没有其分类层(`include_top=False`)。 接下来,它冻结加载的模型(`vgg_model.trainable = False`)。
然后,使用列表推导获取样式和内容层的输出值,该列表推导遍历我们在上一节中指定的层的名称。
然后,使用列表推导获取风格和内容层的输出值,该列表推导遍历我们在上一节中指定的层的名称。
然后将这些输出值与 VGG 输入一起使用,以创建可以访问 VGG 层的新模型,即`get_model()`返回 Keras 模型,该模型输出已训练的 VGG19 模型的样式和内容中间层。 不必使用顶层,因为这是 VGG19 中的最终分类层,我们将不再使用。
然后将这些输出值与 VGG 输入一起使用,以创建可以访问 VGG 层的新模型,即`get_model()`返回 Keras 模型,该模型输出已训练的 VGG19 模型的风格和内容中间层。 不必使用顶层,因为这是 VGG19 中的最终分类层,我们将不再使用。
我们将创建一个输出图像,以使输出和相应要素图层上的输入/样式之间的距离(差异)最小化:
我们将创建一个输出图像,以使输出和相应要素图层上的输入/风格之间的距离(差异)最小化:
```py
def get_model():
......@@ -222,7 +222,7 @@ def get_model():
# 计算损失
现在,我们需要两个图像的内容和样式之间的损失。 我们将使用均方损失如下。 请注意,`image1 - image2`中的减法是两个图像阵列之间逐元素的。 此减法有效,因为图像已在`load_image`中调整为相同大小:
现在,我们需要两个图像的内容和风格之间的损失。 我们将使用均方损失如下。 请注意,`image1 - image2`中的减法是两个图像阵列之间逐元素的。 此减法有效,因为图像已在`load_image`中调整为相同大小:
```py
def rms_loss(image1,image2):
......@@ -237,7 +237,7 @@ def content_loss(content, target):
return rms_loss(content, target)
```
样式损失是根据称为 **Gram 矩阵**的数量定义的。 Gram 矩阵(也称为度量)是样式矩阵及其自身的转置的点积。 因为这意味着图像矩阵的每一列都与每一行相乘,所以我们可以认为原始表示中包含的空间信息已经*分配*。 结果是有关图像的非本地化信息,例如纹理,形状和权重,即其样式
风格损失是根据称为 **Gram 矩阵**的数量定义的。 Gram 矩阵(也称为度量)是风格矩阵及其自身的转置的点积。 因为这意味着图像矩阵的每一列都与每一行相乘,所以我们可以认为原始表示中包含的空间信息已经*分配*。 结果是有关图像的非本地化信息,例如纹理,形状和权重,即其风格
产生`gram_matrix`的代码如下:
......@@ -250,7 +250,7 @@ def gram_matrix(input_tensor):
return gram / tf.cast(number_of_channels, tf.float32) # scaled by the number of channels.
```
因此,样式丢失(其中`gram_target`将是混合图像上样式激活的 Gram 矩阵)如下:
因此,风格丢失(其中`gram_target`将是混合图像上风格激活的 Gram 矩阵)如下:
```py
def style_loss(style, gram_target):
......@@ -258,7 +258,7 @@ def style_loss(style, gram_target):
return rms_loss(gram_style, gram_target)
```
接下来,我们通过获取`content_image``style_image`并将它们馈入模型来找到`content_features``style_features`表示形式。 此代码分为两个块,一个用于`content_features`,另一个用于`style_features`。 对于内容块,我们加载图像,在其上调用我们的模型,最后,提取先前分配的要素图层。 `style_features`的代码是相同的,除了我们首先加载样式图像:
接下来,我们通过获取`content_image``style_image`并将它们馈入模型来找到`content_features``style_features`表示形式。 此代码分为两个块,一个用于`content_features`,另一个用于`style_features`。 对于内容块,我们加载图像,在其上调用我们的模型,最后,提取先前分配的要素图层。 `style_features`的代码是相同的,除了我们首先加载风格图像:
```py
def get_feature_representations(model, content_path, style_path):
......@@ -276,15 +276,15 @@ def get_feature_representations(model, content_path, style_path):
return style_features, content_features
```
接下来,我们需要计算总损失。 查看该方法的签名,我们可以看到,首先,我们传入模型(可以访问 VGG19 的中间层)。 接下来,进入`loss_weights`,它们是每个损失函数(`content_weight``style_weight`和总变化权重)的每个贡献的权重。 然后,我们有了初始图像,即我们正在通过优化过程更新的图像。 接下来是`gram_style_features``content_features`,分别对应于我们正在使用的样式层和内容层。
接下来,我们需要计算总损失。 查看该方法的签名,我们可以看到,首先,我们传入模型(可以访问 VGG19 的中间层)。 接下来,进入`loss_weights`,它们是每个损失函数(`content_weight``style_weight`和总变化权重)的每个贡献的权重。 然后,我们有了初始图像,即我们正在通过优化过程更新的图像。 接下来是`gram_style_features``content_features`,分别对应于我们正在使用的风格层和内容层。
首先从方法签名中复制样式`content_weight`。 然后,在我们的初始图像上调用模型。 我们的模型可以直接调用,因为我们使用的是急切执行,如我们所见,这是 TensorFlow 2 中的默认执行。此调用返回所有模型输出值。
首先从方法签名中复制风格`content_weight`。 然后,在我们的初始图像上调用模型。 我们的模型可以直接调用,因为我们使用的是急切执行,如我们所见,这是 TensorFlow 2 中的默认执行。此调用返回所有模型输出值。
然后,我们有两个类似的块,一个块用于内容,一个块用于样式。 对于第一个(内容)块,获取我们所需层中的内容和样式表示。 接下来,我们累积来自所有内容损失层的内容损失,其中每一层的贡献均被加权。
然后,我们有两个类似的块,一个块用于内容,一个块用于风格。 对于第一个(内容)块,获取我们所需层中的内容和风格表示。 接下来,我们累积来自所有内容损失层的内容损失,其中每一层的贡献均被加权。
第二个块与第一个块相似,不同之处在于,这里我们累积来自所有样式损失层的样式损失,其中每个损失层的每个贡献均被平均加权。
第二个块与第一个块相似,不同之处在于,这里我们累积来自所有风格损失层的风格损失,其中每个损失层的每个贡献均被平均加权。
最后,该函数返回总损失,样式损失和内容损失,如以下代码所示:
最后,该函数返回总损失,风格损失和内容损失,如以下代码所示:
```py
def compute_total_loss(model, loss_weights, init_image, gram_style_features, content_features):
......@@ -323,7 +323,7 @@ def compute_grads(config):
import IPython.display
```
# 执行样式转换
# 执行风格转换
执行`style_transfer`的功能很长,因此我们将分节介绍。 其签名如下:
......@@ -482,7 +482,7 @@ Image.fromarray(best_image)
# 最终展示
最后,我们有一个功能,它与`best_image`一起显示内容和样式图像:
最后,我们有一个功能,它与`best_image`一起显示内容和风格图像:
```py
def show_results(best_image, content_path, style_path, show_large_final=True):
......@@ -512,6 +512,6 @@ show_results(best_image, content_path, style_path)
# 摘要
到此结束我们对神经样式转换的研究。 我们看到了如何拍摄内容图像和样式图像并生成混合图像。 我们使用训练有素的 VGG19 模型中的图层来完成此任务。
到此结束我们对神经风格转换的研究。 我们看到了如何拍摄内容图像和风格图像并生成混合图像。 我们使用训练有素的 VGG19 模型中的图层来完成此任务。
在下一章中,我们将研究循环神经网络。 这些网络可以处理顺序的输入值,并且输入值和输出值中的一个或两个具有可变长度。
\ No newline at end of file
# 使用 TensorFlow 2 的循环神经网络
包括 ConvNet(CNN)在内的许多神经网络体系结构的主要缺点之一是它们不允许处理顺序数据。 换句话说,一个完整的功能(例如图像)必须一次全部呈现。 因此,输入是固定长度张量,而输出必须是固定长度张量。 先前特征的输出值也不会以任何方式影响当前特征。 同样,所有输入值(和输出值)都应视为彼此独立。 例如,在我们的`fashion_mnist`模型(第 4 章和“使用 TensorFlow 2” 的有监督机器学习)中,每个输入时尚图像都独立于并且完全不了解先前图像。
包括 ConvNet(CNN)在内的许多神经网络体系结构的主要缺点之一是它们不允许处理顺序数据。 换句话说,一个完整的功能(例如图像)必须一次全部呈现。 因此,输入是固定长度张量,而输出必须是固定长度张量。 先前特征的输出值也不会以任何方式影响当前特征。 同样,所有输入值(和输出值)都应视为彼此独立。 例如,在我们的`fashion_mnist`模型(第 4 章“使用 TensorFlow 2的有监督机器学习”)中,每个输入时尚图像都独立于并且完全不了解先前图像。
**循环神经网络****RNN**)克服了这个问题,并使许多新的应用成为可能。
......@@ -33,7 +33,7 @@
因此,需要一种新的体系结构来处理顺序到达的数据,并且其输入值和输出值中的一个或两个具有可变长度,例如,语言翻译应用程序中句子中的单词。 在这种情况下,模型的输入和输出都具有不同的长度,就像之前的第四种模式一样。 同样,为了预测给定当前词的后续词,还需要知道先前的词。 这种新的神经网络架构称为 RNN,专门设计用于处理顺序数据。
出现术语**递归**是因为此类模型对序列的每个元素执行相同的计算,其中每个输出都依赖于先前的输出。 从理论上讲,每个输出都取决于所有先前的输出项,但实际上,RNN 仅限于回顾少量步骤。 这种布置等效于具有存储器的 RNN,该存储器可以利用先前的计算结果。
出现术语**循环**是因为此类模型对序列的每个元素执行相同的计算,其中每个输出都依赖于先前的输出。 从理论上讲,每个输出都取决于所有先前的输出项,但实际上,RNN 仅限于回顾少量步骤。 这种布置等效于具有存储器的 RNN,该存储器可以利用先前的计算结果。
RNN 用于顺序输入值,例如时间序列,音频,视频,语音,文本,财务和天气数据。 它们在消费产品中的使用示例包括 Apple 的 Siri,Google 的 Translate 和亚马逊的 Alexa。
......@@ -41,17 +41,17 @@ RNN 用于顺序输入值,例如时间序列,音频,视频,语音,文
![](img/98b325df-dafc-40e2-9825-80f9a1985632.png)
每个 RNN 单元上的回送代表*存储器*。 前馈网络无法区分序列中的项目顺序,而 RNN 从根本上取决于项目的顺序。 例如,假设前馈网络接收到输入字符串 *aardvark* :到输入为 *d* 时,网络已经忘记了先前的输入值为 *a [**a**r* ,因此无法预测下一个 *va* 。 另一方面,在给定相同输入的情况下,循环网络“记住”先前的输入值为 *a**a**r,*,因此 *有可能*根据其先前的训练来预测 *va* 是下一个。
每个 RNN 单元上的回送代表*记忆*。 前馈网络无法区分序列中的项目顺序,而 RNN 从根本上取决于项目的顺序。 例如,假设前馈网络接收到输入字符串`aardvark`:到输入为`d`时,网络已经忘记了先前的输入值为`a``a``r`,因此无法预测下一个`va`。 另一方面,在给定相同输入的情况下,循环网络“记住”先前的输入值为`a``a``r`,因此*有可能*根据其先前的训练来预测`va`是下一个。
RNN 的每个单独项目到网络的输入称为**时间步长**。 因此,例如,在字符级 RNN 中,每个字符的输入都是一个时间步。 下图说明了 RNN 的*展开*
时间步长从 *t = 0* 开始,输入为 **X** <sub>**0**</sub> ,一直到时间步长 *t = t* ,输入为 **X <sub>t</sub>** ,相应的输出值为 **h <sub>0</sub>****h** <sub>**t**</sub> ,如下图所示:
时间步长从`t = 0`开始,输入为`X[0]`,一直到时间步长`t = t`,输入为`X[t]`,相应的输出值为`h[0]``h[t]`,如下图所示:
![](img/b33bb6fe-e10b-4a19-be19-ab717ecda115.png)
展开式循环神经网络
RNN 在称为**的时间反向传播****BPTT**)的过程中通过反向传播进行训练。 在此可以想象 RNN 的展开(也称为**展开**)会创建一系列神经网络,并且会针对每个时间步长计算误差并将其合并,以便可以将网络中的权重更新为 通常与反向传播。 例如,为了计算梯度,从而计算误差,在时间步 *t = 6* 时,我们将向后传播五个步,并对梯度求和。 但是,在尝试学习长期依赖关系时(即在相距很远的时间步之间),这种方法存在问题,因为梯度可能变得太小而使学习变得不可能或非常缓慢,或者它们可能变得 太大并淹没了网络。 这被称为消失/爆炸梯度问题,并且已经发明了各种修改方法来解决它,包括**长短期记忆****LSTM**)网络和**门控循环单元****GRU** **s**),我们将在以后使用。
RNN 在称为**沿时间反向传播****BPTT**)的过程中通过反向传播进行训练。 在此可以想象 RNN 的展开(也称为**展开**)会创建一系列神经网络,并且会针对每个时间步长计算误差并将其合并,以便可以将网络中的权重更新为 通常与反向传播。 例如,为了计算梯度,从而计算误差,在时间步`t = 6`时,我们将向后传播五个步,并对梯度求和。 但是,在尝试学习长期依赖关系时(即在相距很远的时间步之间),这种方法存在问题,因为梯度可能变得太小而使学习变得不可能或非常缓慢,或者它们可能变得 太大并淹没了网络。 这被称为消失/爆炸梯度问题,并且已经发明了各种修改方法来解决它,包括**长短期记忆****LSTM**)网络和**门控循环单元****GRU** **s**),我们将在以后使用。
下图显示了有关展开(或展开)的更多详细信息:
......@@ -61,18 +61,18 @@ RNN 在称为**的时间反向传播**(**BPTT**)的过程中通过反向传
在该图中,我们可以看到以下内容:
* **x <sub>t</sub>** 是时间步长 **t** 的输入。 例如, **x <sub>t</sub>** 可以是基于字符的 RNN 中的第十个字符,表示为来自字符集的索引。
* **s <sub>t</sub>** 是时间步 **t** 的隐藏状态,因此是网络的内存。
* **s <sub>t</sub>** 的计算公式为 *s <sub>t</sub> = f(Ux <sub>t</sub> + Ws <sub>t-1</sub> ),*,其中 *f* 是非线性函数,例如 ReLU。 **U****V****W** 是权重。
* **o <sub>t</sub>** 是时间步长 **t** 的输出。 例如,如果我们要计算字符序列中的下一个字母,它将是字符集 *o <sub>t</sub> = Vs* <sub>*t 的概率向量*</sub>
* `x[t]`是时间步长`t`的输入。 例如,`x[t]`可以是基于字符的 RNN 中的第十个字符,表示为来自字符集的索引。
* `s[t]`是时间步`t`的隐藏状态,因此是网络的内存。
* `s[t]`的计算公式为`s[t] = f(Ux[t] + Ws[t-1])`,其中`f`是非线性函数,例如 ReLU。 `U``V``W`是权重。
* `o[t]`是时间步长`t`的输出。 例如,如果我们要计算字符序列中的下一个字母,它将是字符集`o[t] = Vs[t]`的概率向量
如前所述,我们可以将 **s <sub>t</sub>** 视为网络的内存,因为它包含有关网络中较早时间步长发生了什么的信息。 请注意,权重 **U****V****W** 在每个步骤中都是共享的,因为我们在每个步骤都执行相同的计算,只是使用不同的输入值( 结果是学习权重的数量大大减少了)。 还要注意,我们可能不需要每个时间步长的输出值(如图所示)。 如果我们要进行情感分析,每个步骤都是一个词,比如说电影评论,那么我们可能只关心最终的输出(正面或负面)。
如前所述,我们可以将`s[t]`视为网络的内存,因为它包含有关网络中较早时间步长发生了什么的信息。 请注意,权重`U``V``W`在每个步骤中都是共享的,因为我们在每个步骤都执行相同的计算,只是使用不同的输入值( 结果是学习权重的数量大大减少了)。 还要注意,我们可能不需要每个时间步长的输出值(如图所示)。 如果我们要进行情感分析,每个步骤都是一个词,比如说电影评论,那么我们可能只关心最终的输出(正面或负面)。
现在,让我们看一个使用 RNN 的有趣示例,在该示例中,我们尝试以给定的写作风格创建文本。
# RNN 的应用
在此应用程序中,我们将看到如何使用基于字符的循环神经网络创建文本。 更改要使用的文本的语料库很容易(请参见下面的示例); 在这里,我们将使用查尔斯·狄更斯(Charles Dickens)的小说*大期望*。 我们将在此文本上训练网络,以便如果我们给它一个字符序列,例如 *thousan* ,它将产生序列中的下一个字符 *d* 。 此过程可以继续进行,可以通过在不断演变的序列上反复调用模型来创建更长的文本序列。
在此应用程序中,我们将看到如何使用基于字符的循环神经网络创建文本。 更改要使用的文本的语料库很容易(请参见下面的示例); 在这里,我们将使用查尔斯·狄更斯(Charles Dickens)的小说《大期望》。 我们将在此文本上训练网络,以便如果我们给它一个字符序列,例如`thousan`,它将产生序列中的下一个字符`d`。 此过程可以继续进行,可以通过在不断演变的序列上反复调用模型来创建更长的文本序列。
这是训练模型之前创建的文本的示例:
......@@ -436,7 +436,7 @@ model.summary()
![](img/c16b150d-45b6-4f82-a596-8317ae714c1d.png)
再次回想一下,我们有`84`输入值,我们可以看到,对于嵌入层, *84 * 256 = 21,504* ,对于密集层, *1024 * 84 +84(偏置单位 )= 86,100*
再次回想一下,我们有`84`输入值,我们可以看到,对于嵌入层,`84 * 256 = 21,504`,对于密集层,`1024 * 84 + 84(偏置单元)= 86,100`
# 使用我们的模型获得预测
......
# TensorFlow 估器和 TensorFlow 集线器
# TensorFlow 估器和 TensorFlow 集线器
本章分为两部分,但是此处的技术是相关的。 首先,我们将研究 TensorFlow 估器如何为 TensorFlow 提供简单的高级 API,其次,我们将研究 TensorFlow Hub 如何包含可在自己的应用程序中使用的模块。
本章分为两部分,但是此处的技术是相关的。 首先,我们将研究 TensorFlow 估器如何为 TensorFlow 提供简单的高级 API,其次,我们将研究 TensorFlow Hub 如何包含可在自己的应用程序中使用的模块。
在本章中,我们将涵盖以下主要主题:
* TensorFlow 估
* TensorFlow 估
* TensorFlow 集线器
# TensorFlow 估
# TensorFlow 估
`tf.estimator`是 TensorFlow 的高级 API。 它通过提供用于服务模型的直接训练,评估,预测和导出的方法来简化机器学习编程。
器为 TensorFlow 开发人员带来了许多优势。 与低级 API 相比,使用 Estimators 开发模型更容易,更直观。 特别是,同一模型可以在本地计算机或分布式多服务器系统上运行。 该模型也不了解其所处的处理器,即 CPU,GPU 或 TPU。 估计器还通过简化模型开发人员共享实现的过程,简化了开发过程,并且由于构建在 Keras 层上,因此使自定义更加简单。
器为 TensorFlow 开发人员带来了许多优势。 与低级 API 相比,使用 Estimators 开发模型更容易,更直观。 特别是,同一模型可以在本地计算机或分布式多服务器系统上运行。 该模型也不了解其所处的处理器,即 CPU,GPU 或 TPU。 估计器还通过简化模型开发人员共享实现的过程,简化了开发过程,并且由于构建在 Keras 层上,因此使自定义更加简单。
器会处理与 TensorFlow 模型一起使用的所有背景管线。 它们支持安全,分布式的训练循环,用于图形构建,变量初始化,数据加载,异常处理,创建检查点文件,从故障中恢复以及为 TensorBoard 保存摘要。 正如我们将看到的,由于它们创建检查点,因此它们支持在给定数量的步骤之后停止和开始训练。
器会处理与 TensorFlow 模型一起使用的所有背景管线。 它们支持安全,分布式的训练循环,用于图形构建,变量初始化,数据加载,异常处理,创建检查点文件,从故障中恢复以及为 TensorBoard 保存摘要。 正如我们将看到的,由于它们创建检查点,因此它们支持在给定数量的步骤之后停止和开始训练。
开发 Estimator 模型的过程分为四个步骤:
1. 采集数据并创建数据功能
2. 创建功能列
3. 实例化估
3. 实例化估
4. 评估模型的性能
我们将在以下代码中举例说明这些步骤。
我们之前已经看过`fashion_mnist`数据集(在第 5 章*中使用 TensorFlow 2* 进行无监督学习),因此我们将再次使用该数据集来演示估计器的用例。
我们之前已经看过`fashion_mnist`数据集(在第 5 章“将 TensorFlow 2 用于无监督学习”),因此我们将再次使用该数据集来演示估计器的用例。
# 代码
......@@ -35,7 +35,7 @@ import tensorflow as tf
import numpy as np
```
接下来,我们获取并预处理数据。 注意,`tf.keras.datasets`中方便地存在`fashion_mnist`。 数据集中的`x`值采用整数 NumPy 数组的形式,每个元素的范围为 0 到 255,代表 28 x 28 像素时尚图像中每个像素的灰度值。 为了进行培训,必须将这些值转换为 0 到 1 范围内的浮点数。`y`值采用无符号 8 位整数`(uint8)`的形式,并且必须转换为 32 位整数(`int32` ),供估工具再次使用。
接下来,我们获取并预处理数据。 注意,`tf.keras.datasets`中方便地存在`fashion_mnist`。 数据集中的`x`值采用整数 NumPy 数组的形式,每个元素的范围为 0 到 255,代表 28 x 28 像素时尚图像中每个像素的灰度值。 为了进行培训,必须将这些值转换为 0 到 1 范围内的浮点数。`y`值采用无符号 8 位整数`(uint8)`的形式,并且必须转换为 32 位整数(`int32` ),供估工具再次使用。
尽管可以用以下方法试验该超参数值,但将学习率设置为一个很小的值:
......@@ -171,7 +171,7 @@ classifier.evaluate(input_fn, steps=None, hooks=None, checkpoint_path=None, name
tensorboard --logdir=./tmp/mnist_modelx
```
此处,损耗图如下所示,其中 *x* 轴以 1,000(k)单位表示:
此处,损耗图如下所示,其中`x`轴以 1,000(k)单位表示:
![](img/5b1262f0-e388-4537-ae0f-fe7ee09b7bb9.png)
......@@ -183,7 +183,7 @@ TensorFlow Hub 是一个软件库。 其目的是提供可重用的组件(称
# IMDb(电影评论数据库)
在本节中,我们将研究一种基于 Google 的应用程序,该应用程序在**情感分析**中分析了电影评论的 IMDb 的子集。 该子集由斯坦福大学主持,包含每部电影的评论,以及情绪积极性等级为 1 到 4(差)和 7 到 10(好)的情绪。 问题在于确定关于每个电影的文本句子中表达的视图的极性,即针对每个评论,以确定它是正面评论还是负面评论。 我们将在 TensorFlow Hub 中使用一个模块,该模块先前已经过训练以生成单词嵌入。
在本节中,我们将研究一种基于 Google 的应用程序,该应用程序在**情感分析**中分析了电影评论的 IMDb 的子集。 该子集由斯坦福大学主持,包含每部电影的评论,以及情感积极性等级为 1 到 4(差)和 7 到 10(好)的情感。 问题在于确定关于每个电影的文本句子中表达的视图的极性,即针对每个评论,以确定它是正面评论还是负面评论。 我们将在 TensorFlow Hub 中使用一个模块,该模块先前已经过训练以生成单词嵌入。
词嵌入是数字的向量,因此具有相似含义的词也具有类似的向量。 这是监督学习的示例,因为评论的训练集将使用 IMDB 数据库提供的阳性值来训练模型。 然后,我们将在测试集上使用经过训练的模型,并查看其预测与 IMDB 数据库中存储的预测相比如何,从而为我们提供了一种准确度度量。
......@@ -198,22 +198,23 @@ TensorFlow Hub 是一个软件库。 其目的是提供可重用的组件(称
这是从 IMDb 火车头的顶部起的五行示例:
| | **句子** | **感觉** | **极性** |
| 0 | 我昨晚在 12 月前来这里进行审查... | 3 | 0 |
| 1 | 看,我正在阅读这些评论,并且... | 4 | 0 |
| 2 | 我被这种情绪所吸引。 刻骨铭心... | 10 | 1 |
| 3 | 如果...,这部电影可能是一部不错的 B 电影。 | 4 | 0 |
| 4 | 我对旧的黑白电影有兴趣... | 10 | 1 |
| | **句子** | **情感** | **极性** |
| --- | --- | --- | --- |
| 0 | `I came here for a review last night before dec...` | 3 | 0 |
| 1 | `Look, I'm reading and reading these comments and...` | 4 | 0 |
| 2 | `I was overtaken by the emotion. Unforgettable ...` | 10 | 1 |
| 3 | `This movie could have been a decent B-movie if...` | 4 | 0 |
| 4 | `I have a thing for old black and white movies ...` | 10 | 1 |
这是其尾部的五行:
| | 句子 | 情 | 极性 |
| | 句子 | 情 | 极性 |
| --- | --- | --- | --- |
| 24995 | 我在电影院看了一些很差的电影。 | 1 | 0 |
| 24996 | 这部电影是有计划的尝试以兑现的方式。 | 1 | 0 |
| 24997 | 这部电影写得很差。 字符... | 1 | 0 |
| 24998 | 我是 Stooges 的忠实粉丝,但是唯一的一个... | 2 | 0 |
| 24999 | 好吧,让我首先说说 H ... | 3 | 0 |
| 24995 | `I have watched some pretty poor films in the p...` | 1 | 0 |
| 24996 | `This film is a calculated attempt to cash in t...` | 1 | 0 |
| 24997 | `This movie was so very badly written. The char...` | 1 | 0 |
| 24998 | `I am a huge Stooges fan but the one and only r...` | 2 | 0 |
| 24999 | `Well, let me start off by saying how utterly H...` | 3 | 0 |
以下是测试集:
......@@ -346,7 +347,7 @@ predict_train_input_fn = tf.compat.v1.estimator.inputs.pandas_input_fn(train_df,
predict_test_input_fn = tf.compat.v1.estimator.inputs.pandas_input_fn(test_df, test_df["polarity"], shuffle=False)
```
然后,我们有功能列。 功能列是原始数据和估器之间的中介。 共有九种功能列类型。 它们根据其类型采用数值或分类数据,然后将数据转换为适用于 Estimator 的格式。 在[这个页面](https://www.tensorflow.org/guide/feature_columns)上有一个出色的描述以及许多示例。
然后,我们有功能列。 功能列是原始数据和估器之间的中介。 共有九种功能列类型。 它们根据其类型采用数值或分类数据,然后将数据转换为适用于 Estimator 的格式。 在[这个页面](https://www.tensorflow.org/guide/feature_columns)上有一个出色的描述以及许多示例。
请注意,嵌入来自`tf.hub`
......@@ -390,10 +391,10 @@ estimator.train(input_fn=train_input_fn, steps=steps);
在我们的上下文中,混淆矩阵是一个图表,显示了经过训练的模型的以下内容:
* **真实肯定**:已正确预测真实真实感性为正面的评论(右下)
* **真实否定**:已将其真实否定性感正确地预测为负面的评论(左上)
* **误报**:评论,其正确的负面情感被错误地预测为正面(右上)
* **错误否定**:评论,其真实的正面感被错误地预测为负面(左下)
* **真阳性**:已正确预测真实真实感性为正面的评论(右下)
* **真阴性**:已将其真实否定性感正确地预测为负面的评论(左上)
* **假阳性**:正确的负面情感被错误地预测为正面的评论(右上)
* **假阴性**:真实的正面感被错误地预测为负面的评论(左下)
以下是我们的训练集的混淆矩阵:
......@@ -456,7 +457,7 @@ bottom = np.sum(top)
confusion_train = 2*top/bottom
```
最后,我们使用`seaborn`方法`heatmap`绘制混淆矩阵。 此方法的签名很长且很详细,因此,查看它的最简单方法是在 Jupyter Notebook 中将光标放在 *Shift* + *选项卡*上。
最后,我们使用`seaborn`方法`heatmap`绘制混淆矩阵。 此方法的签名很长且很详细,因此,查看它的最简单方法是在 Jupyter Notebook 中将光标放在`Shift + TAB`上。
我们在这里只需要四个参数:
......@@ -487,11 +488,11 @@ plt.xlabel("Predicted");
plt.ylabel("True");
```
到此结束我们对 IMDb 情分析的研究。
到此结束我们对 IMDb 情分析的研究。
# 摘要
在本章中,我们介绍了用于训练时装数据集的估器。 我们了解了 Estimators 如何为 TensorFlow 提供简单直观的 API。
在本章中,我们介绍了用于训练时装数据集的估器。 我们了解了 Estimators 如何为 TensorFlow 提供简单直观的 API。
然后,我们查看了另一个应用程序,这一次是对 IMDb 中电影评论的情感分类。 我们看到了 TensorFlow Hub 如何为我们提供文本嵌入,即单词的向量,这是具有相似含义的单词具有相似向量的地方。
......
......@@ -10,7 +10,7 @@ Google 提供了一个名为 `tf_upgrade_v2`的命令行脚本,该脚本会将
[这里是更新脚本的实战演示](https://www.youtube.com/watch?v=JmSNUeBG-PQ&list=PLQY2H8rRoyvzoUYI26kHmKSJBedn3SQuB&index=32&t=71s),以及有关它的更多详细信息,请参见[这里](https://github.com/tensorflow/docs/blob/master/site/en/r2/guide/upgrade.md)
重要的是要注意,在运行脚本之前,不应该*手动更新*代码部分。
重要的是要注意,在运行脚本之前,不应该*手动更新*代码部分。
该脚本不会解决所有问题,但是它生成的报告将标识那些必须手动解决的问题。
......
......@@ -4,6 +4,6 @@
本节包含以下章节:
* 第 1 章和“TensorFlow 2 简介”
* 第 2 章和 “Keras,TensorFlow 2” 的高级 API
* 第 3 章和“使用 TensorFlow 2” 的 ANN 技术
\ No newline at end of file
* 第 1 章“TensorFlow 2 简介”
* 第 2 章“Keras,TensorFlow 2 的高级 API”
* 第 3 章“TensorFlow 2 和 ANN 技术”
\ No newline at end of file
......@@ -4,5 +4,5 @@
本节包含以下章节:
* 第 4 章和“使用 TensorFlow 2” 进行监督的机器学习
* 第 5 章和*使用 Tensorflow 2 的无监督学习*
\ No newline at end of file
* 第 4 章“TensorFlow 2 和监督机器学习”
* 第 5 章“Tensorflow 2 和无监督学习”
\ No newline at end of file
# 第 3 节:TensorFlow 2.00 Alpha 的神经网络应用
在本节中,我们将研究许多**人工神经网络****ANN**)应用。 这些包括图像识别,神经样式转换,文本样式生成,时尚识别以及电影评论的 IMDb 数据库的语义分析。
在本节中,我们将研究许多**人工神经网络****ANN**)应用。 这些包括图像识别,神经风格转换,文本风格生成,时尚识别以及电影评论的 IMDb 数据库的语义分析。
本节包含以下章节:
* 第 6 章和“使用 TensorFlow 2” 识别图像
* 第 7 章和“使用 TensorFlow 2” 进行神经风格迁移
* 第 8 章和*使用 Tensorflow 2 的循环神经网络*
* 第 9 章和 *TensorFlow 估算器和 TensorFlow 集线器*
\ No newline at end of file
* 第 6 章“使用 TensorFlow 2 识别图像”
* 第 7 章“将 TensorFlow 2 用于神经风格迁移”
* 第 8 章“Tensorflow 2 和循环神经网络”
* 第 9 章“TensorFlow 估计器和 TensorFlow HUB”
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册