提交 4036167d 编写于 作者: W wizardforcel

2020-12-29 21:26:53

上级 a303e6ac
......@@ -183,7 +183,7 @@ TensorFlow 也以其生产组件而闻名。 它随附 [TensorFlow 服务](https
### Keras
为了与 TensorFlow 高效交互,我们将使用 [Keras](https://keras.io/),这是一个具有高级 API 的 Python 软件包,用于开发神经网络。 虽然 TensorFlow 专注于在计算图中彼此交互的组件,但 Keras 专门专注于神经网络。 Keras 使用 TensorFlow 作为其后端引擎,使开发此类应用变得更加容易。
为了与 TensorFlow 高效交互,我们将使用 [Keras](https://keras.io/),这是一个具有高级 API 的 Python 包,用于开发神经网络。 虽然 TensorFlow 专注于在计算图中彼此交互的组件,但 Keras 专门专注于神经网络。 Keras 使用 TensorFlow 作为其后端引擎,使开发此类应用变得更加容易。
截至 2017 年 11 月(TensorFlow 1.4 版),Keras 作为 TensorFlow 的一部分分发。 在`tf.keras`命名空间下可用。 如果安装了 TensorFlow 1.4 或更高版本,则系统中已经有 Keras 可用。
......@@ -193,13 +193,13 @@ TensorBoard 是用于探索 TensorFlow 模型的数据可视化套件,并与 T
### Jupyter 笔记本,Pandas 和 NumPy
在使用 Python 创建深度学习模型时,通常开始进行交互工作,慢慢地开发一个模型,最终将其变成结构化的软件。 在此过程中,经常使用以下三个 Python 程序包:Jupyter 笔记本,Pandas 和 NumPy:
在使用 Python 创建深度学习模型时,通常开始进行交互工作,慢慢地开发一个模型,最终将其变成结构化的软件。 在此过程中,经常使用以下三个 Python 包:Jupyter 笔记本,Pandas 和 NumPy:
* Jupyter 笔记本创建交互式 Python 会话,使用网络浏览器作为其界面
* Pandas 是用于数据操纵和分析的程序
* Pandas 是用于数据操纵和分析的包
* NumPy 是,经常用于整形数据和执行数值计算
在本书中偶尔会使用这些软件包。 它们通常不构成生产系统的一部分,但经常在浏览数据和开始构建模型时使用。 我们将更加详细地关注其他工具。
在本书中偶尔会使用这些包。 它们通常不构成生产系统的一部分,但经常在浏览数据和开始构建模型时使用。 我们将更加详细地关注其他工具。
### 注意
......@@ -208,12 +208,12 @@ Michael Heydt 的《学习 Pandas》和 Dan Toomey 的《学习 Jupyter》提供
| 组件 | 描述 | 最低版本 |
| --- | --- | --- |
| Python | 通用编程语言。 深度学习应用开发中使用的流行语言。 | 3.6 |
| TensorFlow | 开源图计算 Python 软件包,通常用于开发深度学习系统。 | 1.4 |
| Keras | 提供与 TensorFlow 的高级接口的 Python 软件包。 | 2.0.8-tf(随 TensorFlow 一起分发) |
| TensorFlow | 开源图计算 Python 包,通常用于开发深度学习系统。 | 1.4 |
| Keras | 提供与 TensorFlow 的高级接口的 Python 包。 | 2.0.8-tf(随 TensorFlow 一起分发) |
| TensorBoard | 基于浏览器的软件,用于可视化神经网络统计信息。 | 0.4.0 |
| Jupyter 笔记本 | 基于浏览器的软件,用于与 Python 会话进行交互。 | 5.2.1 |
| Pandas | 用于分析和处理数据的 Python 软件包。 | 0.21.0 |
| NumPy | 用于高性能数值计算的 Python 软件包。 | 1.13.3 |
| Pandas | 用于分析和处理数据的 Python 包。 | 0.21.0 |
| NumPy | 用于高性能数值计算的 Python 包。 | 1.13.3 |
> 表 1:创建深度学习环境所需的软件组件
......@@ -258,9 +258,9 @@ Michael Heydt 的《学习 Pandas》和 Dan Toomey 的《学习 Jupyter》提供
此将为您的系统安装所有必需的依赖项。 如果它们已经安装,则此命令应仅通知您。
这些依赖对于使用本书中的所有代码活动都是必不可少的。
这些依赖对于使用本书中的所有代码活动都是必不可少的。
作为此活动的最后一步,让我们执行脚本`test_stack.py`。 该脚本正式验证了本书所需的所有软件包是否已在系统中安装并可用。
作为此活动的最后一步,让我们执行脚本`test_stack.py`。 该脚本正式验证了本书所需的所有包是否已在系统中安装并可用。
4. 学生,运行脚本`lesson_1/activity_1/test_stack.py`,检查 Python 3,TensorFlow 和 Keras 的依赖项是否可用。 使用以下命令:
......@@ -293,7 +293,7 @@ Michael Heydt 的《学习 Pandas》和 Dan Toomey 的《学习 Jupyter》提供
如果您运行的是 Python 3.6,并且分布式 TensorFlow 滚轮是在其他版本(本例中为 3.5)下编译的,则会显示该消息。 您可以放心地忽略该消息。
一旦我们确认已安装 Python 3,TensorFlow,Keras,TensorBoard 和`requirements.txt`中概述的软件包,我们就可以继续进行有关如何训练神经网络的演示,然后继续使用这些工具的相同工具探索受过训练的网络。
一旦我们确认已安装 Python 3,TensorFlow,Keras,TensorBoard 和`requirements.txt`中概述的包,我们就可以继续进行有关如何训练神经网络的演示,然后继续使用这些工具的相同工具探索受过训练的网络。
### 注意
......
......@@ -301,7 +301,7 @@ bitcoin_recent.to_csv('data/bitcoin_recent.csv', index=False)
# 使用 Keras 作为 TensorFlow 接口
本节重点介绍 Keras。 我们之所以使用 Keras,是因为它将 TensorFlow 接口简化为通用抽象。 在后端,计算仍然在 TensorFlow 中执行,并且仍然使用 TensorFlow 组件构建图形,但是界面要简单得多。 我们花费较少的时间来担心诸如变量和运算之类的各个组件,而花费更多的时间将网络构建为计算单元。 Keras 使您可以轻松地尝试不同的架构和超参数,从而更快地向高性能解决方案迈进。
本节重点介绍 Keras。 我们之所以使用 Keras,是因为它将 TensorFlow 接口简化为通用抽象。 在后端,计算仍然在 TensorFlow 中执行,并且仍然使用 TensorFlow 组件构建图形,但是接口要简单得多。 我们花费较少的时间来担心诸如变量和运算之类的各个组件,而花费更多的时间将网络构建为计算单元。 Keras 使您可以轻松地尝试不同的架构和超参数,从而更快地向高性能解决方案迈进。
从 TensorFlow 1.4.0(2017 年 11 月)开始,Keras 现在以 TensorFlow 作为`tf.keras`正式发行。 这表明 Keras 现在已经与 TensorFlow 紧密集成,并且很可能会在很长一段时间内继续作为开源工具进行开发。
......@@ -368,7 +368,7 @@ model.predict(x=X_train)
> “代码段 2.2”:`model.predict()`的用法
前面的步骤介绍了使用神经网络的 Keras 范例。 尽管可以用非常不同的方式处理不同的架构,但是 Keras 通过使用以下三个组件简化了使用不同架构的界面:网络架构,适应性和预测性:
前面的步骤介绍了使用神经网络的 Keras 范例。 尽管可以用非常不同的方式处理不同的架构,但是 Keras 通过使用以下三个组件简化了使用不同架构的接口:网络架构,适应性和预测性:
![Model Components](img/image02_27.jpg)
......@@ -469,7 +469,7 @@ model.save('bitcoin_lstm_v0.h5')
`NumPy`是一个流行的 Python 库,用于执行数值计算。 深度学习社区使用它来操纵向量和张量,并为深度学习系统做好准备。
特别是,在为深度学习模型调整数据时,`numpy.reshape()`方法非常重要。 该模型允许对`NumPy`数组进行操作,这是类似于量和张量的 Python 对象。
特别是,在为深度学习模型调整数据时,`numpy.reshape()`方法非常重要。 该模型允许对`NumPy`数组进行操作,这是类似于量和张量的 Python 对象。
现在,我们使用 2016 年和 2017 年的星期来组织变量`close_point_relative_normalization`的价格。我们创建不同的组,每个组包含七个观测值(一周中的每一天),共 77 个完整星期。 我们之所以这样做,是因为我们有兴趣预测一周交易量的价格。
......@@ -477,7 +477,7 @@ model.save('bitcoin_lstm_v0.h5')
我们使用 ISO 标准来确定一周的开始和结束。 其他类型的组织也是完全可能的。 遵循此方法既简单又直观,但是仍有改进的空间。
LSTM 网络使用三维张量。 这些维度中的每一个都代表了网络的一项重要属性。 这些尺寸是:
LSTM 网络使用三维张量。 这些维度中的每一个都代表了网络的一项重要属性。 这些大小是:
* **周期长度**:周期长度,即,一个周期中有多少个观测值
* **周期数**:数据集中有多少个周期可用
......@@ -502,7 +502,7 @@ data = np.array(samples)
> “代码段 3”:创建不同星期组的 Python 代码段
结果变量`data`是包含所有正确尺寸的变量。 Keras LSTM 层期望这些维度以特定的顺序进行组织:要素数量,观测数量和周期长度。 让我们重塑数据集以匹配该格式:
结果变量`data`是包含所有正确大小的变量。 Keras LSTM 层期望这些维度以特定的顺序进行组织:要素数量,观测数量和周期长度。 让我们重塑数据集以匹配该格式:
```py
X_train = data[:-1,:].reshape(1, 76, 7)
......@@ -589,7 +589,7 @@ LSTM 是计算上昂贵的模型。 在现代计算机上,我们最多可能
如本课程中所述,LSTM 网络需要具有三个维度的张量。 这些维度是:周期长度,周期数和特征数。
现在,继续创建每周组,然后重新排列结果数组以匹配这些尺寸
现在,继续创建每周组,然后重新排列结果数组以匹配这些大小
4. 随时使用提供的函数`create_groups()`执行此操作:
......
......@@ -49,7 +49,7 @@
错误通过称为反向传播的过程传播。 反向传播是一种将损失函数返回的错误传播回神经网络中每个神经元的技术。 传播的错误会影响神经元的激活方式,并最终影响神经网络的输出。
许多神经网络软件包,包括 Keras,默认情况下都使用此技术。
许多神经网络包,包括 Keras,默认情况下都使用此技术。
### 注意
......@@ -393,7 +393,7 @@ return np.mean(np.abs((A - B) / A)) * 100
return np.sqrt(np.square(np.subtract(A, B)).mean())
```
每个函数都是使用 NumPy 的量方式操作实现的。 它们在相同长度的向量中效果很好。 它们旨在应用于完整的结果集。
每个函数都是使用 NumPy 的量方式操作实现的。 它们在相同长度的向量中效果很好。 它们旨在应用于完整的结果集。
使用`mape()`函数,我们现在可以了解到,我们的模型预测与测试集的价格相比,大约相差 8.4%。 这等效于约 399.6 美元的均方根误差(使用`rmse()`函数计算)。
......
......@@ -68,7 +68,7 @@
* `save()`:将模型另存为本地文件。
* `predict()`:进行并根据以周为单位的观测值的输入序列返回预测。
在本课程中,我们将使用这些方法来对我们的模型进行工作,训练,评估和发布预测。 `Model()`类是如何将基本 Keras 函数包装到 Web 应用中的示例。 前面的方法几乎与前面的课程完全一样,但是添加了语法糖以增强它们的界面。 例如,方法`train()`通过以下代码实现:
在本课程中,我们将使用这些方法来对我们的模型进行工作,训练,评估和发布预测。 `Model()`类是如何将基本 Keras 函数包装到 Web 应用中的示例。 前面的方法几乎与前面的课程完全一样,但是添加了语法糖以增强它们的接口。 例如,方法`train()`通过以下代码实现:
```py
def train(self, data=None, epochs=300, verbose=0, batch_size=1):
......@@ -173,7 +173,7 @@ M.train(model_data[i*7:7*(40 + i) + 7])
首先,我们从导入`cryptonic`开始。 Cryptonic 是为本书开发的简单软件应用,它使用 Python 类和模块实现了本节之前的所有步骤。 将 Cryptonic 视为开发相似应用的模板。
`cryptonic`作为 Python 模块随此活动一起提供。 首先,我们将启动 Jupyter 笔记本实例,然后将加载`cryptonic`程序包。
`cryptonic`作为 Python 模块随此活动一起提供。 首先,我们将启动 Jupyter 笔记本实例,然后将加载`cryptonic`包。
1. 在您的终端上使用,导航到目录`lesson_4/activity_8`,然后执行以下代码来启动 Jupyter 笔记本实例:
......
......@@ -16,7 +16,7 @@ TensorFlow 是 Google 流行的机器学习和深度学习产品。 它已迅速
第 1 章,“机器学习工具包”着眼于安装 Docker,设置机器学习 Docker 文件,与主机共享数据并运行 REST 服务以提供环境。
第 2 章,“图像数据”,教 MNIST 数字,如何获取它们,张量实际上只是多维数组,以及如何将图像数据和分类或分类数据编码为张量 。 然后,我们进行了快速回顾并采用了秘籍的方法来考虑尺寸和张量,以便为机器学习准备数据。
第 2 章,“图像数据”,教 MNIST 数字,如何获取它们,张量实际上只是多维数组,以及如何将图像数据和分类或分类数据编码为张量 。 然后,我们进行了快速回顾并采用了秘籍的方法来考虑大小和张量,以便为机器学习准备数据。
第 3 章,“经典神经网络”涵盖了很多内容! 我们看到了经典的或密集的神经网络的结构。 我们了解激活,非线性和 softmax。 然后我们建立测试和训练数据,并学习如何使用`Dropout``Flatten`构建网络。 我们还将学习有关求解器的所有知识,或者机器实际学习的方法。 然后,我们探索超参数,最后,通过网格搜索对模型进行微调。
......
......@@ -19,9 +19,9 @@ Docker 安装程序窗口
所有平台都可以在这里找到。 我们将只下载 Windows 的 MSI。 它的下载速度相对较快,将其下载到 PC 上后,只需单击 MSI 安装程序,它就会快速继续。
在 Ubuntu 上安装最好使用脚本来完成。 因此,我提供了一个示例安装脚本(`install-docker.sh`),该脚本将更新您的本地程序包管理器,以指向官方 Docker 发行版存储库,然后仅使用应用即可完成安装。
在 Ubuntu 上安装最好使用脚本来完成。 因此,我提供了一个示例安装脚本(`install-docker.sh`),该脚本将更新您的本地包管理器,以指向官方 Docker 发行版存储库,然后仅使用应用即可完成安装。
在 Linux 上安装 Docker 非常简单:只需运行我提供的`install-docker` shell 脚本即可。 软件包将更新,下载然后安装。 当结束时,只需键入`docker --help`以确保已安装所有内容:
在 Linux 上安装 Docker 非常简单:只需运行我提供的`install-docker` shell 脚本即可。 包将更新,下载然后安装。 当结束时,只需键入`docker --help`以确保已安装所有内容:
![](img/2b2fea71-0d0d-4dd8-b2a1-befc8d3d89b0.png)
......@@ -41,7 +41,7 @@ GPU 状态
# 机器学习 Docker 文件
现在,让我们开始准备准备机器学习的 Docker 文件。 在本节中,我们将研究克隆源文件,Docker 所需的基本镜像,安装其他必需的软件包,公开一个卷以便您可以共享您的工作以及公开端口以便您能够查看 Jupyter 笔记本,这是我们将用来探索机器学习的工具。
现在,让我们开始准备准备机器学习的 Docker 文件。 在本节中,我们将研究克隆源文件,Docker 所需的基本镜像,安装其他必需的包,公开一个卷以便您可以共享您的工作以及公开端口以便您能够查看 Jupyter 笔记本,这是我们将用来探索机器学习的工具。
现在,您需要获取这些部分附带的源代码。 前往[这里](https://github.com/wballard/kerasvideo/tree/2018),您可以在其中快速克隆存储库。 在这里,我们只是使用 GitHub for Windows 作为一种相对快速的方法来克隆该存储库,但是您可以以自己喜欢的任何方式使用 Git。 将这些文件放在哪个目录中都没有关系。 我们只是将它们下载到本地工作目录中。 然后,我们将使用此位置作为开始构建实际 Docker 容器的位置。
......@@ -51,7 +51,7 @@ GPU 状态
Docker 文件代码
这就是我们将用来创建环境的东西。 我们从具有 CUDA 和 cuDNN 驱动程序的基本 NVIDIA 镜像开始,它将在将来支持 GPU。 现在,在下一部分中,我们将更新容器上的软件包管理器,以确保我们具有`git``wget`更新的图形软件包,以便能够在笔记本中绘制图表:
这就是我们将用来创建环境的东西。 我们从具有 CUDA 和 cuDNN 驱动程序的基本 NVIDIA 镜像开始,它将在将来支持 GPU。 现在,在下一部分中,我们将更新容器上的包管理器,以确保我们具有`git``wget`更新的图形包,以便能够在笔记本中绘制图表:
![](img/0c02cde9-a2be-466f-9bca-41c7743b5636.png)
......@@ -63,7 +63,7 @@ Docker 文件代码
Docker 文件代码
Anaconda 是一种方便的 Python 发行版,可用于机器学习和数据科学任务,因为它带有预构建的数学库,尤其是 Pandas,NumPy,SciPy 和 scikit-learn,它们是使用优化的**英特尔数学内核库**构建的。 这是因为,即使没有 GPU,使用 Anaconda 通常也可以获得更好的性能。 它还具有以下优点:不是以 root 身份或全局方式安装在系统下,而是安装在主目录中。 因此,您可以将其添加到现有系统上,而不必担心破坏可能依赖 Python 的系统组件,例如,在用户的`bin`中或由全局软件包管理器安装的组件。
Anaconda 是一种方便的 Python 发行版,可用于机器学习和数据科学任务,因为它带有预构建的数学库,尤其是 Pandas,NumPy,SciPy 和 scikit-learn,它们是使用优化的**英特尔数学内核库**构建的。 这是因为,即使没有 GPU,使用 Anaconda 通常也可以获得更好的性能。 它还具有以下优点:不是以 root 身份或全局方式安装在系统下,而是安装在主目录中。 因此,您可以将其添加到现有系统上,而不必担心破坏可能依赖 Python 的系统组件,例如,在用户的`bin`中或由全局包管理器安装的组件。
现在,我们将在名为 Keras 的容器上设置一个用户:
......@@ -79,7 +79,7 @@ Docker 文件代码
Docker 文件代码
这将是我们在这里使用的 Python,并且我们将在其之上安装 TensorFlow 和 Keras,以拥有一个完整的环境。 您会在这里注意到我们同时使用`conda``pip`。 因此,`conda`是 Anaconda Python 随附的软件包管理器,但是您也可以使用常规的`pip`命令添加无法作为`conda`预打包图像使用的软件包。 因此,您可以始终以这种方式混合搭配以获取所需的包装。
这将是我们在这里使用的 Python,并且我们将在其之上安装 TensorFlow 和 Keras,以拥有一个完整的环境。 您会在这里注意到我们同时使用`conda``pip`。 因此,`conda`是 Anaconda Python 随附的包管理器,但是您也可以使用常规的`pip`命令添加无法作为`conda`预打包图像使用的包。 因此,您可以始终以这种方式混合搭配以获取所需的包装。
在最后几节中,我们将设置`VOLUME`
......@@ -145,7 +145,7 @@ Docker 构建输出
请注意,但是,第一次运行可能要花费 30 分钟。
方便地,在 Linux 上构建的命令与在 Windows 上使用 Docker 的命令完全相同。 但是,如果要在 Linux 主机上使用 GPU 支持,则可以选择使用`nvidia-docker`进行构建。 那么`docker build`的作用是什么? 好吧,它将获取并执行 Docker 文件,下载软件包,创建文件系统,运行命令,然后将所有这些更改保存到虚拟文件系统中,以便以后可以重用。 每次运行 Docker 容器时,它都从运行构建时的状态开始。 这样,每次运行都是一致的。
方便地,在 Linux 上构建的命令与在 Windows 上使用 Docker 的命令完全相同。 但是,如果要在 Linux 主机上使用 GPU 支持,则可以选择使用`nvidia-docker`进行构建。 那么`docker build`的作用是什么? 好吧,它将获取并执行 Docker 文件,下载包,创建文件系统,运行命令,然后将所有这些更改保存到虚拟文件系统中,以便以后可以重用。 每次运行 Docker 容器时,它都从运行构建时的状态开始。 这样,每次运行都是一致的。
既然我们已经运行了 Docker 容器,我们将继续到下一部分,在这里我们将使用 Jupyter 笔记本设置并运行 REST 服务。
......
......@@ -10,7 +10,7 @@
现在,让我们了解 MNIST 数字。 在本节中,我们将介绍为帮助我们了解如何处理图像数据而准备的`ImageData`笔记本; 下载并获取 MNIST 数字; 将图像视为原始数字; 最后,根据此数值数据可视化实际图像。
我们将要使用的代码包含在 IPython 笔记本中。 这是我们设置容器的方式,因此您将像在设置机器学习工具包最后提到的那样运行容器。 我还准备了要使用的`ImageData` IPython 笔记本。 我们将首先导入所有必需的软件包,然后打开 Matplotlib 以便自动进行绘图。 这意味着当我们显示图像时,我们不必调用`.plot`; 会自动为我们完成:
我们将要使用的代码包含在 IPython 笔记本中。 这是我们设置容器的方式,因此您将像在设置机器学习工具包最后提到的那样运行容器。 我还准备了要使用的`ImageData` IPython 笔记本。 我们将首先导入所有必需的包,然后打开 Matplotlib 以便自动进行绘图。 这意味着当我们显示图像时,我们不必调用`.plot`; 会自动为我们完成:
![](img/47fe23e8-1eae-4c41-af2d-61c998729f07.png)
......@@ -48,7 +48,7 @@ Python 元组
让我们从基础开始。 您可以想象的最基本的张量是一个张量,在编程语言中该张量仅称为数组。 它只是一个打包在一起的有序数字序列。 接下来是两个张量。 如果查看“灰度图像(数组的数组)”屏幕截图,则每一行都是一维的,而每一列是另一维的。
因此,一行一行地加起来就是两个张量。 同样,它只是一个数组数组。 您会看到其中的训练图像的括号为零; 我们实际上是在选择图像数组中的第一个图像。 因此,在图像数据之前的三个张量实际上是图像阵列,每个图像阵列都有像素的列和行。 因此,三张量是我们存储黑白图像的基本方法。
因此,一行一行地加起来就是两个张量。 同样,它只是一个数组数组。 您会看到其中的训练图像的括号为零; 我们实际上是在选择图像数组中的第一个图像。 因此,在图像数据之前的三个张量实际上是图像数组,每个图像数组都有像素的列和行。 因此,三张量是我们存储黑白图像的基本方法。
为了快速直观地显示图像,您可以看到索引 1 处的图像,`Xs``Ys`(随数字显示的坐标)仅是张量的维度。
......@@ -114,6 +114,6 @@ Python 元组
# 总结
在本章中,我们了解了 MNIST 数字,以及如何获取它们。 张量实际上只是多维数组; 我们如何将图像数据编码为张量; 我们如何将分类或分类数据编码为张量; 然后我们进行了快速回顾,并采用了秘籍的方法来考虑尺寸和张量,以获取用于机器学习的数据。
在本章中,我们了解了 MNIST 数字,以及如何获取它们。 张量实际上只是多维数组; 我们如何将图像数据编码为张量; 我们如何将分类或分类数据编码为张量; 然后我们进行了快速回顾,并采用了秘籍的方法来考虑大小和张量,以获取用于机器学习的数据。
现在,我们已经学习了如何为机器学习设置输入和输出数据,我们将继续下一章,在该章中,我们将创建一个“经典神经网络”(**CNN**)。
\ No newline at end of file
......@@ -103,7 +103,7 @@ ReLu 非线性函数-大于零。
加载`.shape`(测试)
这些尺寸以适当的方式匹配非常重要。 因此,对于训练集,第一个维度必须与您的`x``y`值(您的输入和输出)匹配,并且在您的测试集上,同样必须正确。 但也请注意,训练和测试数据的第二和第三个维度`28``28`相同,而测试和训练数据的`10`(输出维度)相同。 准备信息时,最常见的错误之一就是不对这些数据集进行排序。 但为什么?! 一言以蔽之:**过拟合**
这些大小以适当的方式匹配非常重要。 因此,对于训练集,第一个维度必须与您的`x``y`值(您的输入和输出)匹配,并且在您的测试集上,同样必须正确。 但也请注意,训练和测试数据的第二和第三个维度`28``28`相同,而测试和训练数据的`10`(输出维度)相同。 准备信息时,最常见的错误之一就是不对这些数据集进行排序。 但为什么?! 一言以蔽之:**过拟合**
过拟合本质上是指您的机器学习模型存储一组输入时。 您可以将其视为一个非常复杂的哈希表,该哈希表已使用大量数字对输入和输出映射进行了编码。 但是,通过机器学习,即使我们可以轻松拥有一个哈希表,我们也不需要哈希表。 相反,我们希望有一个模型可以处理未知输入,然后预测适当的输出。 测试数据代表那些未知的输入。 当您跨训练数据训练模型并提供测试数据时,可以使用测试数据来验证您的机器学习模型可以处理和预测从未见过的数据。
......@@ -113,7 +113,7 @@ ReLu 非线性函数-大于零。
在本节中,我们将实际构建神经网络模型,并使用`Dropout``Flatten`创建完整的神经网络。
我们将从使用函数式 Keras 模型实际组装神经网络开始,查看输入和层栈以端对端组装神经网络。 然后,我们将解释为什么会有`Dropout``Flatten`,以及它们对您的模型有什么影响。 最后,我们将显示一个模型摘要:这是一种可视化机器学习模型中参数和层总数的方法。
我们将从使用函数式 Keras 模型实际组装神经网络开始,查看输入和层栈以端对端组装神经网络。 然后,我们将解释为什么会有`Dropout``Flatten`,以及它们对您的模型有什么影响。 最后,我们将显示一个模型摘要:这是一种可视化机器学习模型中参数和层总数的方法。
在这里,我们使用的是 Keras 的函数式模型。 您可以将神经网络视为一系列层,其中每个层均由函数定义。 该函数传递一组参数以配置该层,然后将其作为参数传递给网络中的上一层,以将它们全部链接在一起。 如下面的屏幕快照所示,这小段代码实际上是一个完整的神经网络:
......@@ -121,15 +121,15 @@ ReLu 非线性函数-大于零。
Keras 函数式模型
我们从一个输入层开始,该输入层的形状与我们的一个输入样本相同。 在我们的案例中,我们选择了一张训练图像,从上一课中我们知道它的尺寸为`28x28`像素。 现在,我们将其传递给堆栈。 紧随其后的是`dropout_1`,紧接着是`dropout_2`,然后我们最终变成`softmax`激活,将其切换到输出层。 然后,我们将这些作为输入和输出组合到模型中。 然后,我们打印`summary`,如下所示:
我们从一个输入层开始,该输入层的形状与我们的一个输入样本相同。 在我们的案例中,我们选择了一张训练图像,从上一课中我们知道它的大小为`28x28`像素。 现在,我们将其传递给栈。 紧随其后的是`dropout_1`,紧接着是`dropout_2`,然后我们最终变成`softmax`激活,将其切换到输出层。 然后,我们将这些作为输入和输出组合到模型中。 然后,我们打印`summary`,如下所示:
![](img/d4a8fa97-4247-4cd4-9752-beaa163ae9df.png)
模型摘要输出
因此,您可以从中看到,首先将参数传递给层,然后将层本身传递以形成链。 那么,这些`Dropout``Flatten`层又如何呢? `Dropout`参数本质上是一个技巧。 当我们设置`Dropout`参数(这里是`0.1`)时,我们告诉神经网络要做的是在每个训练周期中随机断开 10% 的激活。 这是使神经网络学习概括。 这是真正的学习,而不是简单地记住输入数据。 `Flatten`层处理尺寸。 因为我们有一个二维的`28x28`像素输入图像,所以我们使用`Flatten`将其转换为`784`的长的一维数字字符串。 这被馈送到输出`softmax`层。
因此,您可以从中看到,首先将参数传递给层,然后将层本身传递以形成链。 那么,这些`Dropout``Flatten`层又如何呢? `Dropout`参数本质上是一个技巧。 当我们设置`Dropout`参数(这里是`0.1`)时,我们告诉神经网络要做的是在每个训练周期中随机断开 10% 的激活。 这是使神经网络学习概括。 这是真正的学习,而不是简单地记住输入数据。 `Flatten`层处理大小。 因为我们有一个二维的`28x28`像素输入图像,所以我们使用`Flatten`将其转换为`784`的长的一维数字字符串。 这被馈送到输出`softmax`层。
打印出模型摘要是弄清参数大小和尺寸的好方法。 这最终成为使用 Keras 的棘手部分之一,例如当您有一组输入样本(在我们的示例中为`28x28`图像),并且在进入`softmax`时,您需要到那时将它们转换成包含十个可能输出值的单个数组。 您可以看到形状在我们穿过每一层时如何变化。 最后,`Flatten`将每个样本的维数降低为一个维,然后将其转换为具有十个可能的输出值的维。
打印出模型摘要是弄清参数大小和大小的好方法。 这最终成为使用 Keras 的棘手部分之一,例如当您有一组输入样本(在我们的示例中为`28x28`图像),并且在进入`softmax`时,您需要到那时将它们转换成包含十个可能输出值的单个数组。 您可以看到形状在我们穿过每一层时如何变化。 最后,`Flatten`将每个样本的维数降低为一个维,然后将其转换为具有十个可能的输出值的维。
好的,现在该运行模型了。 现在,我们了解了如何将包括`Dropout``Flatten`层在内的模型放到一起,我们将继续使用求解器,这是我们实际执行机器学习模型所使用的。
......
......@@ -20,7 +20,7 @@
# 元学习和少样本
从较少的数据点中学习称为**少样本学习****K 次学习**,其中`k`表示数据集中每个类的数据点的数量。 假设我们正在对猫和狗进行图像分类。 如果我们正好有一只狗和一只猫的图像,那么它被称为**单次学习**,也就是说,我们每个班级仅从一个数据点开始学习。 如果我们有 10 张狗的图像和 10 张猫的图像,则称为 10 次学习。 因此, K 次学习中的`k`意味着每个班级都有许多数据点。 还有**零次学习**,每个班级没有任何数据点。 等待。 什么? 根本没有数据点时,我们如何学习? 在这种情况下,我们将没有数据点,但是将获得有关每个类的元信息,并且将从元信息中学习。 由于我们的数据集中有两个类别,即狗和猫,因此可以将其称为双向学习`k`次学习; 因此`n`路表示我们在数据集中拥有的类的数量。
从较少的数据点中学习称为**少样本学习****K 次学习**,其中`k`表示数据集中每个类的数据点的数量。 假设我们正在对猫和狗进行图像分类。 如果我们正好有一只狗和一只猫的图像,那么它被称为**单次学习**,也就是说,我们每个类仅从一个数据点开始学习。 如果我们有 10 张狗的图像和 10 张猫的图像,则称为 10 次学习。 因此, K 次学习中的`k`意味着每个类都有许多数据点。 还有**零次学习**,每个类没有任何数据点。 等待。 什么? 根本没有数据点时,我们如何学习? 在这种情况下,我们将没有数据点,但是将获得有关每个类的元信息,并且将从元信息中学习。 由于我们的数据集中有两个类别,即狗和猫,因此可以将其称为双向学习`k`次学习; 因此`n`路表示我们在数据集中拥有的类的数量。
为了使我们的模型从一些数据点中学习,我们将以相同的方式对其进行训练。 因此,当我们有一个数据集`D`时,我们从数据集中存在的每个类中采样一些数据点,并将其称为**支持集**。 同样,我们从每个类中采样一些不同的数据点,并将其称为**查询集**。 因此,我们使用支持集训练模型,并使用查询集进行测试。 我们以**剧集形式**训练模型-也就是说,在每个剧集中,我们从数据集中`D`中采样一些数据点,准备支持集和查询集,然后在支持集上训练,并在查询集上进行测试。 因此,在一系列剧集中,我们的模型将学习如何从较小的数据集中学习。 我们将在接下来的章节中对此进行更详细的探讨。
......
......@@ -12,7 +12,7 @@
# 什么是连体网络?
连体网络是神经网络的一种特殊类型,它是最简单且使用最广泛的单发学习算法之一。 正如我们在上一章中学到的,单次学习是一种技术,其中我们每个班级仅从一个训练示例中学习。 因此,在每个类别中没有很多数据点的应用中主要使用连体网络。 例如,假设我们要为我们的组织建立一个人脸识别模型,并且在组织中有大约 500 个人在工作。 如果我们想从头开始使用**卷积神经网络****CNN**)建立人脸识别模型,那么我们需要这 500 人中的许多人来训练网络并获得准确性良好的图像。 但是显然,我们不会为这 500 个人提供很多图像,因此除非有足够的数据点,否则使用 CNN 或任何深度学习算法构建模型都是不可行的。 因此,在这种情况下,我们可以求助于复杂的单次学习算法,例如连体网络,该算法可以从更少的数据点进行学习。
连体网络是神经网络的一种特殊类型,它是最简单且使用最广泛的单发学习算法之一。 正如我们在上一章中学到的,单次学习是一种技术,其中我们每个仅从一个训练示例中学习。 因此,在每个类别中没有很多数据点的应用中主要使用连体网络。 例如,假设我们要为我们的组织建立一个人脸识别模型,并且在组织中有大约 500 个人在工作。 如果我们想从头开始使用**卷积神经网络****CNN**)建立人脸识别模型,那么我们需要这 500 人中的许多人来训练网络并获得准确性良好的图像。 但是显然,我们不会为这 500 个人提供很多图像,因此除非有足够的数据点,否则使用 CNN 或任何深度学习算法构建模型都是不可行的。 因此,在这种情况下,我们可以求助于复杂的单次学习算法,例如连体网络,该算法可以从更少的数据点进行学习。
但是,连体网络如何工作? 连体网络基本上由两个对称的神经网络组成,它们共享相同的权重和结构,并且都使用能量函数`E`最终结合在一起。 我们的连体网络的目标是了解两个输入值是相似还是相异。 假设我们有两个图像`X[1]``X2`,我们想了解两个图像是相似还是相异。
......
# 原型网络及其变体
在上一章中,我们了解了什么是连体网络以及如何将它们用于执行少量学习任务。 我们还探讨了如何使用连体网络进行人脸和音频识别。 在本章中,我们将介绍另一种有趣的几次学习算法,称为原型网络,该算法能够将其推广到训练集中没有的班级。 我们将从了解什么是原型网络开始,然后我们将了解如何使用原型网络在 omniglot 数据集中执行分类任务。 然后,我们将看到原型网络的不同变体,例如高斯原型网络和半原型网络。
在上一章中,我们了解了什么是连体网络以及如何将它们用于执行少量学习任务。 我们还探讨了如何使用连体网络进行人脸和音频识别。 在本章中,我们将介绍另一种有趣的几次学习算法,称为原型网络,该算法能够将其推广到训练集中没有的。 我们将从了解什么是原型网络开始,然后我们将了解如何使用原型网络在 omniglot 数据集中执行分类任务。 然后,我们将看到原型网络的不同变体,例如高斯原型网络和半原型网络。
在本章中,您将了解以下内容:
......@@ -37,7 +37,7 @@
在找到类原型与查询点嵌入之间的距离后,我们将 softmax 应用于该距离并获得概率。 由于我们有狮子,大象和狗这三个类,因此我们将获得三个概率。 因此,概率最高的类别将是我们查询点的类别。
由于我们希望网络从几个数据点中学习,也就是说,我们希望执行几次快照学习,因此我们以相同的方式训练网络。 因此,我们使用了间歇式训练-对于每个情节,我们从数据集中的每个班级随机采样一些数据点,我们称其为支持集,仅使用支持集而不是整个数据集来训练网络。 同样,我们从数据集中随机抽取一个点作为查询点,并尝试预测其类别。 因此,通过这种方式,我们的网络受到了如何从较小的数据点集中学习的训练。
由于我们希望网络从几个数据点中学习,也就是说,我们希望执行几次快照学习,因此我们以相同的方式训练网络。 因此,我们使用了间歇式训练-对于每个情节,我们从数据集中的每个随机采样一些数据点,我们称其为支持集,仅使用支持集而不是整个数据集来训练网络。 同样,我们从数据集中随机抽取一个点作为查询点,并尝试预测其类别。 因此,通过这种方式,我们的网络受到了如何从较小的数据点集中学习的训练。
下图显示了我们原型网络的整体流程。 如您所见,首先,我们将为支持集中的所有数据点生成嵌入,并通过在类中获取数据点的平均嵌入来构建类原型。 我们还为查询点生成嵌入。 然后,我们计算类原型与查询点嵌入之间的距离。 我们使用欧几里得距离作为距离度量。 然后,我们将 softmax 应用于此距离并获得概率。 如下图所示,由于我们的查询点是狮子,因此狮子的概率很高,为 0.9:
......@@ -218,7 +218,7 @@ def get_embeddings(support_set, h_dim, z_dim, reuse=False):
return net
```
请记住,我们不会使用整个数据集进行训练; 由于我们使用的是一次学习,因此我们从每个班级中抽取一些数据点作为支持集,并以情景方式使用支持集训练网络。
请记住,我们不会使用整个数据集进行训练; 由于我们使用的是一次学习,因此我们从每个中抽取一些数据点作为支持集,并以情景方式使用支持集训练网络。
现在,我们定义一些重要的变量-我们考虑 50 次五次学习场景:
......
......@@ -22,7 +22,7 @@
关系网络由两个重要函数组成:以`f[φ]`表示的嵌入函数和以`g[φ]`表示的关系函数。 嵌入函数用于从输入中提取特征。 如果输入是图像,则可以使用卷积网络作为嵌入函数,这将为我们提供图像的特征向量/嵌入。 如果我们的输入是文本,那么我们可以使用 LSTM 网络获取文本的嵌入。
众所周知,在一次学习中,每个班级只有一个示例。 例如,假设我们的支持集包含三个类,每个类一个示例。 如下图所示,我们有一个包含三个类别的支持集,`{Lion, Eleph, Dog}`
众所周知,在一次学习中,每个只有一个示例。 例如,假设我们的支持集包含三个类,每个类一个示例。 如下图所示,我们有一个包含三个类别的支持集,`{Lion, Eleph, Dog}`
![](img/030c5e04-cf05-4394-baad-3c43bc5f77fa.png)
......@@ -52,7 +52,7 @@
# 几次学习中的关系网络
我们已经看到了如何拍摄属于支持集中每个类别的单个图像,并在关系网络的单次学习设置中将它们与查询集中图像的关系进行比较。 但是,在几次学习设置中,每个班级将有多个数据点。 我们如何使用嵌入函数在此处学习特征表示?
我们已经看到了如何拍摄属于支持集中每个类别的单个图像,并在关系网络的单次学习设置中将它们与查询集中图像的关系进行比较。 但是,在几次学习设置中,每个将有多个数据点。 我们如何使用嵌入函数在此处学习特征表示?
假设我们有一个支持集,每个类包含一个以上的图像,如下图所示:
......
......@@ -96,17 +96,17 @@ NTM 的重要组成部分如下:
# 基于内容的寻址
在基于内容的寻址中,我们基于相似性从内存中选择值。 控制器返回一个称为`k[t]`密钥向量。 我们将这个关键向量`k[t]`与存储矩阵`M[t]`中的每一行进行比较,以了解相似性。 我们使用余弦相似度作为检查相似度的相似度度量,可以表示为:
在基于内容的寻址中,我们基于相似性从内存中选择值。 控制器返回一个称为`k[t]`向量。 我们将这个关键向量`k[t]`与存储矩阵`M[t]`中的每一行进行比较,以了解相似性。 我们使用余弦相似度作为检查相似度的相似度度量,可以表示为:
![](img/8f047120-7950-4ed1-955b-038fca78e39d.png)
我们引入了一个称为`β`的新参数,称为密钥强度。 它决定了我们的权重向量应有多集中。 基于`β`的值,我们可以增加或减小焦点-也就是说,我们可以基于按键强度`β`的值将注意力转移到特定位置。 当`β`的值较低时,我们将同等地关注所有位置; 当`β`的值较高时,我们将重点放在特定位置。
我们引入了一个称为`β`的新参数,称为强度。 它决定了我们的权重向量应有多集中。 基于`β`的值,我们可以增加或减小焦点-也就是说,我们可以基于按键强度`β`的值将注意力转移到特定位置。 当`β`的值较低时,我们将同等地关注所有位置; 当`β`的值较高时,我们将重点放在特定位置。
因此,我们的权重向量变为:
![](img/05e054c0-4540-4830-9db1-359c3e2f2ba1.png)
也就是说,密钥向量`k[t]`和存储矩阵`M[t]`之间的余弦相似度乘以密钥强度`β``w[t]^c`中的上标`c`表示它们是基于内容的权重。 代替直接使用它,我们对权重应用 softmax。 因此,我们的最终权重如下:
也就是说,键向量`k[t]`和存储矩阵`M[t]`之间的余弦相似度乘以键强度`β``w[t]^c`中的上标`c`表示它们是基于内容的权重。 代替直接使用它,我们对权重应用 softmax。 因此,我们的最终权重如下:
![](img/a2609108-50cd-476d-b757-fe14244827f8.png)
......
......@@ -17,7 +17,7 @@ OpenAI 是由 Elon Musk 和 Sam Altman 创立的非营利性,开源**人工智
# 安装 Anaconda
本书中的所有示例均使用 Anaconda 版本的 Python。 Anaconda 是 Python 的开源发行版。 它被广泛用于科学计算和处理大量数据。 它提供了一个出色的程序包管理环境。 它提供对 Windows,macOS 和 Linux 的支持。 Anaconda 随附安装了 Python 以及用于科学计算的流行软件包,例如 NumPy,SciPy 等。
本书中的所有示例均使用 Anaconda 版本的 Python。 Anaconda 是 Python 的开源发行版。 它被广泛用于科学计算和处理大量数据。 它提供了一个出色的包管理环境。 它提供对 Windows,macOS 和 Linux 的支持。 Anaconda 随附安装了 Python 以及用于科学计算的流行包,例如 NumPy,SciPy 等。
要下载 Anaconda,请访问[这里](https://www.anaconda.com/download/),您将在此处看到用于下载用于不同平台的 Anaconda 的选项。
......@@ -37,7 +37,7 @@ wget https://repo.continuum.io/archive/Anaconda3-5.0.1-Linux-x86_64.sh
bash Anaconda3-5.0.1-Linux-x86_64.sh
```
成功安装 Anaconda 后,我们需要创建一个新的 Anaconda 环境,该环境基本上是一个虚拟环境。 虚拟环境有什么需求? 假设您正在使用 Aum 版本 1.14 的项目 A 和使用 NumPy 版本 1.13 的项目 B。 因此,要进行项目 B,您可以降级 NumPy 或重新安装 Anaconda。 在每个项目中,我们使用具有不同版本的不同库,这些库不适用于其他项目。 我们使用虚拟环境来代替降级或升级版本或为新项目每次重新安装 Anaconda。 这为当前项目创建了一个隔离的环境,因此每个项目可以具有自己的依赖,并且不会影响其他项目。 我们将使用以下命令创建这样的环境,并将我们的环境命名为`universe`
成功安装 Anaconda 后,我们需要创建一个新的 Anaconda 环境,该环境基本上是一个虚拟环境。 虚拟环境有什么需求? 假设您正在使用 Aum 版本 1.14 的项目 A 和使用 NumPy 版本 1.13 的项目 B。 因此,要进行项目 B,您可以降级 NumPy 或重新安装 Anaconda。 在每个项目中,我们使用具有不同版本的不同库,这些库不适用于其他项目。 我们使用虚拟环境来代替降级或升级版本或为新项目每次重新安装 Anaconda。 这为当前项目创建了一个隔离的环境,因此每个项目可以具有自己的依赖,并且不会影响其他项目。 我们将使用以下命令创建这样的环境,并将我们的环境命名为`universe`
```py
conda create --name universe python=3.6 anaconda
......@@ -145,7 +145,7 @@ cd gym
pip install -e '.[all]'
```
前面的命令将获取`gym`存储库并以软件包的形式安装`gym`,如以下屏幕截图所示:
前面的命令将获取`gym`存储库并以包的形式安装`gym`,如以下屏幕截图所示:
![](img/00010.gif)
......@@ -179,7 +179,7 @@ sudo apt-get install python-dev
sudo apt-get install libevent-dev
```
同样,我们可以通过获取`universe`存储库并将`universe`作为软件包安装来安装 OpenAI Universe:
同样,我们可以通过获取`universe`存储库并将`universe`作为包安装来安装 OpenAI Universe:
```py
cd ~
......@@ -574,7 +574,7 @@ x = tf.constant(13)
# 占位符
可以将占位符视为变量,在其中仅定义类型和尺寸而不会分配值。 占位符定义为无值。 占位符的值将在运行时输入。 占位符有一个可选参数`shape`,它指定数据的维数。 如果`shape`设置为`None`,那么我们可以在运行时提供任意大小的数据。 可以使用`tf.placeholder()`函数定义占位符:
可以将占位符视为变量,在其中仅定义类型和大小而不会分配值。 占位符定义为无值。 占位符的值将在运行时输入。 占位符有一个可选参数`shape`,它指定数据的维数。 如果`shape`设置为`None`,那么我们可以在运行时提供任意大小的数据。 可以使用`tf.placeholder()`函数定义占位符:
```py
x = tf.placeholder("float", shape=None)
......@@ -742,7 +742,7 @@ with tf.Session() as sess:
writer.close()
```
如果查看下图,您可以轻松地了解范围如何通过将相似节点分组在一起来帮助我们降低理解的复杂性。 范围界定在处理复杂项目时被广泛使用,以更好地了解节点的功能和依赖
如果查看下图,您可以轻松地了解范围如何通过将相似节点分组在一起来帮助我们降低理解的复杂性。 范围界定在处理复杂项目时被广泛使用,以更好地了解节点的功能和依赖
![](img/00017.jpeg)
......
......@@ -79,7 +79,7 @@
![](img/00170.gif)
假设我们有两个输入, `x1``x2`,我们必须预测输出`y`]。 由于我们有两个输入,因此输入层中的神经元数将为两个。 现在,这些输入将乘以权重,然后添加偏差并将结果值传播到将应用激活函数的隐藏层。 因此,首先我们需要初始化权重矩阵。 在现实世界中,我们不知道哪个输入真正重要,因此需要权重较高才能计算输出。 因此,我们将随机初始化权重和偏差值。 我们可以将输入层和隐藏层之间的权重和偏差分别表示为`w[xh]``b[h]`。 权重矩阵的尺寸如何? 权重矩阵的尺寸必须为`[当前层中的神经元数量 * 下一层中的神经元数量]`。 这是为什么? 因为这是基本的矩阵乘法规则。 要乘以任意两个矩阵`AB`,矩阵`A`中的列数必须等于矩阵`B`中的行数。因此,权重矩阵`w[xh]`的尺寸应为`[输入层中的神经元数量 * 隐藏层中的神经元数量]`,即`2 x 4`
假设我们有两个输入, `x1``x2`,我们必须预测输出`y`]。 由于我们有两个输入,因此输入层中的神经元数将为两个。 现在,这些输入将乘以权重,然后添加偏差并将结果值传播到将应用激活函数的隐藏层。 因此,首先我们需要初始化权重矩阵。 在现实世界中,我们不知道哪个输入真正重要,因此需要权重较高才能计算输出。 因此,我们将随机初始化权重和偏差值。 我们可以将输入层和隐藏层之间的权重和偏差分别表示为`w[xh]``b[h]`。 权重矩阵的大小如何? 权重矩阵的大小必须为`[当前层中的神经元数量 * 下一层中的神经元数量]`。 这是为什么? 因为这是基本的矩阵乘法规则。 要乘以任意两个矩阵`AB`,矩阵`A`中的列数必须等于矩阵`B`中的行数。因此,权重矩阵`w[xh]`的大小应为`[输入层中的神经元数量 * 隐藏层中的神经元数量]`,即`2 x 4`
![](img/00171.jpeg)
......@@ -87,7 +87,7 @@
![](img/00172.jpeg)
应用激活函数后,我们再次将结果`a[1]`乘以新的权重矩阵,并添加在隐藏层和输出层之间流动的新偏差值。 我们可以将该权重矩阵和偏差分别表示为`w[hy]``b[y]`。 该权重矩阵`w[hy]`尺寸将为`[隐藏层中的神经元数量 * 输出层中的神经元数量]`。 由于我们在隐藏层有四个神经元,在输出层有一个神经元,因此`w[hy]`矩阵尺寸`4 x 1`。 因此,我们将`a[1]`乘以权重矩阵`w[hy]`,然后加上偏差`b[y]`并将结果传递到下一层,即输出层:
应用激活函数后,我们再次将结果`a[1]`乘以新的权重矩阵,并添加在隐藏层和输出层之间流动的新偏差值。 我们可以将该权重矩阵和偏差分别表示为`w[hy]``b[y]`。 该权重矩阵`w[hy]`大小将为`[隐藏层中的神经元数量 * 输出层中的神经元数量]`。 由于我们在隐藏层有四个神经元,在输出层有一个神经元,因此`w[hy]`矩阵大小`4 x 1`。 因此,我们将`a[1]`乘以权重矩阵`w[hy]`,然后加上偏差`b[y]`并将结果传递到下一层,即输出层:
![](img/00173.jpeg)
......@@ -729,7 +729,7 @@ CNN 通常包含三个主要层:
# 卷积层
当我们输入图像作为输入时,它实际上将转换为像素值矩阵。 这些像素值的范围为 0 到 255,此矩阵的尺寸为`[图像高度 * 图像宽度 * 通道数]`。 如果输入图像的尺寸为`64 x 64`,则像素矩阵尺寸将为`64 x 64 x 3`,其中 3 表示通道号。 灰度图像具有 1 个通道,彩色图像具有 3 个通道(RGB)。 看下面的照片。 当将此图像作为输入输入时,它将转换为像素值矩阵,我们稍后将看到。 为了更好地理解,我们将考虑灰度图像,因为灰度图像具有 1 个通道,因此我们将获得 2D 矩阵。
当我们输入图像作为输入时,它实际上将转换为像素值矩阵。 这些像素值的范围为 0 到 255,此矩阵的大小为`[图像高度 * 图像宽度 * 通道数]`。 如果输入图像的大小为`64 x 64`,则像素矩阵大小将为`64 x 64 x 3`,其中 3 表示通道号。 灰度图像具有 1 个通道,彩色图像具有 3 个通道(RGB)。 看下面的照片。 当将此图像作为输入输入时,它将转换为像素值矩阵,我们稍后将看到。 为了更好地理解,我们将考虑灰度图像,因为灰度图像具有 1 个通道,因此我们将获得 2D 矩阵。
输入图像如下:
......@@ -779,7 +779,7 @@ CNN 通常包含三个主要层:
![](img/00233.gif)
当我们有许多过滤器时,我们的网络将通过提取许多特征来更好地理解图像。 在构建 CNN 时,我们不必为此过滤矩阵指定值。 在训练过程中将学习此滤波器的最佳值。 但是,我们必须指定过滤器的数量和要使用的过滤器的尺寸
当我们有许多过滤器时,我们的网络将通过提取许多特征来更好地理解图像。 在构建 CNN 时,我们不必为此过滤矩阵指定值。 在训练过程中将学习此滤波器的最佳值。 但是,我们必须指定过滤器的数量和要使用的过滤器的大小
我们可以使用滤波器在输入矩阵上滑动一个像素,然后执行卷积运算。 我们不仅可以滑动一个像素。 我们还可以在输入矩阵上滑动任意数量的像素。 我们在输入矩阵中滑过输入矩阵的像素数称为步幅。
......@@ -795,7 +795,7 @@ CNN 通常包含三个主要层:
# 池化层
在卷积层之后,我们有了池化层。 池化层用于减少特征映射的维数,并且仅保留必要的细节,因此可以减少计算量。 例如,要确定图像中是否有一只狗,我们不想了解狗在图像中的哪个位置,我们只需要狗的特征。 因此,池化层通过仅保留重要特征来减小空间尺寸。 有多种类型的池化操作。 最大池化是最常用的池化操作之一,我们仅从窗口内的要素图中获取最大值。
在卷积层之后,我们有了池化层。 池化层用于减少特征映射的维数,并且仅保留必要的细节,因此可以减少计算量。 例如,要确定图像中是否有一只狗,我们不想了解狗在图像中的哪个位置,我们只需要狗的特征。 因此,池化层通过仅保留重要特征来减小空间大小。 有多种类型的池化操作。 最大池化是最常用的池化操作之一,我们仅从窗口内的要素图中获取最大值。
带有`2 x 2`过滤器且步幅为 2 的最大池如下所示:
......@@ -815,7 +815,7 @@ CNN 通常包含三个主要层:
![](img/00237.gif)
首先,将图像传递到卷积层,在卷积层中我们应用卷积运算以提取特征,然后将特征映射传递到池化层,在其中减小尺寸。 我们可以根据用例添加任意数量的卷积和池化层。 此后,我们可以添加一个神经网络,该神经网络的末尾有一个隐藏层,称为全连接层,该层对图像进行分类。
首先,将图像传递到卷积层,在卷积层中我们应用卷积运算以提取特征,然后将特征映射传递到池化层,在其中减小大小。 我们可以根据用例添加任意数量的卷积和池化层。 此后,我们可以添加一个神经网络,该神经网络的末尾有一个隐藏层,称为全连接层,该层对图像进行分类。
# 使用 CNN 对时尚产品分类
......@@ -919,7 +919,7 @@ y = 8 (Bag)
x = tf.placeholder(tf.float32, [None, 784])
```
我们需要将输入调整为`[p,q,r,s]`格式,其中`q``r`是输入图像的实际尺寸,即`28 x 28``s`是通道号。 由于我们只有灰度图像,因此`s`的值为`1``p`表示训练样本的数量,即批量大小。 由于我们不知道批量大小,因此可以将其设置为`-1`,并且在训练过程中会动态更改它:
我们需要将输入调整为`[p,q,r,s]`格式,其中`q``r`是输入图像的实际大小,即`28 x 28``s`是通道号。 由于我们只有灰度图像,因此`s`的值为`1``p`表示训练样本的数量,即批量大小。 由于我们不知道批量大小,因此可以将其设置为`-1`,并且在训练过程中会动态更改它:
```py
x_shaped = tf.reshape(x, [-1, 28, 28, 1])
......@@ -951,7 +951,7 @@ def maxpool2d(x):
因此,权重矩阵将初始化为`[filter_shape[0],filter_shape[1], number_of_input_channel, filter_size]`
我们将使用`5 x 5`滤镜,并将滤镜尺寸设置为`32`。 由于我们使用灰度图像,因此我们的输入通道号将为`1`。 因此,我们的权重矩阵将为`[5,5,1,32]`
我们将使用`5 x 5`滤镜,并将滤镜大小设置为`32`。 由于我们使用灰度图像,因此我们的输入通道号将为`1`。 因此,我们的权重矩阵将为`[5,5,1,32]`
```py
w_c1 = tf.Variable(tf.random_normal([5,5,1,32]))
......
......@@ -123,7 +123,7 @@ n_outputs = env.action_space.n
![](img/00263.jpeg)
现在,我们定义了`preprocess_observation`函数,用于预处理输入游戏屏幕。 我们减小图像尺寸并将图像转换为灰度:
现在,我们定义了`preprocess_observation`函数,用于预处理输入游戏屏幕。 我们减小图像大小并将图像转换为灰度:
```py
color = np.array([210, 164, 74]).mean()
......
......@@ -36,13 +36,13 @@
毁灭战士是一款非常受欢迎的第一人称射击游戏。 游戏的目标是杀死怪物。 末日是部分可观察的 MDP 的另一个示例,因为智能体(玩家)的视角限制为 90 度。 该智能体对其余环境一无所知。 现在,我们将看到如何使用 DRQN 来训练我们的经纪人玩《毁灭战士》。
代替 OpenAI Gym,我们将使用 ViZDoom 软件包来模拟 Doom 环境以训练我们的智能体。 要了解有关 ViZDoom 软件包的更多信息,[请访问其官方网站](http://vizdoom.cs.put.edu.pl/)。 我们可以使用以下命令简单地安装 ViZDoom:
代替 OpenAI Gym,我们将使用 ViZDoom 包来模拟 Doom 环境以训练我们的智能体。 要了解有关 ViZDoom 包的更多信息,[请访问其官方网站](http://vizdoom.cs.put.edu.pl/)。 我们可以使用以下命令简单地安装 ViZDoom:
```py
pip install vizdoom
```
ViZDoom 提供了许多 Doom 方案,可以在软件包文件夹`vizdoom/scenarios`中找到这些方案。
ViZDoom 提供了许多 Doom 方案,可以在包文件夹`vizdoom/scenarios`中找到这些方案。
# 基本《毁灭战士》游戏
......
......@@ -31,11 +31,11 @@ A3C 网络风起云涌,并接管了 DQN。 除了前面提到的优点之外
![](img/00292.gif)
仅通过查看上图就可以了解 A3C 的工作原理。 正如我们所讨论的,我们可以看到有多个工作程序智能体,每个工作智能体都与自己的环境副本进行交互。 然后,工作人员将学习策略并计算策略损失的梯度,并将该梯度更新到全局网络。 每个智能体都会同时更新此全局网络。 A3C 的优点之一是,与 DQN 不同,我们在这里不使用经验回放内存。 实际上,这是 A3C 网络的最大优势之一。 由于我们有多个与环境交互并将信息聚合到全局网络的智能体,因此经验之间的相关性很低甚至没有。 经验回放需要占用所有经验的大量内存。 由于 A3C 不需要它,因此我们的存储空间和计算时间将减少。
仅通过查看上图就可以了解 A3C 的工作原理。 正如我们所讨论的,我们可以看到有多个工作程序智能体,每个工作智能体都与自己的环境副本进行交互。 然后,工作将学习策略并计算策略损失的梯度,并将该梯度更新到全局网络。 每个智能体都会同时更新此全局网络。 A3C 的优点之一是,与 DQN 不同,我们在这里不使用经验回放内存。 实际上,这是 A3C 网络的最大优势之一。 由于我们有多个与环境交互并将信息聚合到全局网络的智能体,因此经验之间的相关性很低甚至没有。 经验回放需要占用所有经验的大量内存。 由于 A3C 不需要它,因此我们的存储空间和计算时间将减少。
# A3C 如何运作
首先,辅助智能体重置全局网络,然后它们开始与环境进行交互。 每个工人遵循不同的探索策略以学习最佳策略。 然后,他们计算值和策略损失,然后计算损失的梯度并将梯度更新到全局网络。 随着工作人员智能体开始重置全局网络并重复相同的过程,该循环继续进行。 在查看值和策略损失函数之前,我们将了解优势函数的计算方式。 众所周知,优点是`Q`函数和值函数之间的区别:
首先,辅助智能体重置全局网络,然后它们开始与环境进行交互。 每个工作器遵循不同的探索策略以学习最佳策略。 然后,他们计算值和策略损失,然后计算损失的梯度并将梯度更新到全局网络。 随着工作器智能体开始重置全局网络并重复相同的过程,该循环继续进行。 在查看值和策略损失函数之前,我们将了解优势函数的计算方式。 众所周知,优点是`Q`函数和值函数之间的区别:
![](img/00293.jpeg)
......@@ -431,7 +431,7 @@ tensorboard --logdir=logs --port=6007 --host=127.0.0.1
![](img/00301.jpeg)
好的,工人的实际情况是什么? 让我们扩展我们的工作人员网络。 您可以看到工作节点的性能如何:
好的,工作器的实际情况是什么? 让我们扩展我们的工作器网络。 您可以看到工作节点的性能如何:
![](img/00302.jpeg)
......
......@@ -153,7 +153,7 @@ class EnvWrapper:
# 决斗网络
现在,我们构建决斗 DQN; 我们先构建三个卷积层,然后是两个全连接层,最后一个全连接层将被分为两个单独的层,用于值流和优势流。 我们将使用将值流和优势流结合在一起的聚合层来计算 q 值。 这些层的尺寸如下:
现在,我们构建决斗 DQN; 我们先构建三个卷积层,然后是两个全连接层,最后一个全连接层将被分为两个单独的层,用于值流和优势流。 我们将使用将值流和优势流结合在一起的聚合层来计算 q 值。 这些层的大小如下:
* **第 1 层**:32 个`8x8`滤镜,步幅为 4 + RELU
* **第 2 层**:64 个`4x4`滤镜,步幅为 2 + RELU
......
......@@ -60,7 +60,7 @@
![](img/973e52ab-5ebb-40a0-941c-20665d118f10.png)
同样,预测输出`y_hat`可以由输入`x`的函数表示,并由权重`W`进行参数化,如下所示:
同样,预测输出`y_hat`可以由输入`x`的函数表示,并由权重`W`进行参数化,如下所示:
![](img/9e08ed5e-7e12-46d1-a2cb-a2e343d9c8d2.png)
......@@ -262,11 +262,11 @@ ReLU 的限制条件之一是其输入负值的零梯度。 这可能会减慢
在卷积操作中,将滤镜内核的翻转版本放置在整个图像或特征映射上,并为滤镜上每个位置计算滤镜内核输入值与相应图像像素或特征映射值的点积。 输入图像或特征映射。 已经习惯了普通图像处理的读者可能已经使用了不同的滤镜内核,例如高斯滤镜,Sobel 边缘检测滤镜等,其中许多滤镜的权重已预定义。 卷积神经网络的优点是通过训练过程确定不同的滤波器权重。 这意味着,针对卷积神经网络正在处理的问题,可以更好地定制过滤器。
当卷积运算涉及在输入的每个位置上覆盖滤波器内核时,该卷积被称为跨度为 1。 如果我们选择在覆盖过滤器内核时跳过一个位置,那么卷积将以两个步幅执行。 通常,如果将`n`位置跳过而将滤波器内核覆盖在输入上,则表示卷积以`n + 1`的步幅执行。 大于 1 的步幅会减小卷积输出的空间尺寸
当卷积运算涉及在输入的每个位置上覆盖滤波器内核时,该卷积被称为跨度为 1。 如果我们选择在覆盖过滤器内核时跳过一个位置,那么卷积将以两个步幅执行。 通常,如果将`n`位置跳过而将滤波器内核覆盖在输入上,则表示卷积以`n + 1`的步幅执行。 大于 1 的步幅会减小卷积输出的空间大小
通常,卷积层之后是池化层,池化层基本上总结了由池化的接收场确定的邻域中的输出特征映射激活。 例如,一个`2 x 2`的接收场将收集四个相邻的输出特征映射激活的本地信息。 对于最大池操作,将选择四个激活的最大值作为输出,而对于平均池化,将选择四个激活的平均值。 合并降低了特征映射的空间分辨率。 例如,对于具有`2 x 2`接收场的`224 x 224`尺寸的特征映射池化操作,特征映射的空间尺寸将减小为`112 x 112`
通常,卷积层之后是池化层,池化层基本上总结了由池化的接收场确定的邻域中的输出特征映射激活。 例如,一个`2 x 2`的接收场将收集四个相邻的输出特征映射激活的本地信息。 对于最大池操作,将选择四个激活的最大值作为输出,而对于平均池化,将选择四个激活的平均值。 合并降低了特征映射的空间分辨率。 例如,对于具有`2 x 2`接收场的`224 x 224`大小的特征映射池化操作,特征映射的空间大小将减小为`112 x 112`
要注意的一件事是,卷积运算减少了每层要学习的权重数。 例如,如果我们有一个空间尺寸为`224 x 224`的输入图像,而下一层的期望输出为尺寸为` 224 x 224 `的尺寸,那么对于具有完整连接的传统神经网络来说,要学习的权重数是`224 x 224 x 224 x 224`。对于具有相同输入和输出尺寸的卷积层,我们需要学习的只是滤波器内核的权重。 因此,如果我们使用`3 x 3`过滤器内核,我们只需要学习 9 个权重即可,而不是`224 x 224 x 224 x 224`权重。 这种简化是有效的,因为局部空间邻域中的图像和音频之类的结构之间具有高度相关性。
要注意的一件事是,卷积运算减少了每层要学习的权重数。 例如,如果我们有一个空间大小为`224 x 224`的输入图像,而下一层的期望输出为大小为` 224 x 224 `的大小,那么对于具有完整连接的传统神经网络来说,要学习的权重数是`224 x 224 x 224 x 224`。对于具有相同输入和输出大小的卷积层,我们需要学习的只是滤波器内核的权重。 因此,如果我们使用`3 x 3`过滤器内核,我们只需要学习 9 个权重即可,而不是`224 x 224 x 224 x 224`权重。 这种简化是有效的,因为局部空间邻域中的图像和音频之类的结构之间具有高度相关性。
输入图像经过多层卷积和池化操作。 随着网络的发展,特征映射的数量增加,而图像的空间分辨率降低。 在卷积池层的末端,要素图的输出被馈送到全连接层,然后是输出层。
......@@ -366,7 +366,7 @@ ReLU 的限制条件之一是其输入负值的零梯度。 这可能会减慢
# 生成对抗网络
**生成对抗网络**,通常称为 **GAN** ,是通过生成器`G`学习特定概率分布的生成模型。 生成器`G`与判别器`D`进行零和极小极大游戏,并且两者都会随着时间的流逝而逐渐达到纳什均衡。 生成器尝试生成类似于给定概率分布`P(x)`生成的样本,而判别器`D`尝试区分生成器生成的那些假数据样本。`G`来自原始分布的数据样本。 发生`G`尝试通过转换样本`z`来生成与`P(x)`相似的样本。 噪声分布`P(z)`。 鉴别符`D`在假冒时学会将生成器`G`生成的样本标记为`G(z)``x`原始时属于`P(x)`。 在 minimax 游戏的平衡状态下,生成器将学习生成与原始分布`P(x)`相似的样本,因此以下是正确的:
**生成对抗网络**,通常称为 **GAN** ,是通过生成器`G`学习特定概率分布的生成模型。 生成器`G`与判别器`D`进行零和极小极大游戏,并且两者都会随着时间的流逝而逐渐达到纳什均衡。 生成器尝试生成类似于给定概率分布`P(x)`生成的样本,而判别器`D`尝试区分生成器生成的那些假数据样本。`G`来自原始分布的数据样本。 生成`G`尝试通过转换样本`z`来生成与`P(x)`相似的样本。 噪声分布`P(z)`。 鉴别符`D`在假冒时学会将生成器`G`生成的样本标记为`G(z)``x`原始时属于`P(x)`。 在 minimax 游戏的平衡状态下,生成器将学习生成与原始分布`P(x)`相似的样本,因此以下是正确的:
![](img/0bb90a7f-37ac-4079-8896-baa81ed7b81d.png)
......@@ -506,7 +506,7 @@ Figure 1.14: GAN architecture 
权重`w[ij] ∈ W`将可见单位`i`连接到隐藏单位`j`,其中`W ∈ R^(mxn)`是所有这些权重的集合,从可见单位到隐藏单位。 可见单位的偏差由`b[i] ∈ b`表示,而隐藏单位的偏差由`c[j] ∈ c`表示。
受统计物理学中玻耳兹曼分布的思想启发,可见层矢量`v`和隐藏层矢`h`的联合分布正比于配置的负能量的指数:
受统计物理学中玻耳兹曼分布的思想启发,可见层向量`v`和隐藏层向`h`的联合分布正比于配置的负能量的指数:
![](img/1aea1d38-4ac6-4663-b3a2-31b6849a03a0.png)(1)
......@@ -518,13 +518,13 @@ Figure 1.14: GAN architecture 
![](img/7e50218c-8aa9-4d4b-8d38-761ba1efb7ff.png)(2)
类似地,给出隐藏输入`h`的可见单位`i`的概率由以下公式给出:
类似地,给出隐藏输入`h`的可见单位`i`的概率由以下公式给出:
![](img/7bab8697-ec6f-46d1-8e2f-9ec1cf2bf5cc.png)(3)
因此,一旦我们通过训练了解了 RBM 的权重和偏差,就可以在给定隐藏状态的情况下对可见表示进行采样,而在给定可见状态的情况下可以对隐藏状态进行采样。
类似于**主成分分析****PCA**),RBM 是一种方法,将一个维度(由可见层`v`提供)中的数据表示为不同的维度(由隐藏层`h`提供)。 当隐藏层的尺寸小于可见层的尺寸时,RBM 执行减小尺寸的任务。 RBM 通常在二进制数据上训练。
类似于**主成分分析****PCA**),RBM 是一种方法,将一个维度(由可见层`v`提供)中的数据表示为不同的维度(由隐藏层`h`提供)。 当隐藏层的大小小于可见层的大小时,RBM 执行减小大小的任务。 RBM 通常在二进制数据上训练。
通过最大化训练数据的可能性来训练 RBM。 在成本函数相对于权重和偏差的梯度下降的每次迭代中,都会出现采样,这会使训练过程变得昂贵并且在计算上有些棘手。 一种名为**对比发散**的聪明采样方法(使用吉布斯采样)用于训练 RBM。
......@@ -534,7 +534,7 @@ Figure 1.14: GAN architecture 
与 RBM 十分相似,**自编码器**是一类无监督的学习算法,旨在发现数据中的隐藏结构。 在**主成分分析****PCA**)中,我们尝试捕获输入变量之间的线性关系,并尝试通过(输入变量的)线性组合来在降维空间中表示数据,这说明了数据的大部分差异。 但是,PCA 无法捕获输入变量之间的非线性关系。
自编码器是一种神经网络,可以捕获输入变量之间的非线性相互作用,同时在隐藏层中以不同维度表示输入。 在大多数情况下,隐藏层的尺寸小于输入的尺寸。 假设存在高维数据固有的低维结构,我们跳过了这一点。 例如,高维图像可以由低维流形表示,并且自编码器通常用于发现该结构。 下图说明了自编码器的神经架构:
自编码器是一种神经网络,可以捕获输入变量之间的非线性相互作用,同时在隐藏层中以不同维度表示输入。 在大多数情况下,隐藏层的大小小于输入的大小。 假设存在高维数据固有的低维结构,我们跳过了这一点。 例如,高维图像可以由低维流形表示,并且自编码器通常用于发现该结构。 下图说明了自编码器的神经架构:
![](img/594d3d11-05f5-4367-a760-726135cf225b.png)
......
......@@ -153,7 +153,7 @@ Softmax 将是表示输出层中不同类别的概率的最佳激活函数,而
* 丢弃具有更多样本的类别中的数据,或者丢弃低频类别的上样本,以保持样本在各个类别之间的分布均匀。
* 在损失函数中,权重与类别的密度成反比。 这将确保当模型无法对低频类别进行分类时,对成本函数施加更高的惩罚。
我们将使用方案二,因为它不需要生成更多数据或丢弃现有数据。 如果我们将班级权重与班级频率的倒数成正比,则会得到以下班级权重:
我们将使用方案二,因为它不需要生成更多数据或丢弃现有数据。 如果我们将类别权重与类别频率的倒数成正比,则会得到以下类别权重:
| **严重类别** | **类权重** |
| --- | --- |
......@@ -167,7 +167,7 @@ Softmax 将是表示输出层中不同类别的概率的最佳激活函数,而
# 预处理图像
不同类别的图像将存储在不同的文件夹中,因此可以轻松标记其类别。 我们将使用`Opencv`函数读取图像,并将其调整为不同的尺寸,例如`224 x 224 x3`。我们将基于 ImageNet 数据集从每个图像的通道方向上减去平均像素强度。 这意味着减法将使糖尿病性视网膜病变图像达到与在其上训练了预训练模型的处理过的 ImageNet 图像相同的强度范围。 提出每个图像后,它们将存储在`numpy`数组中。 图像预处理函数可以定义如下:
不同类别的图像将存储在不同的文件夹中,因此可以轻松标记其类别。 我们将使用`Opencv`函数读取图像,并将其调整为不同的大小,例如`224 x 224 x3`。我们将基于 ImageNet 数据集从每个图像的通道方向上减去平均像素强度。 这意味着减法将使糖尿病性视网膜病变图像达到与在其上训练了预训练模型的处理过的 ImageNet 图像相同的强度范围。 提出每个图像后,它们将存储在`numpy`数组中。 图像预处理函数可以定义如下:
```py
def get_im_cv2(path,dim=224):
......@@ -183,7 +183,7 @@ def get_im_cv2(path,dim=224):
```
通过`opencv`函数`imread`读取图像,然后使用线性插值方法将其调整为`(224,224,3)`或任何给定尺寸。 ImageNet 图像的红色,绿色和蓝色通道中的平均像素强度分别为`103.939``116.779``123.68`; 从图像中减去这些平均值之后,对预训练模型进行训练。 均值减法的这种活动用于使数据居中。 将数据定为零附近有助于解决消失和爆炸的梯度问题,进而帮助模型收敛更快。 同样,对每个通道进行归一化有助于保持梯度均匀地流入每个通道。 由于我们将为此项目使用预训练的模型,因此在将图像馈入预训练的网络之前,有必要根据通道平均像素值校正图像。 但是,并非必须要根据预训练网络所基于的 ImageNet 的平均值来校正图像。 您可以通过该项目的训练语料库的平均像素强度很好地进行归一化。
通过`opencv`函数`imread`读取图像,然后使用线性插值方法将其调整为`(224,224,3)`或任何给定大小。 ImageNet 图像的红色,绿色和蓝色通道中的平均像素强度分别为`103.939``116.779``123.68`; 从图像中减去这些平均值之后,对预训练模型进行训练。 均值减法的这种活动用于使数据居中。 将数据定为零附近有助于解决消失和爆炸的梯度问题,进而帮助模型收敛更快。 同样,对每个通道进行归一化有助于保持梯度均匀地流入每个通道。 由于我们将为此项目使用预训练的模型,因此在将图像馈入预训练的网络之前,有必要根据通道平均像素值校正图像。 但是,并非必须要根据预训练网络所基于的 ImageNet 的平均值来校正图像。 您可以通过该项目的训练语料库的平均像素强度很好地进行归一化。
同样,您可以选择对整个图像进行均值归一化,而不是对通道进行均值归一化。 这需要从自身中减去每个图像的平均值。 想象一下 CNN 识别的对象在不同的​​光照条件下(例如白天和晚上)曝光的场景。 无论光照条件如何,我们都希望对物体进行正确的分类,但是不同的像素强度将以不同方式激活神经网​​络的神经元,从而导致错误分类物体的可能性。 但是,如果我们从自身中减去每个图像的平均值,则对象将不再受到不同光照条件的影响。 因此,根据我们使用的图像的性质,我们可以为自己选择最佳的图像标准化方案。 但是,任何默认的标准化方法都倾向于提供合理的性能。
......@@ -427,7 +427,7 @@ reduce_lr = keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.50,
# Python 实现训练过程
以下 Python 代码块显示了训练过程的端到端实现。 它由前面各节中讨论的所有函数块组成。 让我们首先调用所需的所有 Python 程序包,如下所示:
以下 Python 代码块显示了训练过程的端到端实现。 它由前面各节中讨论的所有函数块组成。 让我们首先调用所需的所有 Python 包,如下所示:
```py
import numpy as np
......@@ -504,7 +504,7 @@ class TransferLearning:
self.outdir = args.outdir
```
接下来,让我们定义一个函数,该函数可以读取图像并将它们调整为合适的尺寸,如下所示:
接下来,让我们定义一个函数,该函数可以读取图像并将它们调整为合适的大小,如下所示:
```py
def get_im_cv2(self,path,dim=224):
......@@ -766,7 +766,7 @@ Processing Time 26009.3344039917 secs
从日志中的结果可以看出,我们达到了不错的交叉验证精度,约为`56%`,二次 Kappa 约为`0.43`
在此脚本中,我们将所有数据加载到内存中,然后将增强图像从`ImageDataGenerator`馈送到模型进行训练。 如果训练图像集很少和/或尺寸适中,那么将数据加载到内存中可能不会引起太大关注。 但是,如果图像语料库很大和/或我们资源有限,那么将所有数据加载到内存中将不是可行的选择。 由于运行这些实验的计算机具有 64 GB RAM,因此我们能够毫无问题地训练这些模型。 即使是 16 GB 的 RAM 计算机也可能不足以通过将所有数据加载到内存中来运行这些实验,并且您可能会遇到内存错误。
在此脚本中,我们将所有数据加载到内存中,然后将增强图像从`ImageDataGenerator`馈送到模型进行训练。 如果训练图像集很少和/或大小适中,那么将数据加载到内存中可能不会引起太大关注。 但是,如果图像语料库很大和/或我们资源有限,那么将所有数据加载到内存中将不是可行的选择。 由于运行这些实验的计算机具有 64 GB RAM,因此我们能够毫无问题地训练这些模型。 即使是 16 GB 的 RAM 计算机也可能不足以通过将所有数据加载到内存中来运行这些实验,并且您可能会遇到内存错误。
**问题是,我们是否需要一次将所有数据加载到内存中?**
......@@ -774,7 +774,7 @@ Processing Time 26009.3344039917 secs
# 训练期间动态创建小批量
仅加载与小批量对应的数据的一种方法是通过从其位置随机处理图像来动态创建小批量。 小批量处理的图像数量将等于我们指定的小批量大小。 当然,由于在训练期间会动态创建小批量生产,因此在训练过程中会遇到一些瓶颈,但是这一瓶颈可以忽略不计。 特殊的软件包,例如`keras`,具有有效的动态批量创建机制。 我们将在训练过程中利用 keras 中的`flow_from_directory`函数动态创建迷你批,以减少训练过程的内存需求。 我们仍将继续使用`ImageDataGenerator`进行图像增强。 可以如下定义火车生成器和验证生成器。
仅加载与小批量对应的数据的一种方法是通过从其位置随机处理图像来动态创建小批量。 小批量处理的图像数量将等于我们指定的小批量大小。 当然,由于在训练期间会动态创建小批量生产,因此在训练过程中会遇到一些瓶颈,但是这一瓶颈可以忽略不计。 特殊的包,例如`keras`,具有有效的动态批量创建机制。 我们将在训练过程中利用 keras 中的`flow_from_directory`函数动态创建迷你批,以减少训练过程的内存需求。 我们仍将继续使用`ImageDataGenerator`进行图像增强。 可以如下定义火车生成器和验证生成器。
通过将`pre_process`函数作为输入输入到`ImageDataGenerator``preprocessing_function`中,完成从三个通道中减去平均图像像素强度的图像预处理步骤:
......@@ -817,7 +817,7 @@ Processing Time 26009.3344039917 secs
`flow_from_directory`函数将一个图像目录作为输入,并期望一个与该图像目录中的类有关的文件夹。 然后,它从文件夹名称推断类标签。 如果图像目录的图像目录具有以下结构,则将类别推断为`0``1``2``3``4`,与类别文件夹`'class0'``'class1'`有关 ,`'class2'``'class3'``'class4'`
`flow_from_directory`函数的其他重要输入是`batch_size``target_size``class_mode``target_size`用于指定要馈送到神经网络的图像的尺寸,而`class_mode`用于指定问题的性质。 对于二进制分类,将`class_mode`设置为二进制,而对于多分类,将其设置为`categorical`
`flow_from_directory`函数的其他重要输入是`batch_size``target_size``class_mode``target_size`用于指定要馈送到神经网络的图像的大小,而`class_mode`用于指定问题的性质。 对于二进制分类,将`class_mode`设置为二进制,而对于多分类,将其设置为`categorical`
接下来,我们将通过创建动态批量来训练同一模型,而不是一次将所有数据加载到内存中。 我们只需要使用`flow_from_directory`选项创建一个生成器,然后将其绑定到数据扩充对象即可。 数据生成器对象可以如下生成:
......@@ -858,7 +858,7 @@ val_generator = val_datagen.flow_from_directory(val_dir,
在前面的代码中,我们将`ImageDataGenerator`传递给执行均值像素减法的附加任务,因为我们没有控制将图像数据加载到内存中并通过`pre_process`函数传递的任何控制权。 在`preprocessing_function`选项中,我们可以为任何特定的预处理任务传递任何所需的自定义函数。
通过`train_dir``val_dir`,我们将训练和验证目录传递给使用`flow_with_directory`选项创建的训练和验证生成器。 生成器通过查看传递的训练数据目录(此处为`train_dir`)中的班级文件夹数来识别班级数。 在基于`batch_size`的训练时间内,图像根据指定的`batch_size`读入内存
通过`train_dir``val_dir`,我们将训练和验证目录传递给使用`flow_with_directory`选项创建的训练和验证生成器。 生成器通过查看传递的训练数据目录(此处为`train_dir`)中的类别文件夹数来识别类别数。 在基于`batch_size`的训练时间内,图像根据指定的`batch_size`读入内存
`class_mode`帮助生成器识别其二进制分类还是多分类(`'categotical'`)。
......@@ -1072,7 +1072,7 @@ class DataGenerator(keras.utils.Sequence):
在前面的代码中,我们使用`keras.utils.Sequence`定义了`DataGenerator`类。
我们定义数据生成器以接受图像文件名,标签,批量大小,类数以及我们希望将图像调整大小的尺寸。 另外,我们指定是否希望将图像在一个时代中的处理顺序进行混排。
我们定义数据生成器以接受图像文件名,标签,批量大小,类数以及我们希望将图像调整大小的大小。 另外,我们指定是否希望将图像在一个时代中的处理顺序进行混排。
我们指定的函数是从`keras.utils.Sequence`继承的,因此,这些函数中每个函数的特定活动都无法在其他位置指定。`len`函数用于计算一个时期中的批量数。
......
......@@ -94,7 +94,7 @@
![](img/5b33f286-e730-48d1-83d1-f491731ad41f.png)
根据上述公式构建语言模型将需要我们估计几个订单的条件概率,这在实际中是不可能的。 为了使问题在计算上可行,一个简单的假设是仅根据前一个单词而不是之前的所有单词来对单词进行条件处理。 该假设也称为**马尔可夫假设**,该模型称为**二元模型**。 根据二元模型,单词的条件概率可以表示为:
根据上述公式构建语言模型将需要我们估计几个顺序的条件概率,这在实际中是不可能的。 为了使问题在计算上可行,一个简单的假设是仅根据前一个单词而不是之前的所有单词来对单词进行条件处理。 该假设也称为**马尔可夫假设**,该模型称为**二元模型**。 根据二元模型,单词的条件概率可以表示为:
![](img/fed81518-1cd1-4beb-a689-4f153de98fea.png)
......@@ -236,7 +236,7 @@ NMT 与其他传统方法相比的一些优点如下:
# 处理输入数据
文本数据不能直接输入任何神经网络,因为神经网络只能理解数字。 我们将每个单词视为一个单编码的矢量,其长度等于每个语料库中出现的单词的数量。 如果英语语料库包含 1,000 个单词,则一键编码的矢量`v[e]`的尺寸为 1,000,即`v[e] ∈ R^(1000 x 1)`
文本数据不能直接输入任何神经网络,因为神经网络只能理解数字。 我们将每个单词视为一个单编码的向量,其长度等于每个语料库中出现的单词的数量。 如果英语语料库包含 1,000 个单词,则一键编码的向量`v[e]`的大小为 1,000,即`v[e] ∈ R^(1000 x 1)`
我们将通读英语和法语语料库,并确定它们各自中唯一词的数量。 我们还将通过索引来表示单词,对于该单词的单编码向量,该单词对应的索引将设置为 1,而其余索引将设置为 0。 例如,假设在英语语料库中,我们有四个词:`Global warming is real`。 我们可以如下定义每个单词的索引:
......@@ -247,9 +247,9 @@ NMT 与其他传统方法相比的一些优点如下:
| `is` | 2 |
| `real` | 3 |
在这种情况下,我们可以将单词`global`的单热编码向量定义为`[1,0,0,0]^T`。 类似地,`real`的一键编码量可以表示为`[1,0,0,0]^T`
在这种情况下,我们可以将单词`global`的单热编码向量定义为`[1,0,0,0]^T`。 类似地,`real`的一键编码量可以表示为`[1,0,0,0]^T`
现在,转到每个句子或记录的源语言输入,我们将有一系列单词表示为一个单编码的量序列。 下一个明显的问题是如何管理序列长度,因为这可能会有所不同。 最普遍接受的方法是使固定序列长度等于语料库中句子的最大序列长度,或者达到预定的合理长度。 我们将使用目标语句两次:一次作为解码器的翻译输出序列,一次作为解码器的输入序列,唯一的区别是输出序列比输入序列提前一个时间步长。 因此,输入目标序列中的第一个单词将是伪单词`[START]`,而输出目标序列中的最后一个单词将是伪单词`[END]`,标记句子序列的结尾。
现在,转到每个句子或记录的源语言输入,我们将有一系列单词表示为一个单编码的量序列。 下一个明显的问题是如何管理序列长度,因为这可能会有所不同。 最普遍接受的方法是使固定序列长度等于语料库中句子的最大序列长度,或者达到预定的合理长度。 我们将使用目标语句两次:一次作为解码器的翻译输出序列,一次作为解码器的输入序列,唯一的区别是输出序列比输入序列提前一个时间步长。 因此,输入目标序列中的第一个单词将是伪单词`[START]`,而输出目标序列中的最后一个单词将是伪单词`[END]`,标记句子序列的结尾。
如果目标法语句子是`Je m'appelle Santanu`,则解码器中的输入目标和输出目标序列如下:
......@@ -414,7 +414,7 @@ NMT 与其他传统方法相比的一些优点如下:
(Shape of Target Output Tensor:',(40000, 16, 16297))
```
编码器数据的形状为`(40000, 7, 8658)`,其中第一维用于源语言语句的数量,第二维用于时间步长的数量,最终维是单次热编码量的大小, 是`8658`,与英语词汇中的`8658`源语言单词相对应。 类似地,对于目标输入和输出张量,我们看到一热编码向量的大小为`16297`,与法语词汇中的`16297`单词相对应。 法语句子的时间步长为`16`
编码器数据的形状为`(40000, 7, 8658)`,其中第一维用于源语言语句的数量,第二维用于时间步长的数量,最终维是单次热编码量的大小, 是`8658`,与英语词汇中的`8658`源语言单词相对应。 类似地,对于目标输入和输出张量,我们看到一热编码向量的大小为`16297`,与法语词汇中的`16297`单词相对应。 法语句子的时间步长为`16`
# 定义神经机器翻译的模型
......@@ -481,7 +481,7 @@ NMT 与其他传统方法相比的一些优点如下:
# 神经翻译机的损失函数
神经翻译机的损失函数是用于预测模型序列中每个目标单词的平均交叉熵损失。 实际目标词和预测目标词可以是我们所采用的法语语料库中的`16,297`个词中的任何一个。 在时间步`t`处的目标标签将是单热点编码的`y[t] ∈ {0,1}^16297`,法语词汇表中每个`16,297`个单词的预测输出将采用概率形式。 如果将预测的输出概率向量表示为`p[t] ∈ (0, 1)^16297`,则特定句子在每个时间步的平均分类损失由以下给出:
神经翻译机的损失函数是用于预测模型序列中每个目标单词的平均交叉熵损失。 实际目标词和预测目标词可以是我们所采用的法语语料库中的`16,297`个词中的任何一个。 在时间步`t`处的目标标签将是单热点编码的`y[t] ∈ {0,1}^16297`,法语词汇表中每个`16,297`个单词的预测输出将采用概率形式。 如果将预测的输出概率向量表示为`p[t] ∈ (0, 1)^16297`,则特定句子在每个时间步的平均分类损失由以下给出:
![](img/be4d5566-e340-4986-8364-96b61806475a.png)
......@@ -694,11 +694,11 @@ python MachineTranslation.py --path '/home/santanu/ML_DS_Catalog/Machine Transla
('Decoded sentence:', u' un ! \n')
```
总之,先前说明的神经机器翻译实现将相对较短的英语句子翻译为法语的工作相当不错。 我要强调的一件事是使用单热编码矢量来表示每种语言中的输入单词。 由于我们使用的是相对较小的 40,000 个单词的语料库,因此词汇量是合理的,因此,我们能够分别使用大小为 8,658 和 16,297 的英语和法语词汇量的一键编码矢量。 随着语料库的增加,单热点编码词向量的大小将进一步增加。 比较两个单词时,这种稀疏的高维向量没有任何相似性概念,因为即使两个单词的含义几乎相同,它们的余弦乘积也将是`0`。 在下一节中,我们将了解如何以较小的维数进行单词矢量嵌入来解决此问题。
总之,先前说明的神经机器翻译实现将相对较短的英语句子翻译为法语的工作相当不错。 我要强调的一件事是使用单热编码向量来表示每种语言中的输入单词。 由于我们使用的是相对较小的 40,000 个单词的语料库,因此词汇量是合理的,因此,我们能够分别使用大小为 8,658 和 16,297 的英语和法语词汇量的一键编码向量。 随着语料库的增加,单热点编码词向量的大小将进一步增加。 比较两个单词时,这种稀疏的高维向量没有任何相似性概念,因为即使两个单词的含义几乎相同,它们的余弦乘积也将是`0`。 在下一节中,我们将了解如何以较小的维数进行单词向量嵌入来解决此问题。
# 词向量嵌入
代替单热编码矢量,可以使用词矢量嵌入来表示维的密集空间中的单词,该空间比单热编码矢量低得多。 嵌入单词`w`的单词向量可以用`v[w] ∈ R^m`表示,其中`m`是词向量嵌入的维数。 如我们所见,虽然一个热编码矢量的每个分量只能占用{0,1}的二进制值,但词矢量嵌入的分量却可以占用任何实数,因此具有更密集的表示。 相似性和类比的概念也与词向量嵌入有关。
代替单热编码向量,可以使用词向量嵌入来表示维的密集空间中的单词,该空间比单热编码向量低得多。 嵌入单词`w`的单词向量可以用`v[w] ∈ R^m`表示,其中`m`是词向量嵌入的维数。 如我们所见,虽然一个热编码向量的每个分量只能占用{0,1}的二进制值,但词向量嵌入的分量却可以占用任何实数,因此具有更密集的表示。 相似性和类比的概念也与词向量嵌入有关。
通常通过诸如连续词袋法,skip-gram,GloVe 等技术来训练词向量嵌入。 我们将不对它们的实现进行过多的介绍,但中心思想是以这样的方式定义词向量嵌入:将类似的词紧密放置在`m`维欧几里得空间中:
......@@ -706,15 +706,15 @@ python MachineTranslation.py --path '/home/santanu/ML_DS_Catalog/Machine Transla
图 3.7:GloVe 嵌入的相似性和类比说明
在上一张图中,我们绘制了**男人****女人****国王****女王**的 GloVe 词向量嵌入的二维 TSNE 视图 。 我们可以看到,**男人****女人**具有内在的相似性,**国王****女王**的情况也是如此。 此外,我们看到**国王****男人**之间的向量差异与**女王****女人**的向量差异几乎相同,这可能代表王权的一些概念。 如我们所见,除了表达单词之间的相似性之外,还可以通过单词向量嵌入来表示类似*男人:国王:女人:女王*之类的东西。 在下一节中,我们将讨论使用 RNN 中的嵌入层将输入单词表示为单词矢量嵌入,而不是单编码的矢量。
在上一张图中,我们绘制了**男人****女人****国王****女王**的 GloVe 词向量嵌入的二维 TSNE 视图 。 我们可以看到,**男人****女人**具有内在的相似性,**国王****女王**的情况也是如此。 此外,我们看到**国王****男人**之间的向量差异与**女王****女人**的向量差异几乎相同,这可能代表王权的一些概念。 如我们所见,除了表达单词之间的相似性之外,还可以通过单词向量嵌入来表示类似*男人:国王:女人:女王*之类的东西。 在下一节中,我们将讨论使用 RNN 中的嵌入层将输入单词表示为单词向量嵌入,而不是单编码的向量。
# 嵌入层
嵌入层将输入单词的索引作为输入,并提供单词的单词向量嵌入作为输出。 嵌入层的尺寸为`R^(dxV)`,其中`d`是词向量嵌入的尺寸,`V`是词汇的尺寸。 嵌入层可以根据问题了解嵌入本身,也可以提供预训练的嵌入层。 在我们的案例中,我们将让神经机器翻译找出对于源语言和目标语言而言,嵌入向量应该是什么,以实现良好的翻译。 结果,我们定义的每个函数都应更改以适应嵌入层。
嵌入层将输入单词的索引作为输入,并提供单词的单词向量嵌入作为输出。 嵌入层的大小为`R^(dxV)`,其中`d`是词向量嵌入的大小,`V`是词汇的大小。 嵌入层可以根据问题了解嵌入本身,也可以提供预训练的嵌入层。 在我们的案例中,我们将让神经机器翻译找出对于源语言和目标语言而言,嵌入向量应该是什么,以实现良好的翻译。 结果,我们定义的每个函数都应更改以适应嵌入层。
# 实现基于嵌入的 NMT
我们将需要对现有函数进行一些更改,以适应嵌入层。 首先,`process_input`将处理输入以在不同的时间步长中具有单词索引,而不是单热编码量,如下所示:
我们将需要对现有函数进行一些更改,以适应嵌入层。 首先,`process_input`将处理输入以在不同的时间步长中具有单词索引,而不是单热编码量,如下所示:
```py
def process_input(self,input_texts,target_texts=None,verbose=True):
......@@ -777,7 +777,7 @@ np.array(target_texts)
```
与以前的`process_input`函数相比,唯一的变化是,我们不再用单热编码量表示单词,而是用单词的索引表示。 另外,您是否注意到我们为词汇表中不存在的单词添加了额外的单词索引? 理想情况下,这不是为了训练数据而发生的,但是在测试过程中,可能会出现一个不在词汇表中的全新单词。
与以前的`process_input`函数相比,唯一的变化是,我们不再用单热编码量表示单词,而是用单词的索引表示。 另外,您是否注意到我们为词汇表中不存在的单词添加了额外的单词索引? 理想情况下,这不是为了训练数据而发生的,但是在测试过程中,可能会出现一个不在词汇表中的全新单词。
以下是来自输入处理的统计信息:
......@@ -792,7 +792,7 @@ Max sequence length for outputs: 16
('Shape of Target Output Tensor:', (40000, 16, 1))
```
如我们所见,源和目标输入张量现在具有`7``16`时间步长,但是没有一键编码量的维数。 每个时间步长都包含单词的索引。
如我们所见,源和目标输入张量现在具有`7``16`时间步长,但是没有一键编码量的维数。 每个时间步长都包含单词的索引。
下一个变化是关于编码器和解码器网络,以在 LSTM 层之前容纳嵌入层:
......
......@@ -29,7 +29,7 @@
图 4.1:DiscoGAN 的架构图
`B`中生成的图像在样式和样式上都类似于域`A`中的图像。 无需在训练过程中显式配对来自两个域的图像就可以学习这种关系。 鉴于项目的配对是一项耗时的任务,因此这是一项非常强大的功能。 在较高的水平上,它尝试学习神经网络`G[AB]``G[BA]`形式的两个生成器函数。 图像`x[A]`,当通过发生器馈入时`G[AB]`,产生图像`x[AB]`,在域`B`中看起来很真实。此外,当此图像`x[AB]`通过其他生成器网络`G[BA]`馈送时,它应产生图像`x[ABA]`,理想情况下应与原始图像`x[A]`相同。 关于生成器函数,以下关系应成立:
`B`中生成的图像在样式和样式上都类似于域`A`中的图像。 无需在训练过程中显式配对来自两个域的图像就可以学习这种关系。 鉴于项目的配对是一项耗时的任务,因此这是一项非常强大的功能。 在较高的水平上,它尝试学习神经网络`G[AB]``G[BA]`形式的两个生成器函数。 图像`x[A]`,当通过生成器馈入时`G[AB]`,产生图像`x[AB]`,在域`B`中看起来很真实。此外,当此图像`x[AB]`通过其他生成器网络`G[BA]`馈送时,它应产生图像`x[ABA]`,理想情况下应与原始图像`x[A]`相同。 关于生成器函数,以下关系应成立:
![](img/b12bb426-7c2a-4116-be5b-98a133536497.png)
......@@ -47,7 +47,7 @@ L2 范数下的重建损失可以表示为:
由于我们正在处理图像,因此可以假设`x[A]`是所有像素的扁平向量,以符合 L2 规范术语。 如果我们假设`x[A]`是矩阵,则最好将`||·||_2^2`称为 **Frobenius 范数**。 但是,这些只是数学术语,实质上,我们只是将原始图像和重建图像之间的像素值差的平方和求和。
让我们考虑一下生成器在使变换后的图像`x[AB]`追求时要尽量降低成本的做法。 鉴别者将尝试将图像标记为伪图像,因此生成器`G[AB]`应当在这种情况下产生`x[AB]`使其成为假图片的对数丢失的方式尽可能小。 如果域`B`中的鉴别符`D[B]`将真实图像标记为`1`,将伪图像标记为`0`,则图像真实的概率由`D[B](.)`,则发生器应使`x[AB]`在判别器网络下极有可能出现,从而使`D[B](x[B]) = D[B](G[AB](x[A]))`接近`1`)。 就对数损失而言,生成器应使先前概率的负对数最小化,这基本上使我们得到`C[D(AB)]`,如下所示:
让我们考虑一下生成器在使变换后的图像`x[AB]`追求时要尽量降低成本的做法。 鉴别者将尝试将图像标记为伪图像,因此生成器`G[AB]`应当在这种情况下产生`x[AB]`使其成为假图片的对数丢失的方式尽可能小。 如果域`B`中的鉴别符`D[B]`将真实图像标记为`1`,将伪图像标记为`0`,则图像真实的概率由`D[B](.)`,则生成器应使`x[AB]`在判别器网络下极有可能出现,从而使`D[B](x[B]) = D[B](G[AB](x[A]))`接近`1`)。 就对数损失而言,生成器应使先前概率的负对数最小化,这基本上使我们得到`C[D(AB)]`,如下所示:
![](img/549bd16c-1bd7-4f76-b4c1-6179369f92c7.png)
......@@ -189,7 +189,7 @@ the number of input images processed : 30000
# DiscoGAN 的生成器
DiscoGAN 的生成器是前馈卷积神经网络,其中输入和输出是图像。 在网络的第一部分中,图像在空间维度上按比例缩小,而输出要素图的数量随层的进展而增加。 在网络的第二部分中,图像沿空间维度按比例放大,而输出特征映射的数量则逐层减少。 在最终输出层中,将生成具有与输入相同的空间尺寸的图像。 如果生成器将图像`x[A]`转换为`x[AB]`从域`A`到域`B`表示为`G[AB]`,则我们有`x[AB] = G[AB](x[A])`
DiscoGAN 的生成器是前馈卷积神经网络,其中输入和输出是图像。 在网络的第一部分中,图像在空间维度上按比例缩小,而输出要素图的数量随层的进展而增加。 在网络的第二部分中,图像沿空间维度按比例放大,而输出特征映射的数量则逐层减少。 在最终输出层中,将生成具有与输入相同的空间大小的图像。 如果生成器将图像`x[A]`转换为`x[AB]`从域`A`到域`B`表示为`G[AB]`,则我们有`x[AB] = G[AB](x[A])`
此处显示的是`build_generator`函数,我们可以使用它来构建 DiscoGAN 网络的生成器:
......@@ -282,7 +282,7 @@ def build_generator(self,image,reuse=False,name='generator'):
return out_img
```
在生成器函数中,我们定义了 LReLU 激活函数,并使用`0.2`的泄漏因子。 我们还定义了卷积层生成函数`common_conv2d`(用于对图像进行下采样)和`common_deconv2d`(用于将经降采样的图像上采样至其原始空间尺寸)。
在生成器函数中,我们定义了 LReLU 激活函数,并使用`0.2`的泄漏因子。 我们还定义了卷积层生成函数`common_conv2d`(用于对图像进行下采样)和`common_deconv2d`(用于将经降采样的图像上采样至其原始空间大小)。
我们通过使用`tf.get_variable_scope().reuse_variables()`使用`reuse`选项定义生成器函数。 当多次调用同一个生成器函数时,重用选项可确保我们重用特定生成器使用的相同变量。 当我们删除重用选项时,我们为生成器创建了一组新的变量。
......@@ -468,7 +468,7 @@ def build_network(self):
一旦定义了操作,我们就可以使用它们来计算损失函数,同时考虑图像的重建损失和归因于判别器的损失。 请注意,我们使用了相同的生成器函数来定义域`A``B`的生成器,也定义了从`B``A`的生成器。唯一不同的是为这两个网络提供了不同的名称:`generator_AB``generator_BA`。 由于变量作用域定义为`name`,所以这两个生成器都将具有不同的权重集,并以提供的名称为前缀。
下表显示了我们需要跟踪的不同损耗变量。 就发生器或判别器的参数而言,所有这些损失都需要最小化:
下表显示了我们需要跟踪的不同损耗变量。 就生成器或判别器的参数而言,所有这些损失都需要最小化:
| **不同损失的变量** | **说明** |
| --- | --- |
......
......@@ -95,7 +95,7 @@ o1, o2, . . . . . ot . . . oN = { "A ","man" "in" "a" "yellow" "helmet" "is" "wo
在通过`VGG16`处理视频中的图像之前,需要从视频中对其进行采样。 我们从视频中采样图像,使每个视频具有`80`帧。 处理来自`VGG16``80`图像帧后,每个视频将具有`80`特征向量`f[1], f[2], ..., f[80]`。 这些特征将被馈送到 LSTM 以生成文本序列。 我们在 Keras 中使用了预训练的`VGG16`模型。 我们创建一个`VideoCaptioningPreProcessing`类,该类首先通过函数`video_to_frames`从每个视频中提取`80`视频帧作为图像,然后通过函数`extract_feats_pretrained_cnn`中的预训练`VGG16`卷积神经网络处理这些视频帧。 。
`extract_feats_pretrained_cnn`的输出是每个视频帧尺寸`4096`的 CNN 特征。 由于我们正在处理每个视频的`80`帧,因此每个视频将具有`80`这样的`4096`维向量。
`extract_feats_pretrained_cnn`的输出是每个视频帧大小`4096`的 CNN 特征。 由于我们正在处理每个视频的`80`帧,因此每个视频将具有`80`这样的`4096`维向量。
`video_to_frames`函数可以编码如下:
......@@ -116,7 +116,7 @@ o1, o2, . . . . . ot . . . oN = { "A ","man" "in" "a" "yellow" "helmet" "is" "wo
```
从前面的代码中,我们可以看到在`video_to_frames`函数中,`ffmpeg`工具用于将 JPEG 格式的视频图像帧转换。 为图像帧指定为`ffmpeg`尺寸`300 x 400`。 有关`ffmpeg`工具的更多信息,[请参考以下链接](https://www.ffmpeg.org/)
从前面的代码中,我们可以看到在`video_to_frames`函数中,`ffmpeg`工具用于将 JPEG 格式的视频图像帧转换。 为图像帧指定为`ffmpeg`大小`300 x 400`。 有关`ffmpeg`工具的更多信息,[请参考以下链接](https://www.ffmpeg.org/)
`extract_feats_pretrained_cnnfunction`中已建立了从最后一个全连接层中提取特征的预训练 CNN 模型。 该函数的代码如下:
......@@ -161,7 +161,7 @@ o1, o2, . . . . . ot . . . oN = { "A ","man" "in" "a" "yellow" "helmet" "is" "wo
shutil.rmtree(self.temp_dest)
```
我们首先使用`model_cnn_load`函数加载经过预训练的 CNN 模型,然后针对每个视频,根据`ffmpeg.`指定的采样频率,使用`video_to_frames`函数将多个视频帧提取为图像。 图像通过`ffmpeg`创建的视频中的图像帧,但是我们使用`np.linspace`函数拍摄了`80`等距图像帧。 使用`load_image`函数将`ffmpeg`生成的图像调整为`224 x 224`的空间尺寸。 最后,将这些调整大小后的图像通过预训练的 VGG16 卷积神经网络(CNN),并提取输出层之前的最后一个全连接层的输出作为特征。 这些提取的特征向量存储在`numpy`数组中,并在下一阶段由 LSTM 网络进行处理以产生视频字幕。 本节中定义的函数`model_cnn_load`函数定义如下:
我们首先使用`model_cnn_load`函数加载经过预训练的 CNN 模型,然后针对每个视频,根据`ffmpeg.`指定的采样频率,使用`video_to_frames`函数将多个视频帧提取为图像。 图像通过`ffmpeg`创建的视频中的图像帧,但是我们使用`np.linspace`函数拍摄了`80`等距图像帧。 使用`load_image`函数将`ffmpeg`生成的图像调整为`224 x 224`的空间大小。 最后,将这些调整大小后的图像通过预训练的 VGG16 卷积神经网络(CNN),并提取输出层之前的最后一个全连接层的输出作为特征。 这些提取的特征向量存储在`numpy`数组中,并在下一阶段由 LSTM 网络进行处理以产生视频字幕。 本节中定义的函数`model_cnn_load`函数定义如下:
```py
def model_cnn_load(self):
......@@ -263,9 +263,9 @@ def get_clean_caption_data(self,text_path,feat_path):
# 建立模型
在本节中,说明了核心模型构建练习。 我们首先为文本标题的词汇表中的单词定义一个嵌入层,然后是两个 LSTM。 权重`self.encode_W``self.encode_b`用于减少卷积神经网络中特征`f[t]`尺寸。 对于第二个 LSTM(LSTM 2),在任何时间步长`t > N`处的其他输入之一是前一个单词`w[t-1]`,以及来自第一个 LSTM(LSTM 1)的输出`h[t]`。 将`w[t-1]`的词嵌入送入 LSTM 2,而不是原始的单热编码矢量。 对于前`N``(self.video_lstm_step)`,LSTM 1 处理来自 CNN 的输入特征`f[t]`,并且输出的隐藏状态`h[t]`(输出 1)被馈送到 LSTM2。在此编码阶段,LSTM 2 不会接收任何单词`w[t-1]`作为输入。
在本节中,说明了核心模型构建练习。 我们首先为文本标题的词汇表中的单词定义一个嵌入层,然后是两个 LSTM。 权重`self.encode_W``self.encode_b`用于减少卷积神经网络中特征`f[t]`大小。 对于第二个 LSTM(LSTM 2),在任何时间步长`t > N`处的其他输入之一是前一个单词`w[t-1]`,以及来自第一个 LSTM(LSTM 1)的输出`h[t]`。 将`w[t-1]`的词嵌入送入 LSTM 2,而不是原始的单热编码向量。 对于前`N``(self.video_lstm_step)`,LSTM 1 处理来自 CNN 的输入特征`f[t]`,并且输出的隐藏状态`h[t]`(输出 1)被馈送到 LSTM2。在此编码阶段,LSTM 2 不会接收任何单词`w[t-1]`作为输入。
`N + 1`时间步长,我们进入解码阶段,在此阶段,连同来自 LSTM 1 的`h[t]`(输出 1),先前的时间步的词嵌入`w[t-1]`被馈送到 LSTM2。在这一阶段,没有到 LSTM 1 的输入,因为所有特征`f[t]`在时间步`N`耗尽。 解码阶段的时间步长由`self.caption_lstm_step`确定。
`N + 1`时间步长,我们进入解码阶段,在此阶段,连同来自 LSTM 1 的`h[t]`(输出 1),先前的时间步的词嵌入`w[t-1]`被馈送到 LSTM2。在这一阶段,没有到 LSTM 1 的输入,因为所有特征`f[t]`在时间步`N`耗尽。 解码阶段的时间步长由`self.caption_lstm_step`确定。
现在,如果我们用函数`f[2]`表示 LSTM 2 的活动,则`f[2](h[t], w[t-1]) = h[2t]`,其中`h[2t]`是 LSTM 2 在时间步`t`的隐藏状态。 该隐藏状态`h[2t]`在时间`t`时,通过 *softmax* 函数转换为输出单词的概率分布, 选择最高概率的单词作为下一个单词`o_hat[t]`
......@@ -478,7 +478,7 @@ unk => A substitute for a word that is not included in the vocabulary
![](img/21a19e2b-fef3-4156-b1b2-8812e5a6b329.png)
此处,`y^(t) = [y1^(t), y2^(t), ..., y[V]^(t)]`是时间步长`t`时实际目标单词的一个热编码矢量,而`p^(t) = [p1^(t), p2^(t), ..., p[V]^(t)]`是模型预测的概率矢量。
此处,`y^(t) = [y1^(t), y2^(t), ..., y[V]^(t)]`是时间步长`t`时实际目标单词的一个热编码向量,而`p^(t) = [p1^(t), p2^(t), ..., p[V]^(t)]`是模型预测的概率向量。
在训练期间的每个时期都会记录损失,以了解损失减少的性质。 这里要注意的另一件事是,我们正在使用 TensorFlow 的`tf.train.saver`函数保存经过训练的模型,以便我们可以恢复模型以进行推理。
......
......@@ -40,7 +40,7 @@
# 基于潜在分解的推荐系统
基于潜在因子分解的过滤器推荐方法尝试通过分解评分来发现潜在特征,以表示用户和项目资料。 与基于内容的过滤特征不同,这些潜在特征不可解释,可以表示复杂的特征。 例如,在电影推荐系统中,潜在特征之一可能以特定比例表示幽默,悬念和浪漫的线性组合。 通常,对于已经评分的商品,用户`i`对商品`j`的评分`r[ij]`可以表示为`r[ij] = u[i]^T v[j]`。 其中`u[i]`是基于潜在因子的用户配置文件矢量,而`v[i]`是基于相同潜在因子的项目矢量 :
基于潜在因子分解的过滤器推荐方法尝试通过分解评分来发现潜在特征,以表示用户和项目资料。 与基于内容的过滤特征不同,这些潜在特征不可解释,可以表示复杂的特征。 例如,在电影推荐系统中,潜在特征之一可能以特定比例表示幽默,悬念和浪漫的线性组合。 通常,对于已经评分的商品,用户`i`对商品`j`的评分`r[ij]`可以表示为`r[ij] = u[i]^T v[j]`。 其中`u[i]`是基于潜在因子的用户配置文件向量,而`v[i]`是基于相同潜在因子的项目向量 :
![](img/719736b5-d23e-49ca-b6b2-bfcda9d9657a.png)
......@@ -56,13 +56,13 @@
# 用于潜在因子协同过滤的深度学习
除了使用 SVD,您还可以利用深度学习方法来导出给定尺寸的用户和商品资料向量。
除了使用 SVD,您还可以利用深度学习方法来导出给定大小的用户和商品资料向量。
对于每个用户`i`,您可以通过嵌入层定义用户`u[i] ∈ R^k`。 同样,对于每个项目`j`,您可以通过另一个嵌入层定义项目向量`v[j] ∈ R^k`。 然后,用户`i`对项目`j`的评分`r[ij]`可以表示为`u[i], v[j]`的点积,如下所示:
对于每个用户`i`,您可以通过嵌入层定义用户`u[i] ∈ R^k`。 同样,对于每个项目`j`,您可以通过另一个嵌入层定义项目向量`v[j] ∈ R^k`。 然后,用户`i`对项目`j`的评分`r[ij]`可以表示为`u[i], v[j]`的点积,如下所示:
![](img/1c084aa4-07bd-45cb-bdc1-cbd02d52565c.png)
您可以修改神经网络以为用户和项目添加偏见。 假设我们想要`k`潜在分量,则`m`用户的嵌入矩阵`U`尺寸将是`mxk`。 类似地,`n`项的嵌入矩阵`V`的尺寸将为`nxk`
您可以修改神经网络以为用户和项目添加偏见。 假设我们想要`k`潜在分量,则`m`用户的嵌入矩阵`U`大小将是`mxk`。 类似地,`n`项的嵌入矩阵`V`的大小将为`nxk`
在“基于深度学习的潜在因子模型”部分中,我们将使用这种嵌入方法基于`100K Movie Lens`数据集创建推荐系统。 数据集可以从`https://grouplens.org/datasets/movielens/`下载。
......@@ -76,7 +76,7 @@
图 6.4:电影镜头 100 K 数据集上基于深度学习的潜在因子模型
`user_ID``movie_ID`从其相应的嵌入矩阵中提取用户和电影嵌入向量。 在该图中,`embedding_1`代表用户 ID 的嵌入层,而`embedding_2`代表电影 ID 的嵌入层。 在`dot_1`层中执行用户嵌入矢量和电影嵌入矢量的点积,以输出评分(一到五个)。 定义模型的代码如下所示:
`user_ID``movie_ID`从其相应的嵌入矩阵中提取用户和电影嵌入向量。 在该图中,`embedding_1`代表用户 ID 的嵌入层,而`embedding_2`代表电影 ID 的嵌入层。 在`dot_1`层中执行用户嵌入向量和电影嵌入向量的点积,以输出评分(一到五个)。 定义模型的代码如下所示:
```py
def model(max_users,max_movies,latent_factors):
......@@ -234,17 +234,17 @@ test_ratings_df[test_ratings_df['userID'] == 1].sort_values(['rating','predictio
这里,`λ[1]``λ[2]`是正则化常数。 通常,一种流行的梯度下降技术称为**交替最小二乘****ALS**)用于优化,该技术通过保持项目参数固定来交替更新用户配置文件参数,反之亦然。
`surprise`软件包具有 SVD++ 的良好实现。 在下一部分中,我们将在`100K movie lens`数据集上使用 SVD++ 训练模型,并查看性能指标。
`surprise`包具有 SVD++ 的良好实现。 在下一部分中,我们将在`100K movie lens`数据集上使用 SVD++ 训练模型,并查看性能指标。
# MovieLens 100k 数据集上的 SVD++ 训练模型
可以使用以下命令通过`conda`下载`surprise`软件包:
可以使用以下命令通过`conda`下载`surprise`包:
```py
conda install -c conda-forge scikit-surprise
```
对应于 SVD++ 的算法在`surprise`中被命名为`SVDpp`。 我们可以按以下方式加载所有必需的软件包:
对应于 SVD++ 的算法在`surprise`中被命名为`SVDpp`。 我们可以按以下方式加载所有必需的包:
```py
import numpy as np
......@@ -463,7 +463,7 @@ if __name__ == '__main__':
```
训练文件是尺寸`mxnxk``numpy`数组对象,其中`m`是用户总数,`n`是电影总数,并且`k`是离散额定值的数量(一到五个)。 要构建测试集,我们从训练数据集中随机选择 20% 的`m x n`评分条目。 因此,测试集评级样本的所有`k`评级值在训练数据集中均标记为零。 在测试集中,我们不会将数据扩展为三维 numpy 数组格式,因此可以将其用于训练。 相反,我们只将`userid``movieid`和分配的评分保存在三列中。 请注意,存储在火车中的`userid``movieid`和测试文件不是原始评级数据文件`u.data`中的实际 ID。 它们被`1`偏移以适应从`0`而非`1`开始的 Python 和`numpy`索引
训练文件是大小`mxnxk``numpy`数组对象,其中`m`是用户总数,`n`是电影总数,并且`k`是离散额定值的数量(一到五个)。 要构建测试集,我们从训练数据集中随机选择 20% 的`m x n`评分条目。 因此,测试集评级样本的所有`k`评级值在训练数据集中均标记为零。 在测试集中,我们不会将数据扩展为三维 numpy 数组格式,因此可以将其用于训练。 相反,我们只将`userid``movieid`和分配的评分保存在三列中。 请注意,存储在火车中的`userid``movieid`和测试文件不是原始评级数据文件`u.data`中的实际 ID。 它们被`1`偏移以适应从`0`而非`1`开始的 Python 和`numpy`索引
以下命令可用于调用数据预处理脚本:
......
# 电影评论情感分析移动应用
在这个现代时代,将数据发送到云中基于 AI 的应用进行推理是司空见惯的。 例如,用户可以将手机拍摄的图像发送到 Amazon Rekognition API,该服务可以标记图像中存在的各种对象,人物,文本,场景等。 利用托管在云中的基于 AI 的应用的服务的优势在于其易用性。 移动应用只需要向基于 AI 的服务以及图像发出 HTTPS 请求,然后在几秒钟内,该服务将提供推理结果。 这些**机器学习即服务**提供程序中的一些如下:
在这个现代时代,将数据发送到云中基于 AI 的应用进行推理是司空见惯的。 例如,用户可以将手机拍摄的图像发送到 Amazon Rekognition API,该服务可以标记图像中存在的各种对象,人物,文本,场景等。 利用托管在云中的基于 AI 的应用的服务的优势在于其易用性。 移动应用只需要向基于 AI 的服务以及图像发出 HTTPS 请求,然后在几秒钟内,该服务将提供推理结果。 这些**机器学习即服务**供应商中的一些如下:
* 亚马逊 Rekognition
* 亚马逊 Polly
......@@ -207,7 +207,7 @@ records_processed 50000
# 建立模型
我们将构建一个简单的 LSTM 版本的循环神经网络,在输入层之后有一个嵌入层。 使用预训练的尺寸为 100 的 Glove 向量初始化嵌入层字向量,并将该层定义为`trainable`,以便字向量嵌入可以根据训练数据进行更新。 隐藏状态和单元状态的维数也保持为`100`。 使用二进制交叉熵损失训练模型。 为避免过拟合,将脊正则化添加到损失函数中。 **Adam 优化器**用于训练模型。
我们将构建一个简单的 LSTM 版本的循环神经网络,在输入层之后有一个嵌入层。 使用预训练的大小为 100 的 Glove 向量初始化嵌入层字向量,并将该层定义为`trainable`,以便字向量嵌入可以根据训练数据进行更新。 隐藏状态和单元状态的维数也保持为`100`。 使用二进制交叉熵损失训练模型。 为避免过拟合,将脊正则化添加到损失函数中。 **Adam 优化器**用于训练模型。
以下代码段显示了用于在 TensorFlow 中构建模型的函数:
......@@ -580,7 +580,7 @@ Android 应用的核心逻辑是处理用户请求以及传递的数据,然后
1. 将索引字典中的单词加载到`WordToInd` `HashMap`中。 词间索引字典是在训练模型之前,在文本的预处理过程中从分词器派生的。
2. 使用`OnClickListener`方法监视用户是否已提交电影评论以进行推断。
3. 如果已提交电影评论,则将从与 XML 关联的`Review`变量中读取评论。 该评论会通过删除标点符号等内容进行清理,然后拆分为单词。 使用`HashMap`函数`WordToInd`将这些单词中的每个单词转换为相应的索引。 这些索引构成我们 TensorFlow 模型的`InputVec`输入,以进行推断。 输入向量长度为​​`1000`; 因此,如果评论的字数少于`1000`,则量的开头将填充零。
3. 如果已提交电影评论,则将从与 XML 关联的`Review`变量中读取评论。 该评论会通过删除标点符号等内容进行清理,然后拆分为单词。 使用`HashMap`函数`WordToInd`将这些单词中的每个单词转换为相应的索引。 这些索引构成我们 TensorFlow 模型的`InputVec`输入,以进行推断。 输入向量长度为​​`1000`; 因此,如果评论的字数少于`1000`,则量的开头将填充零。
4. 下一步,使用`TensorFlowInferenceInterface`函数创建`mInferenceInterface`对象,将优化的 protobuf 模型(扩展名为`.pb`)从`assets`文件夹加载到内存中。 与原始模型一样,需要定义要参考的 TensorFlow 模型的输入节点和输出节点。 对于我们的模型,它们定义为`INPUT_NODE``OUTPUT_NODE`,它们分别包含 TensorFlow 输入占位符的名称和输出情感概率的操作。 `mInferenceInterface` 对象的`feed`方法用于将`InputVec`值分配给的`INPUT_NODE` 模型,而`mInferenceInterface``run`方法执行`OUTPUT_NODE`。 最后,使用`mInferenceInterface``fetch`方法来填充对浮点变量`value_`的推断结果。
5. 情感分数(情感为正的概率)乘以五将转换为等级。 然后通过`ratingBar` 变量将其馈送到 Android 应用用户界面。
......
......@@ -255,7 +255,7 @@ Keras 中的`TimeDistributed`函数允许在解码器 LSTM 的每个时间步长
![](img/81b811e5-db95-4cf3-9d09-b9a0c7bff88e.png)
标签`[y[i]], i = 1 -> N`代表目标单词的一个热编码版本。 仅对应于实际单词的标签为`1`; 其余为`0`。 术语`Pi`表示实际目标单词是由`i`索引的单词的概率。 为了获得每个输入/输出推特对的总损耗`C`,我们需要对解码器 LSTM 的所有时间步长上的损耗求和。 由于词汇量可能会变得很大,因此在每个时间步骤中为目标标签创建一个热编码矢量`y[t] = [y[i]], i = 1 -> n`会很昂贵。 `sparse_categorical_crossentropy`损失在这里变得非常有益,因为我们不需要将目标单词转换为一个热编码矢量,而只需输入目标单词的索引作为目标标签即可。
标签`[y[i]], i = 1 -> N`代表目标单词的一个热编码版本。 仅对应于实际单词的标签为`1`; 其余为`0`。 术语`Pi`表示实际目标单词是由`i`索引的单词的概率。 为了获得每个输入/输出推特对的总损耗`C`,我们需要对解码器 LSTM 的所有时间步长上的损耗求和。 由于词汇量可能会变得很大,因此在每个时间步骤中为目标标签创建一个热编码向量`y[t] = [y[i]], i = 1 -> n`会很昂贵。 `sparse_categorical_crossentropy`损失在这里变得非常有益,因为我们不需要将目标单词转换为一个热编码向量,而只需输入目标单词的索引作为目标标签即可。
# 训练模型
......@@ -383,7 +383,7 @@ python chatbot.py --max_vocab_size 50000 --max_seq_len 30 --embedding_dim 100 --
| --- | --- | --- |
| `max_vocab_size` | 词汇中的单词数 | `50,000` |
| `max_seq_len` | 应被限制到 LSTM 的推文的最大长度 | `30` |
| `hidden_state_dim` | LSTM 的隐藏状态`h`尺寸 | `100` |
| `hidden_state_dim` | LSTM 的隐藏状态`h`大小 | `100` |
| `embedding_dim` | 词嵌入的维度 | `100` |
| `learning rate` | 用于优化程序的起始学习率 | `0.0001` |
| `dropout` | 用于正则化目的的丢弃 | `0.3` |
......
......@@ -134,7 +134,7 @@ Q 值表也通过迭代`t`进行索引,因为智能体只能查看到目前为
# 实现自动驾驶汽车
现在,我们将研究实现一种自动驾驶的无人驾驶赛车,该赛车使用深度 Q 网络学习如何在赛道上自行驾驶。 驾驶员和汽车将充当智能体,赛车场及其周围环境将充当环境。 我们将使用 OpenAI Gym `CarRacing-v0`框架作为环境。 状态和奖励将由环境呈现给智能体,而智能体将通过采取适当的行动对智能体采取行动。 这些状态采用从汽车前面的摄像头拍摄的图像的形式。 环境接受的动作为三维`a ∈ R^3`的形式,其中第一个分量用于左移,第二个分量用于前移,第三部分用于右移。 该智能体将与环境交互并将交互转换为`(s, a, r, s'), i = 1 -> m`形式的元组。 这些交互元组将用作我们的训练数据。
现在,我们将研究实现一种自动驾驶的无人驾驶赛车,该赛车使用深度 Q 网络学习如何在赛道上自行驾驶。 驾驶员和汽车将充当智能体,赛车场及其周围环境将充当环境。 我们将使用 OpenAI Gym `CarRacing-v0`框架作为环境。 状态和奖励将由环境呈现给智能体,而智能体将通过采取适当的行动对智能体采取行动。 这些状态采用从汽车前面的摄像头拍摄的图像的形式。 环境接受的动作为三维`a ∈ R^3`的形式,其中第一个分量用于左移,第二个分量用于前移,第三部分用于右移。 该智能体将与环境交互并将交互转换为`(s, a, r, s'), i = 1 -> m`形式的元组。 这些交互元组将用作我们的训练数据。
该架构将类似于我们在图右侧所示的架构(“图 9.4A”和“图 9.4B”)。
......
......@@ -388,17 +388,17 @@ Evaluation file written at: /home/santanu/ML_DS_Catalog-/captcha/evaluation.csv
SVHN 是一个现实世界的数据集,由于它在对象识别算法中的使用而在机器学习和深度学习领域中非常受欢迎。 顾名思义,该数据集包含从 Google Street View Images 获得的门牌号码的真实图像。 [可以从以下链接下载数据集](http://ufldl.stanford.edu/housenumbers/)
我们将使用调整后的门牌号数据集,其中图像已调整为尺寸`(32,32)`。 我们感兴趣的数据集是`train_32x32.mat`
我们将使用调整后的门牌号数据集,其中图像已调整为大小`(32,32)`。 我们感兴趣的数据集是`train_32x32.mat`
通过这个**生成对抗网络****GAN**),我们将根据随机噪声生成房屋编号图像,并且生成的图像将与 SVHN 数据集中的图像非常相似。
回顾一下,在 GAN 中,我们有一个生成器(`G`)和一个判别器(`D`),它们针对损失函数彼此玩零和极小极大游戏。 随着时间的流逝,生成器和判别器的工作都会越来越好,直到我们到达一个固定点为止,两者都无法进一步改善。 该固定点是相对于损失函数的鞍点。 对于我们的应用,发生`G`会将给定分布`P(z)`的噪声`z`转换​​为门牌号图像`x`,以使`x = G(z)`
回顾一下,在 GAN 中,我们有一个生成器(`G`)和一个判别器(`D`),它们针对损失函数彼此玩零和极小极大游戏。 随着时间的流逝,生成器和判别器的工作都会越来越好,直到我们到达一个固定点为止,两者都无法进一步改善。 该固定点是相对于损失函数的鞍点。 对于我们的应用,生成`G`会将给定分布`P(z)`的噪声`z`转换​​为门牌号图像`x`,以使`x = G(z)`
生成的图像通过判别器`D`传递,判别器`D`尝试检测此生成的图像`x`为伪造,并从 SVHN 数据集中检测真实的门牌号码图像为真实。 同时,生成器将尝试创建图像`x = G(z)`,以使判别器发现图像是真实的。 如果我们将真实图像标记为`1`,而将生成器生成的伪图像标记为`0`,则判别器将尝试在给定两个类别的分类器网络中最小化二进制交叉熵损失。 鉴别符`D`所导致的损耗可以写成如下:
![](img/ae36b54b-0a7c-4c94-8c4b-4e5209859d44.png)
在前面的表达式中`D(.)`是鉴别函数,其输出表示将图像标记为实数的可能性。`P[z](z)`表示随机变量噪声`z`的分布,而`P[X](x)`表示真实门牌号图像的分布。`G(.)``D(.)`分别表示生成器网络函数和判别器网络函数。 这些参数可以通过网络的权重进行参数化,而网络的权重是我们为表示法的混乱而方便地跳过的。 如果我们用`θ`表示发生器网络权重的参数,用`φ`表示判别器网络的权重,则判别器将学会使`(1)`相对于`φ`的损失最小化,而生成器将旨在使`(1)``θ`的损失相同。 我们可以将`(1)`中优化的损耗称为效用函数,发生器和判别器都在参数方面进行了优化。 实用函数`U`可以根据生成器和判别器的参数来编写,如下所示:
在前面的表达式中`D(.)`是鉴别函数,其输出表示将图像标记为实数的可能性。`P[z](z)`表示随机变量噪声`z`的分布,而`P[X](x)`表示真实门牌号图像的分布。`G(.)``D(.)`分别表示生成器网络函数和判别器网络函数。 这些参数可以通过网络的权重进行参数化,而网络的权重是我们为表示法的混乱而方便地跳过的。 如果我们用`θ`表示生成器网络权重的参数,用`φ`表示判别器网络的权重,则判别器将学会使`(1)`相对于`φ`的损失最小化,而生成器将旨在使`(1)``θ`的损失相同。 我们可以将`(1)`中优化的损耗称为效用函数,生成器和判别器都在参数方面进行了优化。 实用函数`U`可以根据生成器和判别器的参数来编写,如下所示:
![](img/e18dcc4f-da73-459c-ae45-a767f0e05be9.png)
......@@ -436,7 +436,7 @@ SVHN 是一个现实世界的数据集,由于它在对象识别算法中的使
生成器网络将吸收随机噪声,并尝试输出类似于 SVHN 图像的图像作为输出。 随机噪声是`100`维输入向量。 每个维度都是遵循标准正态分布的随机变量,平均值为`0`,标准偏差为`1`
最初的致密层具有`8192`单元,将其重塑为形状为`4 x 4 x 512`的三维张量。 使用`512`滤镜可以将张量视为`4 x 4`图像。 为了增加张量的空间尺寸,我们进行了一系列转置 2D 卷积,步幅为`2`,内核滤波器尺寸为`5 x5`。步幅大小决定了转置卷积的缩放比例。 例如,跨度为 2 的跨度将输入图像的每个空间尺寸加倍,然后进行转置卷积,通常会进行批归一化,以实现更好的收敛性。 除了激活层,网络使用`LeakyReLU`作为激活函数。 网络的最终输出是尺寸`32 x 32 x 3`的图像。
最初的致密层具有`8192`单元,将其重塑为形状为`4 x 4 x 512`的三维张量。 使用`512`滤镜可以将张量视为`4 x 4`图像。 为了增加张量的空间大小,我们进行了一系列转置 2D 卷积,步幅为`2`,内核滤波器大小为`5 x5`。步幅大小决定了转置卷积的缩放比例。 例如,跨度为 2 的跨度将输入图像的每个空间大小加倍,然后进行转置卷积,通常会进行批归一化,以实现更好的收敛性。 除了激活层,网络使用`LeakyReLU`作为激活函数。 网络的最终输出是大小`32 x 32 x 3`的图像。
在最后一层中使用`tanh`激活,以便对`[-1,1]`范围内的图像像素值进行标准化。
......@@ -517,7 +517,7 @@ def discriminator(img_dim,alpha=0.2):
生成器`g`创建`d`判别器将评估的伪造图像,并尝试将其标记为伪造。
`g_d`网络中,`g`生成器创建伪造的图像,然后尝试欺骗`d`判别器,使其相信它们是真实的。 判别器网络使用二进制交叉熵损失进行编译,并且针对判别器参数`φ`优化了损失,而`g_d`网络则针对`g`发生器的参数`θ`进行了编译,以便欺骗判别器。 因此,`g_d`网络损失是与判别器将所有伪造图像标记为真实图像有关的二进制交叉熵损失。 在每个小型批量中,基于与`g_d``d`网络相关的损耗的优化来更新生成器和判别器权重:
`g_d`网络中,`g`生成器创建伪造的图像,然后尝试欺骗`d`判别器,使其相信它们是真实的。 判别器网络使用二进制交叉熵损失进行编译,并且针对判别器参数`φ`优化了损失,而`g_d`网络则针对`g`生成器的参数`θ`进行了编译,以便欺骗判别器。 因此,`g_d`网络损失是与判别器将所有伪造图像标记为真实图像有关的二进制交叉熵损失。 在每个小型批量中,基于与`g_d``d`网络相关的损耗的优化来更新生成器和判别器权重:
```py
def train(dest_train,outdir,
......@@ -580,7 +580,7 @@ def train(dest_train,outdir,
d.save_weights('discriminator', True)
```
`Adam`优化器用于两个网络的优化。 要注意的一件事是,仅需要对网络`g_d`进行编译,以仅针对发生`G`的参数来优化损耗。 因此,我们需要禁用网络`g_d`中判别器`D`的参数训练。
`Adam`优化器用于两个网络的优化。 要注意的一件事是,仅需要对网络`g_d`进行编译,以仅针对生成`G`的参数来优化损耗。 因此,我们需要禁用网络`g_d`中判别器`D`的参数训练。
我们可以使用以下函数来禁用或启用对网络参数的学习:
......@@ -594,11 +594,11 @@ def make_trainable(model, trainable):
# 噪音分布
输入到 GAN 的噪声需要遵循特定的概率分布。 通常使用均匀分布`U[-1,1]`或标准正态分布,即均值`0`和标准偏差`1`的正态分布对噪声量的每个维度进行采样。 从经验上可以看出,从标准正态分布中采样噪声似乎比从均匀分布中采样噪声更好。 在此实现中,我们将使用标准正态分布来采样随机噪声。
输入到 GAN 的噪声需要遵循特定的概率分布。 通常使用均匀分布`U[-1,1]`或标准正态分布,即均值`0`和标准偏差`1`的正态分布对噪声量的每个维度进行采样。 从经验上可以看出,从标准正态分布中采样噪声似乎比从均匀分布中采样噪声更好。 在此实现中,我们将使用标准正态分布来采样随机噪声。
# 数据预处理
如前所述,我们将使用尺寸`32 x 32 x 3`的 SVHN 数据集图像。
如前所述,我们将使用大小`32 x 32 x 3`的 SVHN 数据集图像。
数据集图像易于以矩阵数据形式获得。 图像的原始像素在`[-1,1]`范围内进行归一化,以实现更快,更稳定的收敛。 由于这种转换,生成器的最终激活保持在`tanh`,以确保生成的图像的像素值在`[-1,1]`之内。
......@@ -650,7 +650,7 @@ python captcha_gan.py train --dest_train '/home/santanu/Downloads/train_32x32.ma
| **参数** | **值** | **注释** |
| --- | --- | --- |
| `batch_size` | `100` | 小型批量随机梯度下降的批量大小。 |
| `gen_input_dim` | `100` | 输入随机噪声量维。 |
| `gen_input_dim` | `100` | 输入随机噪声量维。 |
| `gen_lr` | `0.0001` | 生成器学习率。 |
| `gen_beta1` | `0.5` | `beta_1`是生成器的 Adam 优化器的参数。 |
| `dis_input_dim` | `(32,32,3)` | 辨别真假房屋号码图像的形状。 |
......
......@@ -157,7 +157,7 @@ RFE 是我们将使用`RandomForestClassifier`模型的第三种技术,请记
在本章前面看到的特征选择可以认为是降维的一种形式。 当您具有一组紧密相关甚至冗余的特征时,PCA 将是使用较少特征对相同信息进行编码的首选技术。 那么,什么是 PCA? 这是一种统计过程,将一组可能相关的变量的观测值转换为一组线性无关的变量,称为**主成分**。 我们不要讨论有关 PCA 发生了什么的数学细节。
假设我们有一个二维数据集。 PCA 确定数据集变化最大的方向,并将关于这两个要素的最大信息量编码为一个要素,以将维数从二维减少为一个。 此方法将每个点投影到这些轴或新尺寸上。
假设我们有一个二维数据集。 PCA 确定数据集变化最大的方向,并将关于这两个要素的最大信息量编码为一个要素,以将维数从二维减少为一个。 此方法将每个点投影到这些轴或新大小上。
如下面的屏幕截图所示,这两个特征的第一个主要组成部分是点到红线上的投影,这是 PCA 中发生的事情的主要数学直觉:
......@@ -258,7 +258,7 @@ RFE 是我们将使用`RandomForestClassifier`模型的第三种技术,请记
![](img/fa90eb24-2ac3-4ab2-8541-8e645dc22c8b.png)
这就是我们具有四个特征[散布图矩阵]的散布图矩阵`x``y``z``price`的样子。 前三个特征指的是钻石的尺寸`price`表示这三个特征与钻石的定价之间的关系:
这就是我们具有四个特征[散布图矩阵]的散布图矩阵`x``y``z``price`的样子。 前三个特征指的是钻石的大小`price`表示这三个特征与钻石的定价之间的关系:
![](img/050dd302-e6ac-4f0e-a5e2-d12c18a1ec60.png)
......
......@@ -123,7 +123,7 @@
# TensorFlow 简介
TensorFlow 是一个开源软件库,用于使用数据流图进行数值计算。 计算图的概念在 TensorFlow 中非常重要,并且是专门为创建深度学习模型而设计的。 该库允许开发人员将计算部署到台式机,服务器甚至移动设备中的一个或多个 CPU 或 GPU。 该库最初由 Google 的研究人员和工程师开发。 它于 2015 年开源,从那时起,它已成为机器学习领域的主要图书馆之一。
TensorFlow 是一个开源软件库,用于使用数据流图进行数值计算。 计算图的概念在 TensorFlow 中非常重要,并且是专门为创建深度学习模型而设计的。 该库允许开发人员将计算部署到台式机,服务器甚至移动设备中的一个或多个 CPU 或 GPU。 该库最初由 Google 的研究人员和工程师开发。 它于 2015 年开源,从那时起,它已成为机器学习领域的主要之一。
TensorFlow 提供了多个 API,它们可以分为以下两种类型:
......@@ -135,7 +135,7 @@ TensorFlow 提供了多个 API,它们可以分为以下两种类型:
现在,为安装做准备,我们将在 Anaconda 中创建一个新的虚拟环境。 我们可以按照以下说明进行操作:
1. 我们打开 Anaconda 提示符。
2. 我们键入以下命令行来创建新的虚拟环境,并使用`anaconda`传递环境名称,这将安装 Anaconda 随附的所有软件包:
2. 我们键入以下命令行来创建新的虚拟环境,并使用`anaconda`传递环境名称,这将安装 Anaconda 随附的所有包:
```py
conda create-n apa anaconda
......@@ -143,7 +143,7 @@ conda create-n apa anaconda
`apa`代表高级预测分析。 安装可能需要一些时间,具体取决于您的互联网速度。
3. 安装完成后,键入`activate apa`激活新的虚拟环境。 这是 Anaconda 提示的屏幕截图,显示了 Anaconda 软件包的安装:
3. 安装完成后,键入`activate apa`激活新的虚拟环境。 这是 Anaconda 提示的屏幕截图,显示了 Anaconda 包的安装:
![](img/165875cf-3aff-4480-9425-a511a15e8cb8.png)
......
......@@ -62,7 +62,7 @@ relu = np.vectorize(relu)
* **优化算法**:此处使用的优化算法是学习率为 0.01 的梯度下降。
* **损失函数**:对于`loss`函数,我们将使用`cross_entropy`函数,但是与本书中使用的其他损失函数一样,该函数将测量实际值与测量值之间的距离。 模型做出的预测。
* **权重初始化策略**:为此,我们将使用 Xavier 初始化程序,该方法实际上是 TensorFlow 的`fully_connected`函数默认提供的方法。
* **权重初始化策略**:为此,我们将使用 Xavier 初始化,该方法实际上是 TensorFlow 的`fully_connected`函数默认提供的方法。
* **正则化策略**:我们将不使用任何正则化策略。
* **训练策略**:我们将使用 20 个周期。 数据集将被呈现给网络 20 次,并且在每次迭代中,我们将使用 80 的批量大小。因此,我们将数据一次呈现给网络 80 个点,并将整个数据集呈现给网络 20 次。
......@@ -164,7 +164,7 @@ y = tf.placeholder(tf.int64)
* **激活函数**:我们将选择 ReLu 激活函数。
* **优化算法**:这里使用的优化算法是 Adam 优化器。 Adam 优化器是最受欢迎的优化器之一,因为它是解决许多问题的最佳选择。
* **损失函数**:我们将使用均方误差,因为我们在这里进行回归问题,这是`loss`函数的最佳选择之一。
* **权重初始化策略**:为此,我们将使用 Xavier 初始化程序,它是 TensorFlow 中`fully_connected`函数的默认设置。
* **权重初始化策略**:为此,我们将使用 Xavier 初始化,它是 TensorFlow 中`fully_connected`函数的默认设置。
* **正则化策略**:我们将不使用任何正则化策略。
* **训练策略**:我们将使用 40 个周期。 我们将数据集呈现给网络 40 次,并且在每次迭代中,每次运行训练操作时,我们都会使用 50 个数据点的批量。 因此,我们将使用数据集中的 50 个元素。
......@@ -300,12 +300,9 @@ y = tf.placeholder(y_train.dtype)
的 2 的幂进行选择。
* **激活函数**:我们将选择 ELU 激活函数,该函数在上一章中已说明。
* **优化算法**:这里使用的优化算法是 Adam
优化器,学习率为 0.001。
* **优化算法**:这里使用的优化算法是 Adam 优化器,学习率为 0.001。
* **损失函数**:对于`loss`函数,我们将使用交叉熵函数。
* **权重初始化策略**:为此,我们将使用 Xavier 初始化程序,这是
方法的默认方法,该方法与
TensorFlow 中的`fully_connected`函数一起提供。
* **权重初始化策略**:为此,我们将使用 Xavier 初始化器,这是默认方法,该方法与 TensorFlow 中的`fully_connected`函数一起提供。
* **正则化策略**:我们将不使用任何正则化策略。
* **训练策略**:我们将使用 40 个周期。 因此,我们将 40 次数据集
呈现给网络,并且在每次迭代中,我们将使用 100 的批量大小。
......
......@@ -43,7 +43,7 @@ TF 2.0 的另一个主要变化是没有更多的全局变量。 在 TF 1.x 中
# 安装和使用 PIP
对于初学者来说,`pip`是 Python 社区中流行的软件包管理系统。 如果您的系统上未安装此软件,请先安装它,然后再继续进行。 在许多 Linux 安装中,默认情况下安装了 Python 和`pip`。 您可以通过键入以下命令来检查是否已安装`pip`
对于初学者来说,`pip`是 Python 社区中流行的包管理系统。 如果您的系统上未安装此软件,请先安装它,然后再继续进行。 在许多 Linux 安装中,默认情况下安装了 Python 和`pip`。 您可以通过键入以下命令来检查是否已安装`pip`
```py
python3 -m pip --help
......@@ -51,7 +51,7 @@ python3 -m pip --help
如果看到`blurb`描述`pip`支持的不同命令,则说明`pip`已安装在系统上。 如果未安装`pip`,您将看到一条错误消息,类似于`No module named pip` <q></q>
隔离开发环境通常是一个好主意。 这极大地简化了依赖管理并简化了软件开发过程。 我们可以使用 Python 中名为`virtualenv`的工具来实现环境隔离。 此步骤是可选的,但强烈建议:
隔离开发环境通常是一个好主意。 这极大地简化了依赖管理并简化了软件开发过程。 我们可以使用 Python 中名为`virtualenv`的工具来实现环境隔离。 此步骤是可选的,但强烈建议:
```py
>>mkdir .venv
......@@ -71,7 +71,7 @@ pip3 install tensorflow==version_tag
pip3 install tensorflow==2.0.0-beta1
```
最新软件包更新的完整列表可在[这个页面](https://pypi.org/project/tensorflow/#history)中找到。
最新包更新的完整列表可在[这个页面](https://pypi.org/project/tensorflow/#history)中找到。
您可以通过运行以下命令来测试安装:
......@@ -130,7 +130,7 @@ pip3 install tensorflow-gpu==2.0.0-alpha0
```
有关最新软件包更新的完整列表,请访问[这里](https://pypi.org/project/tensorflow/#history)
有关最新包更新的完整列表,请访问[这里](https://pypi.org/project/tensorflow/#history)
您可以通过运行以下命令来测试安装:
......@@ -142,7 +142,7 @@ python3 -c "import tensorflow as tf; a = tf.constant(1); print(tf.math.add(a, a)
TF 2.0 可以通过两种主要方式使用-使用低级 API 和使用高级 API。 为了在 TF 2.0 中使用低级 API,需要实现诸如`tf.GradientTape``tf.function`之类的 API。
编写低级代码的代码流程是定义函数内部的前向传递,该函数将输入数据作为参数。 然后使用`tf.function`装饰器对该函数进行注,以便在图形模式下运行它及其所有优点。 为了记录和获得前向通过的梯度,装饰器函数和损失函数都在`tf.GradientTape`上下文管理器中运行,可以从中计算梯度并将其应用于模型变量。
编写低级代码的代码流程是定义函数内部的前向传递,该函数将输入数据作为参数。 然后使用`tf.function`装饰器对该函数进行注,以便在图形模式下运行它及其所有优点。 为了记录和获得前向通过的梯度,装饰器函数和损失函数都在`tf.GradientTape`上下文管理器中运行,可以从中计算梯度并将其应用于模型变量。
训练代码也可以使用低级 API 编写,用于...
......@@ -154,19 +154,19 @@ TF 2.0 可以通过两种主要方式使用-使用低级 API 和使用高级 API
当训练和服务于机器学习模型时,可变大小的数据很常见。 在不同的基础媒体类型和模型架构中,此问题始终存在。 当代的解决方案是使用最大记录的大小,对较小的记录使用填充。 这不仅效率低下,不仅在内存或存储方面,而且在计算效率方面也是如此; 例如,当处理循环模型的输入时。
参差不齐的张量有助于解决此问题。 在非常高的水平上,参差不齐的张量可以被认为是变长链表的 TensorFlow 模拟。 这里要注意的一个重要事实是,这种可变性也可以存在于嵌套尺寸中。 这意味着有可能...
参差不齐的张量有助于解决此问题。 在非常高的水平上,参差不齐的张量可以被认为是变长链表的 TensorFlow 模拟。 这里要注意的一个重要事实是,这种可变性也可以存在于嵌套大小中。 这意味着有可能...
# 真正的参差不齐的张量是什么?
参差不齐的张量也可以定义为具有一个或多个参差不齐的尺寸的张量。 换句话说,具有可变长度切片的尺寸。 由于最常见的用例涉及处理有限数量的记录,因此参差不齐的张量要求最外面的维度是统一的,换句话说,该维度的所有切片都应具有相同的长度。 最外部尺寸之前的尺寸可以既参差不齐,也可以统一。 总结一下这些要点,我们可以指出,参差不齐的张量的形状目前仅限于以下形式:
参差不齐的张量也可以定义为具有一个或多个参差不齐的大小的张量。 换句话说,具有可变长度切片的大小。 由于最常见的用例涉及处理有限数量的记录,因此参差不齐的张量要求最外面的维度是统一的,换句话说,该维度的所有切片都应具有相同的长度。 最外部大小之前的大小可以既参差不齐,也可以统一。 总结一下这些要点,我们可以指出,参差不齐的张量的形状目前仅限于以下形式:
* 单个统一尺寸
* 后跟一个或多个参差不齐的尺寸
* 后跟零个或更多个统一尺寸
* 单个统一大小
* 后跟一个或多个参差不齐的大小
* 后跟零个或更多个统一大小
# 构造参差不齐的张量
TF 2.0 提供了大量可用于创建或返回锯齿张量的方法。 最简单的方法之一是`tf.ragged.constant()`。 让我们用它来创建尺寸为[`num_sentences`,(`num_words`)的参差不齐的张量。 请注意,我们使用圆括号来指示参差不齐的尺寸
TF 2.0 提供了大量可用于创建或返回锯齿张量的方法。 最简单的方法之一是`tf.ragged.constant()`。 让我们用它来创建大小为[`num_sentences`,(`num_words`)的参差不齐的张量。 请注意,我们使用圆括号来指示参差不齐的大小
```py
sentences = tf.ragged.constant([ ["Hello", "World", "!"], ["We", "are", "testing", "tf.ragged.constant", "."] ])print(sentences)
......@@ -224,14 +224,14 @@ print(x * x) # Multiply a ragged tensor with another ragged tensor
<tf.RaggedTensor [[1, 4, 9, 16], [1, 4]]>
```
此外,`tf.ragged`包中定义了各种特定于参差不齐的张量的运算符。 可能有必要查看软件包的文档以了解更多信息。 请参阅以下链接以获取有关此文档的详细文档:
此外,`tf.ragged`包中定义了各种特定于参差不齐的张量的运算符。 可能有必要查看包的文档以了解更多信息。 请参阅以下链接以获取有关此文档的详细文档:
* [`RaggedTensor`](https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/RaggedTensor)
* [`ragged`](https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/ragged)
# 新的重要软件
# 新的重要包
TF 2.0 的到来还伴随着 TensorFlow 下更多有趣且有用的软件包的到来,这些软件包可以单独安装。 其中一些软件包包括 TensorFlow 数据集,TensorFlow 插件,TensorFlow 文本和 TensorFlow 概率。
TF 2.0 的到来还伴随着 TensorFlow 下更多有趣且有用的包的到来,这些包可以单独安装。 其中一些包包括 TensorFlow 数据集,TensorFlow 插件,TensorFlow 文本和 TensorFlow 概率。
TensorFlow 数据集是一个 Python 模块,可轻松访问 100 多个数据集,从音频到自然语言再到图像。 这些数据集可以通过以下代码轻松下载并用于模型中:
......
......@@ -73,7 +73,7 @@ my_model.add(layer_1)
my_model.add(layer_n)
```
假设您要建立一个描述全连接神经网络的模型(也称为**多层感知器****MLP**)),以对具有五个属性的一维记录进行二进制分类。 我们的模型包括四个全连接层。 纯粹出于说明目的,我们假设每个全连接层包含 10 个节点或神经元。 这些层中的每一层都使用**整流线性单元****ReLU**)激活函数。 最终输出通过`softmax`层获取。 可以在相应层的构造函数中定义特定于层的自定义。 实现此模型的代码如下:
假设您要建立一个描述全连接神经网络的模型(也称为**多层感知器****MLP**)),以对具有五个属性的一维记录进行二进制分类。 我们的模型包括四个全连接层。 纯粹出于说明目的,我们假设每个全连接层包含 10 个节点或神经元。 这些层中的每一层都使用**整流线性单元****ReLU**)激活函数。 最终输出通过`softmax`层获取。 可以在相应层的构造中定义特定于层的自定义。 实现此模型的代码如下:
```py
model = tf.keras.Sequential()
......@@ -95,9 +95,9 @@ model.add(layers.Dense(10, activation='relu'))
model.add(layers.Dense(2, activation='softmax'))
```
使用`Sequential` API 的另一种方法是提供列表中的所有层,或者通常提供某种迭代器。 这些可以在初始化模型对象时传递给`Sequential()`构造函数。 这在分隔层描述和模型创建任务时特别有用。 让我们看下面的示例,以更好地理解这一点。
使用`Sequential` API 的另一种方法是提供列表中的所有层,或者通常提供某种迭代器。 这些可以在初始化模型对象时传递给`Sequential()`构造。 这在分隔层描述和模型创建任务时特别有用。 让我们看下面的示例,以更好地理解这一点。
考虑一下尝试从以下这些层的列表中生成模型的示例:`layer_list =[layer_1, layer_2, …. , layer_n]`。 现在可以通过将`layer_list`对象直接传递给构造函数来创建模型,如下所示:
考虑一下尝试从以下这些层的列表中生成模型的示例:`layer_list =[layer_1, layer_2, …. , layer_n]`。 现在可以通过将`layer_list`对象直接传递给构造来创建模型,如下所示:
```py
new_model = tf.keras.Sequential(layer_list)
......@@ -136,7 +136,7 @@ model_using_generator = tf.keras.Sequential(layers=get_layers(10))
# 训练模型
**训练模型**指的是为不同网络组件学习权重的过程,这些过程在给定的一组示例中将损失函数降至最低。 简而言之,训练神经网络意味着找到网络值的最佳组合。 如您所知,训练过程也与评估和预测过程紧密相关。 借助抽象的强大功能,Keras 提供了强大的高级界面来实现和管理端到端的训练过程。 让我们看一下它为使用顺序和函数式 API 创建的模型提供的训练 API。 它为此阶段提供的一些函数如下:
**训练模型**指的是为不同网络组件学习权重的过程,这些过程在给定的一组示例中将损失函数降至最低。 简而言之,训练神经网络意味着找到网络值的最佳组合。 如您所知,训练过程也与评估和预测过程紧密相关。 借助抽象的强大功能,Keras 提供了强大的高级接口来实现和管理端到端的训练过程。 让我们看一下它为使用顺序和函数式 API 创建的模型提供的训练 API。 它为此阶段提供的一些函数如下:
* `model.compile()`:此函数用于配置训练过程。 用户指定详细信息,例如优化器的类型(以及超参数(如果有的话)),损失函数的类型以及要评估的指标。 这些也是可以使用 TensorBoard 可视化的指标。 下面的示例代码片段描述了一个带有**随机梯度下降****SGD**)优化器,`CategoricalCrossentropy`损失函数和记录`Accuracy`指标的样本训练配置:
......@@ -314,7 +314,7 @@ loaded_model = tf.keras.models.load_model(
# `keras.applications`模块
`keras.applications`模块包含具有流行模型权重的预构建架构。 这些可以直接用于进行预测。 用户还可以使用它们来创建其他网络的输入特征。 该软件包中突出的预建实现包括:
`keras.applications`模块包含具有流行模型权重的预构建架构。 这些可以直接用于进行预测。 用户还可以使用它们来创建其他网络的输入特征。 该包中突出的预建实现包括:
* `densenet module`:Keras 的 DenseNet 模型
* `inception_resnet_v2`:Keras 的 Inception-ResNet V2 模型
......@@ -363,7 +363,7 @@ import tensorflow as tfimport tensorflow.keras as keras
# 估计器
从头开始构建机器学习模型时,从业人员通常会经历多个高级阶段。 其中包括训练,评估,预测和装运,以供大规模使用(或出口)。 到目前为止,开发人员必须编写自定义代码才能实现这些步骤中的每个步骤。 在所有应用中,运行这些过程所需的许多样板代码都保持不变。 更糟的是,此代码很容易需要在低抽象级别上进行操作。 这些问题放在一起,可能会在开发过程中造成极大的效率低下。
从头开始构建机器学习模型时,从业人员通常会经历多个高级阶段。 其中包括训练,评估,预测和装运,以供大规模使用(或导出)。 到目前为止,开发人员必须编写自定义代码才能实现这些步骤中的每个步骤。 在所有应用中,运行这些过程所需的许多样板代码都保持不变。 更糟的是,此代码很容易需要在低抽象级别上进行操作。 这些问题放在一起,可能会在开发过程中造成极大的效率低下。
TensorFlow 团队尝试通过引入 Estimators 来解决此问题,Estimators 是一个高级 API,旨在抽象出在上述阶段执行不同任务时产生的许多复杂性。 具体来说,估计器是用于封装以下类别任务的高级 API:
......@@ -379,7 +379,7 @@ TensorFlow 团队尝试通过引入 Estimators 来解决此问题,Estimators
* 基于估计器的模型与硬件和环境无关:
* 程序员不必担心 Estimator 是在本地计算机上运行还是在远程计算网格上运行。
* 程序员可以在 CPU,GPU 或 TPU 上运行基于 Estimator 的模型,而无需重新编码他们的模型。
* 估计器简​​化了团队中不同开发人员之间或使用不同环境或栈的团队之间的共享实现。
* 估计器简​​化了团队中不同开发人员之间或使用不同环境或栈的团队之间的共享实现。
* 程序员可以使用高级直观代码来开发高性能和前沿模型。 换句话说,程序员不必在管理低级 TensorFlow API 的复杂性上浪费时间。
* 估计器建立在`tf.keras.layers`本身上,从而简化了自定义。
* 估计器为您构建图。
......
......@@ -14,7 +14,7 @@
# 原始数据
用于训练 ML 模型的原始数据可以是文本文件,CSV 文件,图像,视频或自定义格式的文件。 原始数据甚至可以是这些文件类型的组合。 原始数据也可以是有序数据,例如时间序列数据,或者,它甚至可以是文本的量表示,例如单词嵌入。 重要的是要确保在将原始输入数据输入模型之前对其进行管理,因为它会影响运行时模型训练的效率。
用于训练 ML 模型的原始数据可以是文本文件,CSV 文件,图像,视频或自定义格式的文件。 原始数据甚至可以是这些文件类型的组合。 原始数据也可以是有序数据,例如时间序列数据,或者,它甚至可以是文本的量表示,例如单词嵌入。 重要的是要确保在将原始输入数据输入模型之前对其进行管理,因为它会影响运行时模型训练的效率。
在许多情况下,原始数据可以存储在数据库中,例如 MySQL,MS SQL,MongoDB 等。 就本书而言,假设甚至表格数据,SQL 或 NoSQL 数据都是原始数据,并且出于机器/深度学习模型的目的,需要将其拆分并转换为`TFRecords`。 解释 SQL 和 NoSQL 数据库超出了本书的范围。
......
......@@ -23,7 +23,7 @@ TensorFlow 1.x 版本强烈支持低级和中级 API,以构建机器学习模
`tf.keras`是 TensorFlow 对 Keras API 规范的实现。 这是用于构建和训练模型的高级 API,其中包括对 TensorFlow 特定功能的一流支持,例如急切执行,`tf.data`管道和估计器。 `tf.keras`使 TensorFlow 易于使用,而不会牺牲灵活性和性能。
Keras(定义 Keras API 标准的原始网站)是一个开源项目,由于其简单和强大而受到 ML 工程师和数据科学家的极大关注。 最初,Keras 的默认后端引擎(请记住,Keras 是一组 API)是 Theano; 但是,最近它发生了变化,现在 TensorFlow 作为其默认后端引擎。 您还可以将默认后端引擎设置为 MXNet,CNTK 等。 Keras API 非常易于使用,模块化且可组合。 此外,还可以轻松扩展您的特定需求。 TensorFlow 采用了 Keras API 标准,从那时起,使用 TensorFlow 核心功能的`tf.keras`开发就如火如荼地进行。 现在,随着 TF 2.0 的发布,TF 开发团队为`tf.keras`高级 API 提供了紧密而有效的支持。 另外,值得一提的是 Keras 和`tf.keras`是两个完全不同的软件包,作为 TF 2.0 的一部分,应使用`tf.keras`。 在版本方面,在 TensorFlow 2.0 中,TensorFlow 和`tf.keras`的版本号仍然存在差异,您可以尝试使用`tf.__version__``tf.keras.__version__`查看此版本。
Keras(定义 Keras API 标准的原始网站)是一个开源项目,由于其简单和强大而受到 ML 工程师和数据科学家的极大关注。 最初,Keras 的默认后端引擎(请记住,Keras 是一组 API)是 Theano; 但是,最近它发生了变化,现在 TensorFlow 作为其默认后端引擎。 您还可以将默认后端引擎设置为 MXNet,CNTK 等。 Keras API 非常易于使用,模块化且可组合。 此外,还可以轻松扩展您的特定需求。 TensorFlow 采用了 Keras API 标准,从那时起,使用 TensorFlow 核心功能的`tf.keras`开发就如火如荼地进行。 现在,随着 TF 2.0 的发布,TF 开发团队为`tf.keras`高级 API 提供了紧密而有效的支持。 另外,值得一提的是 Keras 和`tf.keras`是两个完全不同的包,作为 TF 2.0 的一部分,应使用`tf.keras`。 在版本方面,在 TensorFlow 2.0 中,TensorFlow 和`tf.keras`的版本号仍然存在差异,您可以尝试使用`tf.__version__``tf.keras.__version__`查看此版本。
# 比较估计器和`tf.keras`
......@@ -129,7 +129,7 @@ model.add(tf.keras.layers.Dense(units=num_classes,
# 模型子类化 API
模型子类化 API 通过对`tf.keras.Model`类对象进行子类化(派生)来构建完全自定义的模型。 这是通过在派生类的构造函数`__init__(...)`中创建层堆栈并将其设置为该类的属性来实现的。 此外,您可以在`call(...)`函数中实现前向通过图。
模型子类化 API 通过对`tf.keras.Model`类对象进行子类化(派生)来构建完全自定义的模型。 这是通过在派生类的构造`__init__(...)`中创建层栈并将其设置为该类的属性来实现的。 此外,您可以在`call(...)`函数中实现前向通过图。
让我们使用以下类构建模型子类:
......@@ -195,7 +195,7 @@ self.num_filters = 32
# 模型编译与训练
神经网络对复杂的非线性函数建模,例如`sin(x)``x ** 2``x ** 3`,仅举几个简单的函数, 由层的网络(栈)组成。 这些层可以是卷积层,循环层或简单的前馈层的混合。 每层由神经元组成。 神经元有两种模型化非线性的成分:前一层的加权总和,然后是激活函数。 神经网络试图以迭代方式学习给定训练数据的分布。 一旦通过指定激活函数以层栈的形式构建了神经网络,就需要定义一个目标函数(也称为损失函数)以使用适当的模型来改善模型权重。
神经网络对复杂的非线性函数建模,例如`sin(x)``x ** 2``x ** 3`,仅举几个简单的函数, 由层的网络(栈)组成。 这些层可以是卷积层,循环层或简单的前馈层的混合。 每层由神经元组成。 神经元有两种模型化非线性的成分:前一层的加权总和,然后是激活函数。 神经网络试图以迭代方式学习给定训练数据的分布。 一旦通过指定激活函数以层栈的形式构建了神经网络,就需要定义一个目标函数(也称为损失函数)以使用适当的模型来改善模型权重。
# `compile()` API
......@@ -338,9 +338,9 @@ print("Final loss: {:.3f}".format(loss(model, input_x, input_y)))
print("W = {}, B = {}".format(*model.trainable_variables))
```
TF 2.0 中添加的另一个功能是`tf.function`装饰器。 用`tf.function`函数时,它仍然像任何其他 Python 函数一样工作,但是将被编译成图形,这提供了诸如执行速度更快,GPU 和 TPU 加速之类的好处,并且可以轻松导出到`SavedModel`
TF 2.0 中添加的另一个功能是`tf.function`装饰器。 用`tf.function`函数时,它仍然像任何其他 Python 函数一样工作,但是将被编译成图形,这提供了诸如执行速度更快,GPU 和 TPU 加速之类的好处,并且可以轻松导出到`SavedModel`
并非所有函数都需要使用`tf.function`进行注释,因为在带注释的函数内部调用的任何函数也将在图形模式下运行。 对于具有多个较小操作的图形,此类函数速度更快,但对于其他具有较昂贵操作(例如卷积)的图形,改进效果会较小。
并非所有函数都需要使用`tf.function`进行注解,因为在带注解的函数内部调用的任何函数也将在图形模式下运行。 对于具有多个较小操作的图形,此类函数速度更快,但对于其他具有较昂贵操作(例如卷积)的图形,改进效果会较小。
`tf.function`装饰器还可以绘制 Python 控制流图,例如`if``while``for``break``continue``return`。 运行这些功能可实现更快的求值和硬件加速。
......
......@@ -248,7 +248,7 @@ Result for output key output_0:
# TensorFlow 服务
**TensorFlow 服务****TensorFlow 扩展****TFX**)平台的组成部分。 顾名思义,它旨在用于服务于机器学习模型。 简而言之,它是专为生产环境设计的高性能服务系统。 TensorFlow 服务的一个重要特征是它向下游用户公开了一致的 API,而与所服务模型的实际内容无关。 这使得快速进行实验和重新部署变得容易,而无需对其余软件栈进行任何其他更改。 它附带对 TensorFlow 模型的内置支持,并且可以扩展为服务于其他类型的模型。
**TensorFlow 服务****TensorFlow 扩展****TFX**)平台的组成部分。 顾名思义,它旨在用于服务于机器学习模型。 简而言之,它是专为生产环境设计的高性能服务系统。 TensorFlow 服务的一个重要特征是它向下游用户公开了一致的 API,而与所服务模型的实际内容无关。 这使得快速进行实验和重新部署变得容易,而无需对其余软件栈进行任何其他更改。 它附带对 TensorFlow 模型的内置支持,并且可以扩展为服务于其他类型的模型。
在本节中,我们将详细介绍 TensorFlow 服务。 从基本的安装和设置开始,以下小节通过一系列动手示例描述如何设置服务器来为`SavedModel`服务。 我们还将简要介绍 TensorFlow 服务提供的一些关键 API。
......@@ -265,7 +265,7 @@ Result for output key output_0:
现在我们已经设置了 TensorFlow 服务,让我们使用它来执行一些实际任务。 我们可以看看如何设置后端服务器以服务于前面几节中构建的`SavedModel`格式。 我们可以使用上一节中下载的 Docker 镜像来运行`SavedModel`格式。 为此,我们需要做两件事:
* 将本地主机上包含模型的位置绑定到容器内的目录(`/models/<your-model_name>`
* 绑定网络端口 TensorFlow 服务正在听主机上的网络端口
* 绑定网络端口 TensorFlow 服务正在听主机上的网络端口
该命令的一般形式如下:
......
......@@ -6,7 +6,7 @@
# TFLite 简介
TFLite 是一组工具,可帮助开发人员在二进制尺寸较小且延迟较低的设备上运行 TF 模型。 TFLite 由两个主要组件组成:TFLite 解释器(`tf.lite.Interpreter`)和 TFLite 转换器(`tf.lite.TFLiteConverter`)。 TFLite 解释器实际上是在低功耗设备(例如手机,嵌入式 Linux 设备和微控制器)上运行 TFLite 模型的。 另一方面,TFLite 转换器在可用于训练 TF 模型的强大设备上运行,并将训练后的 TF 模型转换为解释器的有效形式。
TFLite 是一组工具,可帮助开发人员在二进制大小较小且延迟较低的设备上运行 TF 模型。 TFLite 由两个主要组件组成:TFLite 解释器(`tf.lite.Interpreter`)和 TFLite 转换器(`tf.lite.TFLiteConverter`)。 TFLite 解释器实际上是在低功耗设备(例如手机,嵌入式 Linux 设备和微控制器)上运行 TFLite 模型的。 另一方面,TFLite 转换器在可用于训练 TF 模型的强大设备上运行,并将训练后的 TF 模型转换为解释器的有效形式。
TFLite 旨在简化在设备上执行机器学习的过程,而无需通过网络连接发送任何数据。 这样可以改善延迟时间(因为没有通过网络传输数据),提高了隐私性(因为没有数据会离开设备)和脱机功能(因为不需要互联网连接就可以在任何地方发送数据)。
......@@ -51,7 +51,7 @@ use_frameworks!
pod 'TensorFlowLiteSwift'
```
通过运行`pod install`来安装软件包,这将安装`pod`文件中包括的所有软件包,包括新添加的`TFLite`软件包。 安装后,可以通过在`swift`文件顶部附近添加`import TensorFlowLite`来导入软件包。
通过运行`pod install`来安装包,这将安装`pod`文件中包括的所有包,包括新添加的`TFLite`包。 安装后,可以通过在`swift`文件顶部附近添加`import TensorFlowLite`来导入包。
2. 要运行`interpreter`,首先为张量分配内存:
......@@ -124,7 +124,7 @@ USB 加速器与任何具有运行 Debian 的 USB 端口的 Linux 计算机兼
![](img/ee7dff88-2f0b-4a1a-86b9-966f0c8ce1d7.png)
但是,Edge TPU 有两个约束。 如前所述,必须使用量化感知训练对`Tensor`参数进行量化。 张量大小必须恒定(这样就不能有动态大小); 模型参数必须恒定; 张量必须是一维,二维或三维张量,或者是三个最里面的尺寸大于 3 维的张量,并且只能包含 Edge TPU 支持的那些操作。 如果不满足这些要求,那么将仅编译某些模型。 模型图中发生不支持的操作的第一点是编译器将图分为两部分:一部分包含 Edge TPU 可以计算的所有操作,另一部分包含它不能计算的操作,这些部分将运行在 CPU 上:
但是,Edge TPU 有两个约束。 如前所述,必须使用量化感知训练对`Tensor`参数进行量化。 张量大小必须恒定(这样就不能有动态大小); 模型参数必须恒定; 张量必须是一维,二维或三维张量,或者是三个最里面的大小大于 3 维的张量,并且只能包含 Edge TPU 支持的那些操作。 如果不满足这些要求,那么将仅编译某些模型。 模型图中发生不支持的操作的第一点是编译器将图分为两部分:一部分包含 Edge TPU 可以计算的所有操作,另一部分包含它不能计算的操作,这些部分将运行在 CPU 上:
![](img/aedc0f8e-e06f-4917-ad0a-41abe07ad00b.png)
......
......@@ -22,7 +22,7 @@ TF 1.x 中的`session.run()`调用与...非常相似。
# 适用于 TF 2.0 的推荐技术
第一条建议涉及在 TF 2.0 中处理常规代码工作流。 TF 1.x 中常见的工作流程是使用瀑布策略,其中所有计算都布置在默认图形上。 然后,使用`session.run()`运行选定的张量。 在 TF 2.0 中,应将代码重构为较小的函数,这些函数将在需要时调用。 这些函数可以是普通的 Python 函数,但如果在另一个以`tf.function`释的函数中调用它们,则仍可以在图形模式下运行。 这意味着`tf.function`仅应用于注释高级计算,例如模型的前向传递或单个训练步骤。
第一条建议涉及在 TF 2.0 中处理常规代码工作流。 TF 1.x 中常见的工作流程是使用瀑布策略,其中所有计算都布置在默认图形上。 然后,使用`session.run()`运行选定的张量。 在 TF 2.0 中,应将代码重构为较小的函数,这些函数将在需要时调用。 这些函数可以是普通的 Python 函数,但如果在另一个以`tf.function`解的函数中调用它们,则仍可以在图形模式下运行。 这意味着`tf.function`仅应用于注解高级计算,例如模型的前向传递或单个训练步骤。
以前,模型和训练循环所需的所有计算都将预先确定并编写,并使用`session.run()`执行。 这使得 TF 1.x 代码对于大多数编码人员来说很难遵循,因为模型的流程可能与图形的编码方式完全不同,因为该图是在最后运行的。 急切执行和`tf.function`专门用于简化 TensorFlow 代码动态过程,并使其他开发人员更容易理解预编写的代码。
......@@ -116,7 +116,7 @@ model.fit(dataset)
# 转换 TF 1.x 模型
第一步是将所有`tf.Session.run()`调用替换为 Python 函数。 这意味着将`tf.placeholder``feed_dict`转换为函数参数。 这些成为函数的返回值。 此更改意味着与 TF 1.x 不同,可以使用标准的 Python 工具(例如`pdb`)来逐步调试该功能。 构建函数后,可以添加`tf.function`批注以在图形模式下运行该函数,以及 TF 1.x 中等效的`tf.Session.run`调用的效率。
第一步是将所有`tf.Session.run()`调用替换为 Python 函数。 这意味着将`tf.placeholder``feed_dict`转换为函数参数。 这些成为函数的返回值。 此更改意味着与 TF 1.x 不同,可以使用标准的 Python 工具(例如`pdb`)来逐步调试该功能。 构建函数后,可以添加`tf.function`注解以在图形模式下运行该函数,以及 TF 1.x 中等效的`tf.Session.run`调用的效率。
使用`tf.layers` API 创建的 TF 1.x 模型可以相对容易地转换为 TF 2.0。 `tf.layers`模块用于包含依赖于`tf.variable_scope`定义和重用变量的层函数。
......@@ -194,7 +194,7 @@ with tf.Session() as sess:
feed_dict={in_a: [1, 0], in_b: [0, 1]})
```
可以通过将前向函数更改为用`tf.function`的函数进行基于图形的计算,删除`session.run`函数和变量范围并添加简单的函数调用来转换此代码。 将不会在`W`变量上全局调用正则化; 相反,它将被手动调用,而无需引用全局集合:
可以通过将前向函数更改为用`tf.function`的函数进行基于图形的计算,删除`session.run`函数和变量范围并添加简单的函数调用来转换此代码。 将不会在`W`变量上全局调用正则化; 相反,它将被手动调用,而无需引用全局集合:
```py
W = tf.Variable(tf.ones(shape=(2,2)), name="W")
......@@ -269,7 +269,7 @@ class CustomLayer(tf.keras.layers.Layer):
前面的代码创建了一个名为`CustomLayer`的类,该类继承了`tf.keras.layers.Layer`类的属性。 此技术允许在`tf.keras`模型内部使用任何类型的低级代码,而不管它是使用`Sequential` API 还是`functional` API 的模型。 此类中有两种方法:
* `build()`:此方法修改继承的类的默认生成方法。 在这种方法中,应该创建模型所需的所有变量。 尽管可以在模型的`the __init__()`方法中完成此操作,但建议使用`build()`,以便在正确的最佳时间构建变量。 可以使用`self.add_weight`函数完成此操作,以使 Keras 跟踪变量和正则化损失。
* `call()`:在输入张量上调用模型时,将运行此方法。 此方法通常采用两个参数:`inputs``training`。 尽管`inputs`参数是不言自明的,但`training`参数可能不会一直使用,但是对于在该层中使用批量规范化和丢弃的情况而言是必不可少的。 该功能由`tf.function`装饰器批注,以实现签名,基于图的优点以及自动控件的依赖关系。
* `call()`:在输入张量上调用模型时,将运行此方法。 此方法通常采用两个参数:`inputs``training`。 尽管`inputs`参数是不言自明的,但`training`参数可能不会一直使用,但是对于在该层中使用批量规范化和丢弃的情况而言是必不可少的。 该功能由`tf.function`装饰器注解,以实现签名,基于图的优点以及自动控件的依赖关系。
写入此自定义层后,即可在`tf.keras`模块中的任何位置使用它。 对于此转换,将使用`Sequential` API:
......@@ -295,7 +295,7 @@ test_out = model(test_data, training=False)
在 TF 2.0 中,可以使用三种类型的训练循环。 这些循环中的每一个都有不同的优点和缺点,并且难度,API 级别和复杂性各不相同。 它们如下:
* 第一种训练循环是`tf.keras.Model.fit()`。 这是一个内置的训练循环,可处理训练的所有方面,并为各种 Keras 提供统一的界面...
* 第一种训练循环是`tf.keras.Model.fit()`。 这是一个内置的训练循环,可处理训练的所有方面,并为各种 Keras 提供统一的接口...
# 转换时要注意的其他事项
......@@ -367,11 +367,11 @@ print(' accuracy: {:.3f}'.format(mean_accuracy))
**用 TF 2.0 编写的代码的速度是否与基于图的 TF 1.x 代码相同?**
是的,使用`tf.function``tf.keras`在 TF 2.0 中编写的代码将具有与 TF 1.x 相同的速度和最优性。 正如我们在本章前面提到的那样,使用`tf.function`主要功能允许模型以图模式运行,并且该功能中的所有计算和逻辑都将编译为一个计算图。 使用`tf.keras`定义和训练 TensorFlow 模型也是如此。 使用`model.fit`方法还将在图形模式下训练模型,并具有所有优点和优化功能,这些优点和优点包括:
是的,使用`tf.function``tf.keras`在 TF 2.0 中编写的代码将具有与 TF 1.x 相同的速度和最优性。 正如我们在本章前面提到的那样,使用`tf.function`主要功能允许模型以图模式运行,并且该功能中的所有计算和逻辑都将编译为一个计算图。 使用`tf.keras`定义和训练 TensorFlow 模型也是如此。 使用`model.fit`方法还将在图形模式下训练模型,并具有所有优点和优化功能,这些优点和优点包括:
# TF 2.0 的未来
TF 2.0 目前处于 beta 版本,因此仍在开发中。 即将出现的一些关键功能包括对软件包的修改,例如 TensorBoard,TensorFlow Lite,TensorFlow.js,用于 TensorFlow 的 Swift 和 TensorFlow Extended,以及对基本 API 的微小更改。 TensorBoard 将看到增强功能,例如改进的超参数调优功能,引入托管功能以使共享仪表板变得容易,并使插件能够使用不同的前端技术,例如 ReactJS。 TensorFlow Lite 将扩大支持的操作范围,将 TF 2.0 模型更轻松地转换为 TFLite,并扩展对 Edge TPU 和 AIY 板的支持。 TensorFlow.js 和用于 TensorFlow 的 Swift 都将看到速度和性能方面的改进,并且很快将包含一组丰富的示例和带有端到端教程的入门指南。 TF Extended 即将与 TF 2.0 基本 API 完全集成,并将包括完全协调的端到端工作流程和训练函数。
TF 2.0 目前处于 beta 版本,因此仍在开发中。 即将出现的一些关键功能包括对包的修改,例如 TensorBoard,TensorFlow Lite,TensorFlow.js,用于 TensorFlow 的 Swift 和 TensorFlow Extended,以及对基本 API 的微小更改。 TensorBoard 将看到增强功能,例如改进的超参数调优功能,引入托管功能以使共享仪表板变得容易,并使插件能够使用不同的前端技术,例如 ReactJS。 TensorFlow Lite 将扩大支持的操作范围,将 TF 2.0 模型更轻松地转换为 TFLite,并扩展对 Edge TPU 和 AIY 板的支持。 TensorFlow.js 和用于 TensorFlow 的 Swift 都将看到速度和性能方面的改进,并且很快将包含一组丰富的示例和带有端到端教程的入门指南。 TF Extended 即将与 TF 2.0 基本 API 完全集成,并将包括完全协调的端到端工作流程和训练函数。
TF 2.0 基本 API 将包括针对任务的更多预制估计器,例如增强树,随机森林,最近邻搜索和 k 均值聚类。 `tf.distribute.Strategy`模型将扩展其对 Keras 子模型,TPU 和多节点训练的支持,以在多个处理器上实现更优化和更快的训练。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册