提交 c48b1156 编写于 作者: W wizardforcel

2021-01-15 22:27:33

上级 73851ef4
......@@ -84,7 +84,7 @@ Rosenblatt 还介绍了权重的概念(`w`1,`w`2,…,`w`n),这些数
注意
在神经网络中引用层的常规方法如下:
在神经网络中引用层的常规方法如下:
第一层是输入层,最后一层是输出层,中间的所有层都是隐藏层。
......@@ -288,7 +288,7 @@ CNN 创建的模型使用神经元的子组来识别图像的不同方面。 这
考虑到这一点,CNN 的体系结构中的层划分了它们的识别任务。 第一层专注于琐碎的模式,而网络末端的层则使用该信息来揭示更复杂的模式。
例如,当识别图片中的人脸时,前几层专注于寻找将一个特征与另一个特征分开的边缘。 接下来,后续层强调面部的某些特征,例如鼻子。 最后,最后两层使用此信息将人的整个面孔放在一起。
例如,当识别图片中的人脸时,前几层专注于寻找将一个特征与另一个特征分开的边缘。 接下来,后续层强调面部的某些特征,例如鼻子。 最后,最后两层使用此信息将人的整个面孔放在一起。
当遇到某些特征时激活一组神经元的想法是通过使用过滤器(内核)来实现的,过滤器(内核)是 CNN 架构的主要组成部分之一。 但是,它们不是体系结构中存在的唯一元素,这就是为什么在此将对 CNN 的所有组件进行简要说明的原因:
......@@ -344,7 +344,7 @@ CNN 创建的模型使用神经元的子组来识别图像的不同方面。 这
3. **Fully connected layers**: Finally, considering that the network would be of no use if it was only capable of detecting a set of features without having the capability of classifying them into a class label, fully connected layers are used at the end of CNNs to take the features that were detected by the previous layer (known as the feature map) and output the probability of that group of features belonging to a class label, which is used to make the final prediction.
像人工神经网络一样,全连接层使用感知器根据给定的输入来计算输出。 此外,至关重要的是要提到 CNN 在体系结构的末尾通常具有不止一个完全连接的层。
像人工神经网络一样,全连接层使用感知器根据给定的输入来计算输出。 此外,至关重要的是要提到 CNN 在体系结构的末尾通常具有不止一个全连接层。
通过组合所有这些概念,可以获得 CNN 的常规体系结构。 每个类型可以有任意数量的层,每个卷积层可以具有任意数量的滤镜(每个滤镜用于特定任务)。 此外,池化层应具有与上一个卷积层相同数量的过滤器,如下图所示:
......
......@@ -111,7 +111,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
## CNN 的基础
深度卷积网络是一种将图像作为输入并通过一系列**卷积层**和滤镜,**池化层****完全连接的**的网络。 HTG6] FC 层,以最终应用 **softmax** 激活函数,该函数将图像分类为类标签。 与 ANN 一样,这种分类形式是通过为图像赋予每个类别标签一个介于 0 和 1 之间的值来计算属于每个类别标签的图像的概率来执行的。 具有较高概率的类别标签被选择为该图像的最终预测。
深度卷积网络是一种将图像作为输入并通过一系列**卷积层**和滤镜,**池化层****全连接层**(FC)的网络,以最终应用 **softmax** 激活函数,该函数将图像分类为类标签。 与 ANN 一样,这种分类形式是通过为图像赋予每个类别标签一个介于 0 和 1 之间的值来计算属于每个类别标签的图像的概率来执行的。 具有较高概率的类别标签被选择为该图像的最终预测。
以下是对每个层的详细说明,以及如何在 PyTorch 中定义此类层的代码示例。
......@@ -123,7 +123,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
注意
再次访问 CNN 的*简介“第 2 章”,*神经网络*的*部分,以提醒您在输入和滤波器之间执行的确切计算。
再次访问 “第 2 章”,“神经网络 CNN 的简介”部分,以提醒您在输入和滤波器之间执行的确切计算。
所得矩阵的形状取决于输入的形状,其中包含大小为[`h`x`w`x`c`的图像矩阵) 大小(`f`hx`f`wx`c`)的大小将根据以下公式输出:
......@@ -199,7 +199,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
注意
*图 4.12* 中的数字是构成的,不是实际的计算。 重点应放在方框上,这些方框说明步幅等于 2 时的移动过程。
“图 4.12”中的数字是构成的,不是实际的计算。 重点应放在方框上,这些方框说明步幅等于 2 时的移动过程。
使用步幅时,以下方程式可用于计算输出宽度:
......@@ -261,7 +261,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
这样,您就成功地计算了从卷积层得出的矩阵的输出形状。
在 PyTorch 中编码卷积层非常简单。 使用自定义模块,只需要创建**网络**类。 该类应包含定义网络体系结构(即网络层)的 **__init__** 方法和定义要对信息进行计算的**转发**方法。 穿过图层,如以下代码片段所示:
在 PyTorch 中编码卷积层非常简单。 使用自定义模块,只需要创建**网络**类。 该类应包含定义网络体系结构(即网络层)的`__init__`方法和定义要对信息进行计算的`forward`方法。 穿过层,如以下代码片段所示:
将 torch.nn 导入为 nn
......@@ -305,9 +305,9 @@ x = self.conv1(x)
返回 x
在这里,层的定义发生在**顺序**容器内部。 通常,一个容器包括卷积层,激活功能和池化层。 一组新的层包含在其下面的不同容器中。
在这里,层的定义发生在**顺序**容器内部。 通常,一个容器包括卷积层,激活功能和池化层。 一组新的层包含在其下面的不同容器中。
在前面的示例中,在**顺序**容器内定义了卷积层和激活层。 因此,在**正向**方法中,不需要卷积层的输出通过激活函数,因为已经使用容器对其进行了处理。
在前面的示例中,在**顺序**容器内定义了卷积层和激活层。 因此,在`forward`方法中,不需要卷积层的输出通过激活函数,因为已经使用容器对其进行了处理。
### 池层
......@@ -329,13 +329,13 @@ x = self.conv1(x)
## 练习 4.02:计算一组卷积和池化层的输出形状
以下练习将结合卷积层和池化层。 目的是确定经过一组层后的输出矩阵的大小。
以下练习将结合卷积层和池化层。 目的是确定经过一组层后的输出矩阵的大小。
注意
此练习不需要编码,而是由基于我们前面提到的概念的计算组成。
考虑以下几组层,并在所有转换结束时指定输出层的形状,并考虑 256 x 256 x 3 的输入图像:
考虑以下几组层,并在所有转换结束时指定输出层的形状,并考虑 256 x 256 x 3 的输入图像:
1. 卷积层,具有 16 个大小为 3 的滤镜,步幅和填充为 1。
2. 池层还具有大小为 2 的过滤器以及大小为 2 的步幅。
......@@ -402,7 +402,7 @@ x = self.pool1(x)
返回 x
可以看出,在 **__init__** 方法中将池化层(**MaxPool2d**)添加到网络体系结构中。 在这里,进入最大池层的参数从左到右分别是过滤器(`2`)和步幅(`2`)的大小。 接下来,更新了**正向**方法,以使信息通过新的合并层。
可以看出,在`__init__`方法中将池化层(`MaxPool2d`)添加到网络体系结构中。 在这里,进入最大池层的参数从左到右分别是过滤器(`2`)和步幅(`2`)的大小。 接下来,更新了`forward`方法,以使信息通过新的合并层。
同样,这里显示了一种同样有效的方法,其中使用了自定义模块和**顺序**容器:
......@@ -428,9 +428,9 @@ x = self.conv1(x)
正如我们之前提到的,池化层还包含在激活函数下方与卷积层相同的容器中。 在新的**顺序**容器中,下面将定义一组后续层(卷积,激活和池化)。
同样,**转发**方法不再需要单独调用每个层; 而是通过容器传递信息,该容器既包含图层又包含激活功能。
同样,`forward`方法不再需要单独调用每个层; 而是通过容器传递信息,该容器既包含层又包含激活功能。
### 完全连接的
### 全连接
在输入经过一组卷积和池化层之后,在网络体系结构的末尾定义一个或多个 FC 层。 来自第一 FC 层之前的层的输出数据从矩阵展平为向量,可以将其馈送到 FC 层(与传统神经网络的隐藏层相同)。
......@@ -474,7 +474,7 @@ x = F.log_softmax(self.linear2(x),dim = 1)
返回 x
使用与上一节相同的编码示例,在 **__init__** 方法内部,将两个 FC 层添加到网络。 接下来,在**正向**函数内部,使用 **view()**函数将池化层的输出展平。 然后,它通过第一 FC 层,该层应用激活功能。 最后,数据连同其激活功能一起通过最终的 FC 层。
使用与上一节相同的编码示例,在`__init__`方法内部,将两个 FC 层添加到网络。 接下来,在`forward`函数内部,使用`view()`函数将池化层的输出展平。 然后,它通过第一 FC 层,该层应用激活功能。 最后,数据连同其激活功能一起通过最终的 FC 层。
同样,使用与之前相同的编码示例,可以使用自定义模块和**顺序**容器将 FC 层添加到我们的模型中,如下所示:
......@@ -508,7 +508,7 @@ x = F.log_softmax(self.linear2(x),dim = 1)
返回 x
可以看出,**顺序**容器保持不变,并在 **__init__** 方法内在下面添加了两个 FC 层。 接下来,**正向**函数将信息传递通过整个容器,然后将输出平坦化以通过 FC 层。
可以看出,**顺序**容器保持不变,并在`__init__`方法内在下面添加了两个 FC 层。 接下来,`forward`函数将信息传递通过整个容器,然后将输出平坦化以通过 FC 层。
一旦定义了网络的架构,就可以按照与 ANN 相同的方式来处理训练网络的以下步骤。
......@@ -528,7 +528,7 @@ transforms.Normalize((0.5,0.5,0.5),\
(0.5, 0.5, 0.5))])
**转换**变量用于定义要在数据集上执行的一组转换。 在这种情况下,数据集将被转换为张量并在其所有维度上进行规范化。
`transforms`变量用于定义要在数据集上执行的一组转换。 在这种情况下,数据集将被转换为张量并在其所有维度上进行规范化。
train_data =数据集.MNIST(root ='data',train = True,\
......@@ -540,7 +540,7 @@ download = True,transform = transform)
在前面的代码中,要下载的数据集是 MNIST。 这是一个流行的数据集,其中包含从零到九的手写灰度数字图像。 PyTorch 数据集提供训练和测试集。
从前面的代码片段可以看出,要下载数据集,有必要定义数据的根,默认情况下应将其定义为 **data** 。 接下来,定义您是要下载培训还是测试数据集。 我们将**下载**参数设置为 **True** 。 最后,我们使用之前定义的**转换**变量对数据集执行转换:
从前面的代码片段可以看出,要下载数据集,有必要定义数据的根,默认情况下应将其定义为`data`。 接下来,定义您是要下载培训还是测试数据集。 我们将`download`参数设置为`True`。 最后,我们使用之前定义的`transform`变量对数据集执行转换:
dev_size = 0.2
......@@ -558,7 +558,7 @@ train_sampler = SubsetRandomSampler(train_idx)
dev_sampler = SubsetRandomSampler(dev_idx)
在前面的代码段中,PyTorch 的 **SubsetRandomSampler()**函数用于通过随机采样索引将原始训练集分为训练集和验证集。 在接下来的步骤中将使用它来生成将在每次迭代中馈送到模型中的批处理:
在前面的代码段中,PyTorch 的`SubsetRandomSampler()`函数用于通过随机采样索引将原始训练集分为训练集和验证集。 在接下来的步骤中将使用它来生成将在每次迭代中馈送到模型中的批处理:
batch_size = 20
......@@ -578,7 +578,7 @@ test_loader = torch.utils.data.DataLoader(test_data,\
batch_size =批量大小)
**DataLoader()**函数用于为每组数据批量加载图像。 首先,将包含集合的变量作为参数传递,然后定义批处理大小。 最后,我们在上一步中创建的采样器用于确保随机创建每次迭代中使用的批次,这有助于提高模型的性能。 此函数的结果变量(**train_loader****dev_loader****test_loader**)将分别包含功能部件和目标的值。
`DataLoader()`函数用于为每组数据批量加载图像。 首先,将包含集合的变量作为参数传递,然后定义批处理大小。 最后,我们在上一步中创建的采样器用于确保随机创建每次迭代中使用的批次,这有助于提高模型的性能。 此函数的结果变量(`train_loader``dev_loader``test_loader`)将分别包含功能部件和目标的值。
注意
......@@ -602,7 +602,7 @@ batch_size =批量大小)
2. 设置要对数据执行的转换,这将是数据到张量的转换以及像素值的归一化。
3. 设置批量为 100 张图像,并从 **CIFAR10** 数据集下载训练和测试数据。
4. 使用 20% 的验证大小,定义将用于将数据集分为这两组的训练和验证采样器。
5. 使用 **DataLoader()**函数定义用于每组数据的批次。
5. 使用`DataLoader()`函数定义用于每组数据的批次。
6. Define the architecture of your network. Use the following information to do so:
Conv1:卷积层,将彩色图像作为输入,并将其通过大小为 3 的 10 个滤镜。应将 padding 和 stride 都设置为 1。
......@@ -617,9 +617,9 @@ batch_size =批量大小)
展平图像后,滤除项设置为 20%。
线性 1:一个完全连接的层,接收上一层的展平矩阵作为输入,并生成 100 个单位的输出。 为此层使用 ReLU 激活功能。 此处,辍学期限设置为 20%。
线性 1:一个全连接层,接收上一层的展平矩阵作为输入,并生成 100 个单位的输出。 为此层使用 ReLU 激活功能。 此处,辍学期限设置为 20%。
Linear2:一个完全连接的层,可生成 10 个输出,每个类标签一个。 将 **log_softmax** 激活功能用于输出层。
Linear2:一个全连接层,可生成 10 个输出,每个类标签一个。 将`log_softmax`激活功能用于输出层。
7. 定义训练模型所需的所有参数。 将纪元数设置为 50。
8. 训练您的网络,并确保保存训练和验证集的损失和准确性值。
......@@ -664,7 +664,7 @@ batch_size =批量大小)
## 使用 PyTorch 进行数据增强
使用 **Torchvision** 包在 PyTorch 中执行数据增强非常容易。 该软件包除了包含流行的数据集和模型架构之外,还包含可以在数据集上执行的常见图像转换功能。
使用`Torchvision`包在 PyTorch 中执行数据增强非常容易。 该软件包除了包含流行的数据集和模型架构之外,还包含可以在数据集上执行的常见图像转换功能。
注意
......@@ -692,7 +692,7 @@ test_data =数据集.CIFAR10('data',train = False,\
download = True,transform = transform)
在这里,使用 **Horizo​​ntalFlip** 函数,将要下载的数据将进行水平翻转(考虑用户设置的概率值,并确定将进行此变换的图像的百分比)。 通过使用 **RandomGrayscale** 函数,图像将被转换为灰度(还考虑了概率)。 然后,将数据转换为张量并进行规范化。
在这里,使用`Horizo​​ntalFlip`函数,将要下载的数据将进行水平翻转(考虑用户设置的概率值,并确定将进行此变换的图像的百分比)。 通过使用`RandomGrayscale`函数,图像将被转换为灰度(还考虑了概率)。 然后,将数据转换为张量并进行规范化。
考虑到模型是在迭代过程中进行训练的,其中多次输入训练数据,因此这些转换可确保第二次遍历数据集不会将完全相同的图像馈入模型。
......@@ -745,7 +745,7 @@ transform = transform [“ test”])
1. 复制上一个活动中的笔记本。
2. Change the definition of the **transform** variable so that it includes, in addition to normalizing and converting the data into tensors, the following transformations:
对于训练/验证集, **RandomHorizo​​ntalFlip** 函数的概率为 50% (0.5), **RandomGrayscale** 函数的概率为 10% (0.1)。
对于训练/验证集,`RandomHorizo​​ntalFlip`函数的概率为 50% (0.5),`RandomGrayscale`函数的概率为 10% (0.1)。
对于测试集,请勿添加任何其他转换。
......@@ -802,8 +802,8 @@ transform = transform [“ test”])
在 PyTorch 中,考虑到有两种不同的类型,添加批归一化就像向网络体系结构添加新层一样简单,如下所述:
* **BatchNorm1d**:此层用于在二维或三维输入上实现批量标准化。 它从上一层接收输出节点的数量作为参数。 这通常在 FC 层上使用。
* **BatchNorm2d**:这将批量归一化应用于四维输入。 同样,它采用的参数是上一层输出节点的数量。 它通常在卷积层上使用,这意味着它接受的参数应等于上一层的通道数。
* `BatchNorm1d`:此层用于在二维或三维输入上实现批量标准化。 它从上一层接收输出节点的数量作为参数。 这通常在 FC 层上使用。
* `BatchNorm2d`:这将批量归一化应用于四维输入。 同样,它采用的参数是上一层输出节点的数量。 它通常在卷积层上使用,这意味着它接受的参数应等于上一层的通道数。
据此,在 CNN 中批量标准化的实现如下:
......@@ -837,7 +837,7 @@ x = F.log_softmax(self.linear2(x),dim = 1)
返回 x
如我们所见,批处理规范化层的初始定义与 **__init__** 方法内的其他任何层类似。 接下来,在**正向**方法内的激活函数之后,将每个批处理归一化层应用于其对应层的输出。
如我们所见,批处理规范化层的初始定义与`__init__`方法内的其他任何层类似。 接下来,在`forward`方法内的激活函数之后,将每个批处理归一化层应用于其对应层的输出。
## 活动 4.03:实现批量标准化
......
此差异已折叠。
此差异已折叠。
......@@ -1086,9 +1086,9 @@
展平图像后,使用掉落项设置为 20%。
线性 1:一个完全连接的层,接收上一层的展平矩阵作为输入,并生成 100 个单位的输出。 为此层使用 ReLU 激活功能。 此处的辍学期限设置为 20%。
线性 1:一个全连接层,接收上一层的展平矩阵作为输入,并生成 100 个单位的输出。 为此层使用 ReLU 激活功能。 此处的辍学期限设置为 20%。
Linear2:一个完全连接的层,可生成 10 个输出,每个类标签一个。 将 **log_softmax** 激活功能用于输出层:
Linear2:一个全连接层,可生成 10 个输出,每个类标签一个。 将 **log_softmax** 激活功能用于输出层:
CNN(nn.Module)类:
......@@ -1798,7 +1798,7 @@
'21':'conv4_2','28':'conv5_1'}
def features_extractor(x,模型,层):
def features_extractor(x,模型,层):
功能= {}
......@@ -1826,13 +1826,13 @@
8. Calculate the gram matrix for the style features. Also, create the initial target image.
以下代码段为用于提取样式特征的每个层创建了 gram 矩阵:
以下代码段为用于提取样式特征的每个层创建了 gram 矩阵:
style_grams = {}
对于我在 style_features 中:
层= style_features [i]
层= style_features [i]
_,d1,d2,d3 = layer.shape
......@@ -1878,7 +1878,7 @@
对于范围(1,迭代+1)中的 i:
#提取所有相关层的特征
#提取所有相关层的特征
target_features = features_extractor(target_img,模型,\
......@@ -1894,7 +1894,7 @@
style_losses = 0
用于 style_weights 中的层:
用于 style_weights 中的层:
#为该层创建语法矩阵
......@@ -1910,7 +1910,7 @@
style_gram = style_grams [layer]
#计算该层的样式损失
#计算该层的样式损失
style_loss = style_weights [layer] * \
......@@ -1918,7 +1918,7 @@
style_gram)** 2)
#计算所有层的样式丢失
#计算所有层的样式丢失
style_losses + = style_loss /(d1 * d2 * d3)
......
......@@ -55,7 +55,7 @@ Logistic 回归是**判别式分类器**的一种形式,在判别式分类器
![](img/2ea3be34-ced7-4c60-a302-98d1f0c35e3e.jpeg)
因此,例如,如果我们查看花朵与汽车等类别,则初始层的功能就足够了。 但是,如果我们有诸如汽车类型之类的类别,则需要更深层次的模型,因为我们需要提取更复杂的特征,这需要更大的数据集。 问题是,什么决定了模型学习的特征或参数的类型,是否有可能在初始层学习这些重要参数? 在下一部分中,我们将探索 Siamese 网络,它是一种神经网络架构,可以通过更改损失函数及其架构设计来学习前几层的复杂功能。
因此,例如,如果我们查看花朵与汽车等类别,则初始层的功能就足够了。 但是,如果我们有诸如汽车类型之类的类别,则需要更深层次的模型,因为我们需要提取更复杂的特征,这需要更大的数据集。 问题是,什么决定了模型学习的特征或参数的类型,是否有可能在初始层学习这些重要参数? 在下一部分中,我们将探索 Siamese 网络,它是一种神经网络架构,可以通过更改损失函数及其架构设计来学习前几层的复杂功能。
# 了解暹罗网络
......@@ -73,9 +73,9 @@ Logistic 回归是**判别式分类器**的一种形式,在判别式分类器
暹罗网络由两个相同的神经网络组成,它们共享相似的参数,每个磁头获取一个输入数据点。 在中间层,由于权重和偏差相同,因此我们提取了相似的特征。 这些网络的最后一层被馈送到**对比损失函数层**,,该层计算两个输入之间的相似度。
您可能会遇到的一个问题是,为什么暹罗网络的层共享参数? 如果我们已经在努力改变损失函数,这是否有助于我们分别训练各层?
您可能会遇到的一个问题是,为什么暹罗网络的层共享参数? 如果我们已经在努力改变损失函数,这是否有助于我们分别训练各层?
我们不单独训练层的主要原因有两个:
我们不单独训练层的主要原因有两个:
* 对于每一层,我们都添加了数千个参数。 因此,类似于我们在共享参数的卷积神经网络方法中所做的工作,我们可以更快地优化网络。
* 权重共享确保两个相似的图像不会映射到要素嵌入空间中的不同位置。
......@@ -232,7 +232,7 @@ VGG16 和 Inception Net 是深度学习架构,它们在 ImageNet 数据集上
* **问题 1:**即使分类策略 <sub>![](img/17dc3f3b-c6a5-4351-b438-0bea4fdd2273.png)</sub>已设定条件,训练集图像的嵌入也彼此独立,而不认为它们是支持集的一部分 在支持集上。
**解决方案:**匹配网络使用**双向长短期存储器****LSTM**)在整个支持范围内启用每个数据点的编码 组。 通常,LSTM 用于理解数据序列,因为它们能够使用其单元内部的门保持整个数据的上下文。 同样,使用双向 LSTM 可以更好地理解数据序列。 匹配网络使用双向 LSTM 来确保支持集中一幅图像的嵌入将具有所有其他图像嵌入的上下文。
**解决方案:**匹配网络使用**双向长短期记忆****LSTM**)在整个支持范围内启用每个数据点的编码 组。 通常,LSTM 用于理解数据序列,因为它们能够使用其单元内部的门保持整个数据的上下文。 同样,使用双向 LSTM 可以更好地理解数据序列。 匹配网络使用双向 LSTM 来确保支持集中一幅图像的嵌入将具有所有其他图像嵌入的上下文。
* **问题 2:**如果要计算两个数据点之间的相似度,首先需要将它们放入相同的嵌入空间。 因此,支持集`S`必须能够有助于提取测试图像嵌入。
......@@ -1059,7 +1059,7 @@ plot_loss(train_loss,val_loss)
![](img/97d99dae-968d-45c3-9d2f-13cf0b663c2b.png)
在本节中,我们探索了使用 MNIST 数据集的暹罗网络的实现以及使用 Omniglot 数据集的匹配网络体系结构。 在 Siamese 网络编码练习中,我们创建了一个小的卷积层,并由一个完全连接的层姐妹体系结构进行了扩展。 训练模型后,我们还绘制了模型获得的二维嵌入图,并观察了某些数字如何聚类在一起。 同样,在匹配网络编码练习中,我们为匹配网络的每个模块实现了小型体系结构,例如嵌入提取器,注意力模型和完全上下文嵌入。 我们还观察到,仅用 100 个时期,我们就可以达到约 86% 的精度,并绘制了匹配网络架构的精度和损耗图。
在本节中,我们探索了使用 MNIST 数据集的暹罗网络的实现以及使用 Omniglot 数据集的匹配网络体系结构。 在 Siamese 网络编码练习中,我们创建了一个小的卷积层,并由一个全连接层姐妹体系结构进行了扩展。 训练模型后,我们还绘制了模型获得的二维嵌入图,并观察了某些数字如何聚类在一起。 同样,在匹配网络编码练习中,我们为匹配网络的每个模块实现了小型体系结构,例如嵌入提取器,注意力模型和完全上下文嵌入。 我们还观察到,仅用 100 个时期,我们就可以达到约 86% 的精度,并绘制了匹配网络架构的精度和损耗图。
您可能还观察到某些模型是从头开始训练的-我们可能已经使用了转移学习体系结构,或者增加了 LSTM 体系结构的隐藏大小,或者也许被认为是加权的交叉熵损失函数。 总是有实验和改进的空间。 如果您想进一步尝试使用该模型,建议您访问本书的 GitHub 页面。
......
......@@ -396,11 +396,11 @@ class WriteHead(Memory):
return mem, w
```
`ReadHead``WriteHead`都使用完全连接的层来生成用于内容编址的参数(`k``beta``g``s``gamma`)。
`ReadHead``WriteHead`都使用全连接层来生成用于内容编址的参数(`k``beta``g``s``gamma`)。
6. 实现神经图灵机结构,其中包括:
* 完全连接的控制器
* 全连接控制器
* 读写磁头
* 记忆体参数
* 在无法训练的内存上运行的实用程序功能
......@@ -710,7 +710,7 @@ class WriteHead(Memory):
return mem, w
```
`ReadHead``WriteHead`都使用完全连接的层来生成用于内容编址的参数(`k``beta``g``s``gamma`)。
`ReadHead``WriteHead`都使用全连接层来生成用于内容编址的参数(`k``beta``g``s``gamma`)。
请注意,此练习只是为了展示 MANN 如何受到 NTM 的启发。 如果您想在真实的数据集上探索前面的练习,请参考[上的 GitHub 存储库 https://github.com/PacktPublishing/Hands-On-One-shot-Learning-with-Python/tree / master / Chapter03](https://github.com/PacktPublishing/Hands-On-One-shot-Learning-with-Python/tree/master/Chapter03)
......
......@@ -164,11 +164,11 @@
![Figure 1.11 – Fully connected network ](img/B12365_01_11.jpg)
图 1.11 –完全连接的网络
图 1.11 –全连接网络
每个输入节点都连接到另一层中的每个节点。 这被称为**全连接层**。 然后,将来自的全连接层的输出乘以其自身的附加权重,以便预测`y`。 因此,我们的预测不再只是![](img/Formula_01_027.png)的函数,而是现在包括针对每个参数的多个学习权重。 功能![](img/Formula_01_028.png)不再仅受![](img/Formula_01_029.png)影响。 现在,它也受到![](img/Formula_01_030.png)的影响。 参数。
由于完全连接层中的每个节点都将`X`的所有值作为输入,因此神经网络能够学习输入特征之间的交互特征。 多个完全连接的层可以链接在一起,以学习更复杂的功能。 在本书中,我们将看到我们构建的所有神经网络都将使用该概念。 将不同品种的多层链接在一起,以构建更复杂的模型。 但是,在我们完全理解神经网络之前,还有另外一个关键要素要涵盖:激活函数。
由于全连接层中的每个节点都将`X`的所有值作为输入,因此神经网络能够学习输入特征之间的交互特征。 多个全连接层可以链接在一起,以学习更复杂的功能。 在本书中,我们将看到我们构建的所有神经网络都将使用该概念。 将不同品种的多层链接在一起,以构建更复杂的模型。 但是,在我们完全理解神经网络之前,还有另外一个关键要素要涵盖:激活函数。
## 激活功能
......@@ -178,7 +178,7 @@
图 1.12 –神经网络中的激活函数
我们将激活函数应用于完全连接层中的每个节点。 这意味着完全连接层中的每个节点都将特征和权重之和作为输入,对结果值应用非线性函数,并输出转换后的结果。 尽管激活功能有许多不同,但最近使用最频繁的是 **ReLU****整流线性单元**
我们将激活函数应用于全连接层中的每个节点。 这意味着全连接层中的每个节点都将特征和权重之和作为输入,对结果值应用非线性函数,并输出转换后的结果。 尽管激活功能有许多不同,但最近使用最频繁的是 **ReLU****整流线性单元**
![Figure 1.13 – Representation of ReLU output ](img/B12365_01_13.jpg)
......
......@@ -214,9 +214,9 @@ self.fc3 = nn.Linear(196,98)
self.fc4 = nn.Linear(98,10)
我们像从 Python PyTorch 中继承 **nn.Module** 一样,在 Python 中构建普通类,从而构建分类器。 在我们的**初始**方法中,我们定义了神经网络的每一层。 在这里,我们定义了大小可变的完全连接的线性层。
我们像从 Python PyTorch 中继承 **nn.Module** 一样,在 Python 中构建普通类,从而构建分类器。 在我们的**初始**方法中,我们定义了神经网络的每一层。 在这里,我们定义了大小可变的全连接线性层。
我们的第一层接受`784`输入,因为这是我们要分类的每个图像的大小(28x28)。 然后,我们看到一层的输出必须与下一层的输入具有相同的值,这意味着我们的第一个完全连接的层输出`392`个单位,而我们的第二层则采用`392`单位作为输入。 对每一层都重复一次,每次它们具有一半的单位数量,直到我们到达最终的完全连接层为止,该层输出`10`个单位。 这是我们分类层的长度。
我们的第一层接受`784`输入,因为这是我们要分类的每个图像的大小(28x28)。 然后,我们看到一层的输出必须与下一层的输入具有相同的值,这意味着我们的第一个全连接层输出`392`个单位,而我们的第二层则采用`392`单位作为输入。 对每一层都重复一次,每次它们具有一半的单位数量,直到我们到达最终的全连接层为止,该层输出`10`个单位。 这是我们分类层的长度。
我们的网络现在看起来像这样:
......@@ -250,7 +250,7 @@ x = self.dropout(F.relu(self.fc3(x)))
x = F.log_softmax(self.fc4(x),dim = 1)
分类器中的 **forward()**方法是我们在其中应用激活函数并定义在我们的网络中应用 dropout 的位置的方法。 我们的**正向**方法定义了输入将通过网络的路径。 首先,它获取我们的输入 **x,**,并将其整形以在网络中使用,并将其转换为一维矢量。 然后,我们将其通过我们的第一个完全连接的层,并将其包装在 **ReLU** 激活函数中,以使其为非线性。 我们也将其包装在我们的[drop]中,如 **init** 方法中所定义。 我们对网络中的所有其他层重复此过程。
分类器中的 **forward()**方法是我们在其中应用激活函数并定义在我们的网络中应用 dropout 的位置的方法。 我们的**正向**方法定义了输入将通过网络的路径。 首先,它获取我们的输入 **x,**,并将其整形以在网络中使用,并将其转换为一维矢量。 然后,我们将其通过我们的第一个全连接层,并将其包装在 **ReLU** 激活函数中,以使其为非线性。 我们也将其包装在我们的[drop]中,如 **init** 方法中所定义。 我们对网络中的所有其他层重复此过程。
对于我们的最终预测层,我们将其包装在对数 **softmax** 层中。 我们将使用它来轻松计算我们的损失函数,如下所示。
......
......@@ -156,7 +156,7 @@ projection_king_embedding =手套['女王']-手套['女人'] +手套['男人']
输入的单词首先通过嵌入层,表示为大小(n,l)的张量,其中 n 是嵌入的指定长度,l 是语料库中单词的数量。 这是因为语料库中的每个单词都有其自己独特的张量表示形式。
然后使用来自四个上下文词的组合(求和)嵌入,将其馈入一个完全连接的层中,以学习针对目标词与上下文词的嵌入表示形式进行最终分类。 请注意,我们的预测词/目标词被编码为向量,即我们的语料库的长度。 这是因为我们的模型可以有效地预测语料库中每个单词成为目标单词的概率,而最终分类是概率最高的一个。 然后,我们得到一个损失,通过我们的网络反向传播,并更新完全连接层上的参数以及嵌入本身。
然后使用来自四个上下文词的组合(求和)嵌入,将其馈入一个全连接层中,以学习针对目标词与上下文词的嵌入表示形式进行最终分类。 请注意,我们的预测词/目标词被编码为向量,即我们的语料库的长度。 这是因为我们的模型可以有效地预测语料库中每个单词成为目标单词的概率,而最终分类是概率最高的一个。 然后,我们得到一个损失,通过我们的网络反向传播,并更新全连接层上的参数以及嵌入本身。
该方法之所以有效,是因为我们学习到的嵌入表示语义相似性。 假设我们在以下方面训练模型:
......@@ -216,7 +216,7 @@ projection_king_embedding =手套['女王']-手套['女人'] +手套['男人']
embedding_length = 20
接下来,我们在 PyTorch 中定义 **CBOW** 模型。 我们定义嵌入层,以便它接受语料库长度的向量,并输出单个嵌入。 我们将线性层定义为一个完全连接的层,该层将嵌入并输出`64`的向量。 我们将最后一层定义为与文本语料库相同长度的分类层。
接下来,我们在 PyTorch 中定义 **CBOW** 模型。 我们定义嵌入层,以便它接受语料库长度的向量,并输出单个嵌入。 我们将线性层定义为一个全连接层,该层将嵌入并输出`64`的向量。 我们将最后一层定义为与文本语料库相同长度的分类层。
6. We define our forward pass by obtaining and summing the embeddings for all input context words. This then passes through the fully connected layer with ReLU activation functions and finally into the classification layer, which predicts which word in the corpus corresponds to the summed embeddings of the context words the most:
......
......@@ -17,7 +17,7 @@
# 构建 RNN
RNN 由循环层组成。 尽管它们在许多方面类似于标准前馈神经网络中的完全连接层,但这些递归层由隐藏状态组成,该隐藏状态在顺序输入的每个步骤中进行更新。 这意味着对于任何给定的序列,模型都使用隐藏状态初始化,该状态通常表示为一维向量。 然后,将序列的第一步输入模型,并根据一些学习到的参数更新隐藏状态。 然后将第二个单词馈入网络,并根据其他一些学习到的参数再次更新隐藏状态。 重复这些步骤,直到处理完整个序列,并且使我们处于最终的隐藏状态。 该计算*循环*具有从先前的计算中继承并更新的隐藏状态,这就是为什么我们将这些网络称为循环的原因。 然后,将这个最终的隐藏状态连接到另一个完全连接的层,并预测最终的分类。
RNN 由循环层组成。 尽管它们在许多方面类似于标准前馈神经网络中的全连接层,但这些递归层由隐藏状态组成,该隐藏状态在顺序输入的每个步骤中进行更新。 这意味着对于任何给定的序列,模型都使用隐藏状态初始化,该状态通常表示为一维向量。 然后,将序列的第一步输入模型,并根据一些学习到的参数更新隐藏状态。 然后将第二个单词馈入网络,并根据其他一些学习到的参数再次更新隐藏状态。 重复这些步骤,直到处理完整个序列,并且使我们处于最终的隐藏状态。 该计算*循环*具有从先前的计算中继承并更新的隐藏状态,这就是为什么我们将这些网络称为循环的原因。 然后,将这个最终的隐藏状态连接到另一个全连接层,并预测最终的分类。
我们的循环层如下所示,其中`h`是隐藏状态,而`x`是我们在序列中各个时间步的输入。 对于每次迭代,我们都会在每个时间步`x`中更新隐藏状态:
......@@ -43,7 +43,7 @@ RNN 由循环层组成。 尽管它们在许多方面类似于标准前馈神经
## 使用 RNN 进行情感分析
在情绪分析的上下文中,我们的模型是根据评论的情绪分析数据集训练的,该数据集由多个文本评论和 0 或 1 的标签组成,具体取决于评论是负面还是正面 。 这意味着我们的模型成为分类任务(两个类别为负/正)。 我们的句子经过一层学习的单词嵌入,以形成包含多个向量的句子的表示(每个单词一个)。 然后将这些向量顺序地馈入我们的 RNN 层,最终的隐藏状态将通过另一个完全连接的层。 我们的模型输出是介于 0 到 1 之间的单个值,具体取决于我们的模型是根据句子预测的是消极情绪还是正面情绪。 这意味着我们完整的分类模型如下所示:
在情绪分析的上下文中,我们的模型是根据评论的情绪分析数据集训练的,该数据集由多个文本评论和 0 或 1 的标签组成,具体取决于评论是负面还是正面 。 这意味着我们的模型成为分类任务(两个类别为负/正)。 我们的句子经过一层学习的单词嵌入,以形成包含多个向量的句子的表示(每个单词一个)。 然后将这些向量顺序地馈入我们的 RNN 层,最终的隐藏状态将通过另一个全连接层。 我们的模型输出是介于 0 到 1 之间的单个值,具体取决于我们的模型是根据句子预测的是消极情绪还是正面情绪。 这意味着我们完整的分类模型如下所示:
![Figure 5.3 – Classification model ](img/B12365_05_3.jpg)
......@@ -107,13 +107,13 @@ LSTM 与 RNN 的结构非常相似。 虽然 LSTM 的各个步骤之间存在一
图 5.6 – LSTM 电池的内部工作原理
尽管这看起来比 RNN 更加令人生畏,但我们将依次解释 LSTM 单元的每个组件。 我们首先来看**忘记门**(由粗体矩形指示):
尽管这看起来比 RNN 更加令人生畏,但我们将依次解释 LSTM 单元的每个组件。 我们首先来看**遗忘门**(由粗体矩形指示):
![Figure 5.7 – The forget gate ](img/B12365_05_7.jpg)
图 5.7 –忘记
图 5.7 –遗忘
忘记门本质上是学习要忘记序列中的哪些元素。 先前的隐藏状态`h`t-1 和最新的输入步骤`x`1 被串联在一起,并通过了在忘记门和 S 形函数上获得的权重矩阵 将值压缩为 0 到 1 之间的值。将得到的矩阵 *ft* 逐点乘以上一步`c`t-1 的单元状态。 这有效地将掩码应用于先前的小区状态,使得仅来自先前的小区状态的相关信息被提出。
遗忘门本质上是学习要忘记序列中的哪些元素。 先前的隐藏状态`h`t-1 和最新的输入步骤`x`1 被串联在一起,并通过了在遗忘门和 S 形函数上获得的权重矩阵 将值压缩为 0 到 1 之间的值。将得到的矩阵 *ft* 逐点乘以上一步`c`t-1 的单元状态。 这有效地将掩码应用于先前的小区状态,使得仅来自先前的小区状态的相关信息被提出。
接下来,我们将查看**输入门**
......@@ -129,11 +129,11 @@ LSTM 与 RNN 的结构非常相似。 虽然 LSTM 的各个步骤之间存在一
图 5.9 –输出门
输出门计算 LSTM 单元的最终输出-单元状态和隐藏状态,并继续进行下一步。 单元状态`c`t 与前两个步骤相同,是忘记门和输入门的乘积。 通过获取串联的先前隐藏状态`h`t-1 和当前时间步输入`x`t,可以计算出最终隐藏状态`h`t ,并通过具有一些学习参数的 S 型函数来获得输出门输出`o`t。 最终单元状态`c`t 通过 tanh 函数并乘以输出门输出`o`t,以计算最终隐藏状态`h`t。 这意味着在输出门上学习到的参数可以有效地控制将先前隐藏状态和当前输出中的哪些元素与最终单元状态进行组合,以作为新的隐藏状态延续到下一个时间步长。
输出门计算 LSTM 单元的最终输出-单元状态和隐藏状态,并继续进行下一步。 单元状态`c`t 与前两个步骤相同,是遗忘门和输入门的乘积。 通过获取串联的先前隐藏状态`h`t-1 和当前时间步输入`x`t,可以计算出最终隐藏状态`h`t ,并通过具有一些学习参数的 S 型函数来获得输出门输出`o`t。 最终单元状态`c`t 通过 tanh 函数并乘以输出门输出`o`t,以计算最终隐藏状态`h`t。 这意味着在输出门上学习到的参数可以有效地控制将先前隐藏状态和当前输出中的哪些元素与最终单元状态进行组合,以作为新的隐藏状态延续到下一个时间步长。
在我们的前向遍历中,我们简单地遍历模型,初始化我们的隐藏状态和单元状态,并在每个时间步使用 LSTM 单元对其进行更新,直到剩下最终的隐藏状态为止,该状态将输出到神经元的下一层 网络。 通过在 LSTM 的所有层中进行反向传播,我们可以计算相对于网络损耗的梯度,因此我们知道通过梯度下降来更新参数的方向。 我们得到几种矩阵或参数-一种用于输入门,一种用于输出门,以及一种用于忘记门。
在我们的前向遍历中,我们简单地遍历模型,初始化我们的隐藏状态和单元状态,并在每个时间步使用 LSTM 单元对其进行更新,直到剩下最终的隐藏状态为止,该状态将输出到神经元的下一层 网络。 通过在 LSTM 的所有层中进行反向传播,我们可以计算相对于网络损耗的梯度,因此我们知道通过梯度下降来更新参数的方向。 我们得到几种矩阵或参数-一种用于输入门,一种用于输出门,以及一种用于遗忘门。
因为我们获得的参数要比简单的 RNN 多,并且我们的计算图更加复杂,所以与简单的 RNN 相比,通过网络反向传播和更新权重的过程可能会花费更长的时间。 但是,尽管训练时间更长,但是我们已经证明,与传统的 RNN 相比,LSTM 具有显着的优势,因为输出门,输入门和忘记门都结合在一起,使模型能够确定应使用输入的哪些元素。 更新隐藏状态,并且以后应该忘记隐藏状态的哪些元素,这意味着该模型能够更好地形成长期依存关系并保留先前序列步骤中的信息。
因为我们获得的参数要比简单的 RNN 多,并且我们的计算图更加复杂,所以与简单的 RNN 相比,通过网络反向传播和更新权重的过程可能会花费更长的时间。 但是,尽管训练时间更长,但是我们已经证明,与传统的 RNN 相比,LSTM 具有显着的优势,因为输出门,输入门和遗忘门都结合在一起,使模型能够确定应使用输入的哪些元素。 更新隐藏状态,并且以后应该忘记隐藏状态的哪些元素,这意味着该模型能够更好地形成长期依存关系并保留先前序列步骤中的信息。
## 双向 LSTM
......@@ -313,7 +313,7 @@ self.n_layers = n_layers
self.n_hidden = n_hidden
然后,我们定义网络的每个层。 首先,我们定义嵌入层,该层的词汇量为字长,嵌入向量的大小为 **n_embed** 超参数。 我们的 LSTM 层是使用嵌入层的输出矢量大小,模型的隐藏状态的长度以及 LSTM 层将具有的层数来定义的。 我们还添加了一个参数来指定可以对 LSTM 进行批量数据训练,并添加一个参数以允许我们通过辍学实现网络正则化。 我们用概率 **drop_p** (将在模型创建时指定的超参数)定义另外一个辍学层,以及对最终全连接层和输出/预测节点的定义(具有 S 型激活函数) :
然后,我们定义网络的每个层。 首先,我们定义嵌入层,该层的词汇量为字长,嵌入向量的大小为 **n_embed** 超参数。 我们的 LSTM 层是使用嵌入层的输出矢量大小,模型的隐藏状态的长度以及 LSTM 层将具有的层数来定义的。 我们还添加了一个参数来指定可以对 LSTM 进行批量数据训练,并添加一个参数以允许我们通过辍学实现网络正则化。 我们用概率 **drop_p** (将在模型创建时指定的超参数)定义另外一个辍学层,以及对最终全连接层和输出/预测节点的定义(具有 S 型激活函数) :
self.embedding = nn.Embedding(n_vocab,n_embed)
......
......@@ -287,7 +287,7 @@ batch_size = 64,
kernel_size =(3,embedding_dim))
在此,滤波器尺寸分别为`2``3`。 但是,在单个功能中执行此操作效率更高。 此外,如果我们向函数传递不同的过滤器大小,则将自动生成我们的图层,而不是每次添加新图层时都必须手动定义每个图层。
在此,滤波器尺寸分别为`2``3`。 但是,在单个功能中执行此操作效率更高。 此外,如果我们向函数传递不同的过滤器大小,则将自动生成我们的层,而不是每次添加新层时都必须手动定义每个层。
我们还将 **out_channels** 值定义为我们希望训练的过滤器数; **kernel_size** 将包含我们嵌入的长度。 因此,我们可以将 **ModuleList** 函数的长度传递给我们希望训练的滤波器长度以及每个滤波器的数量,它将自动生成卷积层。 该卷积层如何查找给定变量集的示例如下:
......@@ -321,7 +321,7 @@ concat = self.dropout(torch.cat(池,暗= 1))
在这里,我们首先将输入文本传递到嵌入层,以获取句子中所有单词的嵌入。 接下来,对于我们将嵌入语句传递到的每个先前定义的卷积层,我们应用 **relu** 激活函数并压缩结果,删除结果输出的第四维。 对所有定义的卷积层重复此操作,以便使**转化为**包含在所有卷积层的输出列表中。
对于这些输出中的每一个,我们都应用了合并函数来减小卷积层输出的维数,如前所述。 然后,我们将池化层的所有输出连接在一起,并在将其传递到最终的全连接层之前应用一个 dropout 函数,这将对我们的类进行预测。 完全定义 CNN 类之后,我们创建模型的实例。 我们定义我们的超参数,并使用它们创建 CNN 类的实例:
对于这些输出中的每一个,我们都应用了合并函数来减小卷积层输出的维数,如前所述。 然后,我们将池化层的所有输出连接在一起,并在将其传递到最终的全连接层之前应用一个 dropout 函数,这将对我们的类进行预测。 完全定义 CNN 类之后,我们创建模型的实例。 我们定义我们的超参数,并使用它们创建 CNN 类的实例:
input_dimensions = len(questions.vocab)
......
......@@ -275,7 +275,7 @@
## 构建解码器
我们的解码器将从我们的编码器的 LSTM 层中获取最终的隐藏状态,并将其转换为另一种语言的输出语句。 我们首先以与编码器几乎完全相同的方式初始化解码器。 唯一的区别是我们还添加了一个完全连接的线性层。 该层将使用来自 LSTM 的最终隐藏状态,以便对句子中的正确单词进行预测:
我们的解码器将从我们的编码器的 LSTM 层中获取最终的隐藏状态,并将其转换为另一种语言的输出语句。 我们首先以与编码器几乎完全相同的方式初始化解码器。 唯一的区别是我们还添加了一个全连接线性层。 该层将使用来自 LSTM 的最终隐藏状态,以便对句子中的正确单词进行预测:
类 Decoder(nn.Module):
......@@ -297,7 +297,7 @@ self.fc_out = nn.Linear(hid_dims,output_dims)
self.dropout = nn.Dropout(辍学)
除了增加了两个关键步骤外,我们的前向通过与编码器非常相似。 首先,从上一层取消输入,以使其为进入嵌入层的正确大小。 我们还添加了一个完全连接的层,该层采用了 RNN 层的输出隐藏层,并使用它来预测序列中的下一个单词:
除了增加了两个关键步骤外,我们的前向通过与编码器非常相似。 首先,从上一层取消输入,以使其为进入嵌入层的正确大小。 我们还添加了一个全连接层,该层采用了 RNN 层的输出隐藏层,并使用它来预测序列中的下一个单词:
def forward(自我,输入,h,单元格):
......
......@@ -14,7 +14,7 @@
[第 1 章](../Text/1.html)*使用 PyTorch 处理张量*介绍 PyTorch 及其安装,然后继续使用 PyTorch 处理张量。
[第 2 章](../Text/2.html)*处理神经网络*全面介绍了开始和训练完全连接的神经网络的所有要求,从而对基本神经网络的所有组件进行了详尽的解释。 :层,前馈网络,反向传播,损失函数,梯度,权重更新以及使用 CPU / GPU。
[第 2 章](../Text/2.html)*处理神经网络*全面介绍了开始和训练全连接神经网络的所有要求,从而对基本神经网络的所有组件进行了详尽的解释。 :层,前馈网络,反向传播,损失函数,梯度,权重更新以及使用 CPU / GPU。
[第 3 章](../Text/3.html)*用于计算机视觉的卷积神经网络*首先介绍了用于更高级任务的一类神经网络,即卷积神经网络。 在这里,我们将与 PyTorch 一起探索 TorchVision,训练 CNN 模型,并使用 TensorBoard 可视化其进度。 我们还将介绍与卷积网络构建块相关的各种任务。 卷积神经网络(CNN 或 ConvNet)是一类 DNN,最常用于分析图像。
......
......@@ -17,7 +17,7 @@
在本章中,以下食谱将使我们开始使用神经网络:
* 定义神经网络类
* 创建一个完全连接的网络
* 创建一个全连接网络
* 定义损失函数
* 实施优化器
* 实施辍学
......@@ -25,7 +25,7 @@
# 技术要求
在本章中,我们将开始处理图像数据并学习完全连接的神经网络如何工作。 PyTorch 有一个名为 TorchVision 的补充库,我们将在开始食谱之前进行安装。
在本章中,我们将开始处理图像数据并学习全连接神经网络如何工作。 PyTorch 有一个名为 TorchVision 的补充库,我们将在开始食谱之前进行安装。
您可以对`torchvision`使用以下`pip`安装命令:
......@@ -37,7 +37,7 @@ pip install torchvision
# 定义神经网络类
在本食谱中,我们将从了解 TorchVision 的一些重要功能开始,这些功能使它能够处理图像数据并进行处理。 然后,我们将通过定义一个类来定义神经网络的基本架构,并查看可用于此的模块和方法。 在本食谱中,我们将专注于完全连接的神经网络类。 它的属性是各个层,其目的是对各种类型的衣服进行分类。
在本食谱中,我们将从了解 TorchVision 的一些重要功能开始,这些功能使它能够处理图像数据并进行处理。 然后,我们将通过定义一个类来定义神经网络的基本架构,并查看可用于此的模块和方法。 在本食谱中,我们将专注于全连接神经网络类。 它的属性是各个层,其目的是对各种类型的衣服进行分类。
我们将使用 Fashion–MNIST 数据集。 这是 Zalando 文章图片的数据集,包括 6 万个示例的训练集和 10,000 个示例的测试集。 我们将拍摄一张尺寸为 28 x 28 的灰度图像,并将其转换为 784 的矢量。
......@@ -142,7 +142,7 @@ TorchVision 的`datasets`模块附带了许多受欢迎的数据集; 如果机
我们可以用任何名称定义模型类,但是重要的是它是`nn.Module`的子类并具有`super().__init__()`,该类为模型提供了许多有用的方法和属性,并保留了体系结构的知识。
我们使用`nn.Linear()`通过输入和输出尺寸来定义完全连接的层。 我们将 softmax 层用于最后一层输出,因为有 10 个输出类。 我们在输出层之前的层中使用 ReLU 激活来学习数据中的非线性。 `hidden1`层采用 784 个输入单元,并给出 256 个输出单元。 `hidden2`短语输出 128 个单位,输出层有 10 个输出单位,代表 10 个输出类别。 softmax 层将激活转换为概率,以便沿维度 1 加 1。
我们使用`nn.Linear()`通过输入和输出尺寸来定义全连接层。 我们将 softmax 层用于最后一层输出,因为有 10 个输出类。 我们在输出层之前的层中使用 ReLU 激活来学习数据中的非线性。 `hidden1`层采用 784 个输入单元,并给出 256 个输出单元。 `hidden2`短语输出 128 个单位,输出层有 10 个输出单位,代表 10 个输出类别。 softmax 层将激活转换为概率,以便沿维度 1 加 1。
# 还有更多...
......@@ -152,7 +152,7 @@ TorchVision 的`datasets`模块附带了许多受欢迎的数据集; 如果机
您可以在[这个页面](https://pytorch.org/docs/stable/torchvision/transforms.html)上查看有关转换的更多详细信息,还可以在[这个页面](https://pytorch.org/tutorials/beginner/blitz/neural_networks_tutorial.html#sphx-glr-beginner-blitz-neural-networks-tutorial-py)上了解有关定义模型类的更多信息。
# 创建一个完全连接的网络
# 创建一个全连接网络
在本食谱中,我们将扩展在先前食谱中定义的类*定义神经网络类*。 在*定义神经网络类*配方中,我们仅创建了所需架构的组件; 现在我们将把所有这些部分捆绑在一起,以建立一个明智的网络。 我们各层的进度将从 784 个单位增加到 256 个,然后是 128 个,最后是 10 个单位的输出层。
......
......@@ -4,9 +4,9 @@
CNN 是一种特殊的网络,可以将图像作为张量接收。 彩色图像由红色,绿色和蓝色三个颜色通道组成,称为 RGB。 我们将这些二维矩阵通道堆叠起来以形成彩色图像; 每个通道的值变化会产生不同的颜色。 CNN 将图像作为三个独立的堆叠颜色层,一个层放在另一个层上。
图像从附近的一个设置像素中获得其含义,但是单个像素不能保存有关整个图像的太多信息。 在也称为密集层的完全连接的神经网络中,一层中的每个节点都连接到下一层中的每个其他节点。 CNN 利用像素之间的空间结构来减少两层之间的连接数,从而显着提高训练速度,同时减少模型参数。
图像从附近的一个设置像素中获得其含义,但是单个像素不能保存有关整个图像的太多信息。 在也称为密集层的全连接神经网络中,一层中的每个节点都连接到下一层中的每个其他节点。 CNN 利用像素之间的空间结构来减少两层之间的连接数,从而显着提高训练速度,同时减少模型参数。
这是显示完全连接的网络的图像:
这是显示全连接网络的图像:
![](img/06998e32-12e3-44d9-9100-99d43f341b71.png)
......@@ -603,7 +603,7 @@ pip install torchvision==0.x.x
# 定义 CNN 架构
到目前为止,在本章中,我们一直在研究 CNN 的不同组成部分,以及如何将数据集中的数据加载到可以馈入 CNN 模型的格式中。 在本食谱中,我们将通过到目前为止已经看到的完成模型的组件来定义 CNN 模型架构。 这与我们在[第 2 章](../Text/2.html)*处理神经网络*中介绍的全连接神经网络非常相似。 为了更好地理解此配方,从[第 2 章](../Text/2.html)*处理神经网络*修改完全连接的神经网络的模型定义将是一个好主意。 我们将在 CIFAR10 数据集上建立图像分类模型,我们在*加载图像数据*配方中对此进行了讨论。
到目前为止,在本章中,我们一直在研究 CNN 的不同组成部分,以及如何将数据集中的数据加载到可以馈入 CNN 模型的格式中。 在本食谱中,我们将通过到目前为止已经看到的完成模型的组件来定义 CNN 模型架构。 这与我们在[第 2 章](../Text/2.html)*处理神经网络*中介绍的全连接神经网络非常相似。 为了更好地理解此配方,从[第 2 章](../Text/2.html)*处理神经网络*修改全连接神经网络的模型定义将是一个好主意。 我们将在 CIFAR10 数据集上建立图像分类模型,我们在*加载图像数据*配方中对此进行了讨论。
# 怎么做...
......@@ -676,11 +676,11 @@ CNN(
# 这个怎么运作...
此食谱的工作方式与[第 2 章](../Text/2.html)*处理神经网络*时非常相似,当我们研究一个完全连接的神经网络时。 我们从`__init__()`方法和父类的构造函数开始,定义了从 PyTorch 中的`nn.Module`继承的 CNN 类。 之后,我们通过传入与每一层相关的参数来定义 CNN 中的各个层。 对于我们的第一卷积层,输入通道的数量为 3(RGB),输出通道的数量定义为 16,其平方核大小为 3。第二卷积层采用上一层的张量,并具有 16 个输入通道和 32 个输出通道,内核尺寸为 3 x3。类似地,第三卷积层具有 32 个输入通道和 64 个输出通道,内核尺寸为 3 x 3。 我们还需要一个最大池化层,并使用 2 的内核大小和 2 的步幅。我们使用`.view()`将张量的三个维度展平为一个维度,以便可以将其传递到完全连接的网络中。 `view`函数中的-1 通过确保`view`函数之前和之后的元素数量保持相同(在本例中为批量大小)来确保将正确的尺寸自动分配给该尺寸。
此食谱的工作方式与[第 2 章](../Text/2.html)*处理神经网络*时非常相似,当我们研究一个全连接神经网络时。 我们从`__init__()`方法和父类的构造函数开始,定义了从 PyTorch 中的`nn.Module`继承的 CNN 类。 之后,我们通过传入与每一层相关的参数来定义 CNN 中的各个层。 对于我们的第一卷积层,输入通道的数量为 3(RGB),输出通道的数量定义为 16,其平方核大小为 3。第二卷积层采用上一层的张量,并具有 16 个输入通道和 32 个输出通道,内核尺寸为 3 x3。类似地,第三卷积层具有 32 个输入通道和 64 个输出通道,内核尺寸为 3 x 3。 我们还需要一个最大池化层,并使用 2 的内核大小和 2 的步幅。我们使用`.view()`将张量的三个维度展平为一个维度,以便可以将其传递到全连接网络中。 `view`函数中的-1 通过确保`view`函数之前和之后的元素数量保持相同(在本例中为批量大小)来确保将正确的尺寸自动分配给该尺寸。
对于第一个完全连接的层,我们有 1,024 个输入(通过将最大池后的`64 x 4 x 4`张量展平而获得)和 512 个输出。 对于最后一个完全连接的层,我们有 512 个输入和 10 个输出,代表输出类别的数量。 我们还为完全连接的层定义了一个辍学层,概率为 0.3。
对于第一个全连接层,我们有 1,024 个输入(通过将最大池后的`64 x 4 x 4`张量展平而获得)和 512 个输出。 对于最后一个全连接层,我们有 512 个输入和 10 个输出,代表输出类别的数量。 我们还为全连接层定义了一个辍学层,概率为 0.3。
接下来,我们定义`forward()`方法,将`__init__()`方法中定义的组件连接在一起。 因此,输入批处理的 16 个张量(每个张量为 32 x 32 x 3)经过第一个卷积层,然后经过 ReLU,然后是最大合并层,以形成尺寸为 16 x 16 的输出张量。 x 16,然后通过第二个卷积层,然后是 ReLU 和最大池层,输出的尺寸为 8 x 8 x 32,然后是第三个卷积层,然后是 ReLU 和最大池 层,尺寸为 4 x 4 x64。此后,我们将图像展平为 1,024 个元素的向量,并将其通过辍学层传递到第一个完全连接的层,提供 512 个输出,然后是 ReLU 和 在最后一个完全连接的层中删除,以提供所需的输出数量,本例中为 10。
接下来,我们定义`forward()`方法,将`__init__()`方法中定义的组件连接在一起。 因此,输入批处理的 16 个张量(每个张量为 32 x 32 x 3)经过第一个卷积层,然后经过 ReLU,然后是最大合并层,以形成尺寸为 16 x 16 的输出张量。 x 16,然后通过第二个卷积层,然后是 ReLU 和最大池层,输出的尺寸为 8 x 8 x 32,然后是第三个卷积层,然后是 ReLU 和最大池 层,尺寸为 4 x 4 x64。此后,我们将图像展平为 1,024 个元素的向量,并将其通过辍学层传递到第一个全连接层,提供 512 个输出,然后是 ReLU 和 在最后一个全连接层中删除,以提供所需的输出数量,本例中为 10。
然后,我们从 CNN 类实例化该模型并打印该模型。
......@@ -694,7 +694,7 @@ CNN(
# 训练图像分类器
现在我们已经定义了模型,接下来的主要步骤是使用手头的数据训练该模型。 这将与我们在[第 2 章](../Text/2.html)*处理神经网络*和我们完全连接的神经网络中进行的训练非常相似。 在本食谱中,我们将完成训练图像分类器的工作。 如果您在完成本食谱之前,先阅读了[第 2 章](../Text/2.html)*与神经网络**实现优化器*食谱,那将非常有用。
现在我们已经定义了模型,接下来的主要步骤是使用手头的数据训练该模型。 这将与我们在[第 2 章](../Text/2.html)*处理神经网络*和我们全连接神经网络中进行的训练非常相似。 在本食谱中,我们将完成训练图像分类器的工作。 如果您在完成本食谱之前,先阅读了[第 2 章](../Text/2.html)*与神经网络**实现优化器*食谱,那将非常有用。
# 怎么做...
......
......@@ -31,7 +31,7 @@
在上图中,我们可以看到 RNN 的展开图,其中一个步骤的信息被馈送到下一个步骤,从而创建同一网络的多个副本,所有这些信息都封装在循环循环中。 循环神经网络接受输入并给出输出,但是该输出不仅取决于给定实例上的输入,还取决于提供给网络的输入的整个历史,网络会在数学上记住这些输入。
循环神经网络能够接收可变大小的输入序列并产生可变大小的输出序列,从而执行与完全连接的神经网络中固定数量的计算相反的可变数量的计算。 进一步的 RNN 允许信息持久化,并在接收到的输入之间共享该信息。 在给定实例上生成的输出基于到目前为止所看到的所有输入的历史记录。
循环神经网络能够接收可变大小的输入序列并产生可变大小的输出序列,从而执行与全连接神经网络中固定数量的计算相反的可变数量的计算。 进一步的 RNN 允许信息持久化,并在接收到的输入之间共享该信息。 在给定实例上生成的输出基于到目前为止所看到的所有输入的历史记录。
这是 LSTM 的示意图:
......@@ -403,7 +403,7 @@ TorchText 具有用于处理嵌入的`vocab`模块。 我们可以通过在此
self.rnn = nn.LSTM(embedding_dim, hidden_dim)
```
5. 然后,我们添加一个完全连接的层:
5. 然后,我们添加一个全连接层:
```py
self.fc = nn.Linear(hidden_dim, output_dim)
......@@ -466,9 +466,9 @@ return self.fc(hidden)
我们使用`torch.nn`模块创建了从`torch.nn.Module`继承的模型类`LSTMClassifier`,并初始化了基类构造函数。 然后,我们定义嵌入层,其中输入维与词汇量大小相同,输出为嵌入维,然后将嵌入层输出传递到 LSTM 层,其中输入维为嵌入维,然后 定义隐藏状态维度。
然后,我们定义了完全连接的层和丢弃层。 接下来,我们定义`forward()`方法,该方法接受输入序列,并将其传递给嵌入层,从而产生尺寸为`embedding_dim`的输出,该输出是输入序列的嵌入向量。 然后将这个字向量传递到 LSTM 层,该层输出三个状态-输出状态,隐藏状态和单元状态。
然后,我们定义了全连接层和丢弃层。 接下来,我们定义`forward()`方法,该方法接受输入序列,并将其传递给嵌入层,从而产生尺寸为`embedding_dim`的输出,该输出是输入序列的嵌入向量。 然后将这个字向量传递到 LSTM 层,该层输出三个状态-输出状态,隐藏状态和单元状态。
隐藏状态张量保存了到目前为止 LSTM 所见过的所有序列的信息,因此我们采用了隐藏状态,应用了`dropout`,并将其通过全连接层传递给最终输出向量,其大小等于 类数。 例如,对于有毒评论数据集,输出类别的数量为六; 但是,对于具有两个状态(正向和负向)的情感分析器,我们甚至可以考虑只具有一个输出,以便`1`代表积极情感,`0`代表消极情感。
隐藏状态张量保存了到目前为止 LSTM 所见过的所有序列的信息,因此我们采用了隐藏状态,应用了`dropout`,并将其通过全连接层传递给最终输出向量,其大小等于 类数。 例如,对于有毒评论数据集,输出类别的数量为六; 但是,对于具有两个状态(正向和负向)的情感分析器,我们甚至可以考虑只具有一个输出,以便`1`代表积极情感,`0`代表消极情感。
# 还有更多...
......@@ -563,13 +563,13 @@ class MultiLSTMClassifier(nn.Module):
self.rnn = nn.LSTM(embedding_dim, hidden_dim, num_layers=num_layers, bidirectional=True)
```
2. 然后,我们将更改全连接层的输入尺寸:
2. 然后,我们将更改全连接层的输入尺寸:
```py
self.fc = nn.Linear(2*hidden_dim, output_dim)
```
3. 然后,将输入更新为完全连接的层,如下所示:
3. 然后,将输入更新为全连接层,如下所示:
```py
hidden = self.dropout(torch.cat((hidden[-2,:,:], hidden[-1,:,:]), dim=1))
......@@ -603,9 +603,9 @@ class BiLSTMClassifier(nn.Module):
# 这个怎么运作...
在此配方中,我们在 LSTM 定义中将`bidirectional`标志设置为`True`。 我们将前向和后向 LSTM 的隐藏状态串联起来,并将它们传递到完全连接的层中。 因此,全连接层的输入尺寸增加了一倍,以适应前向和后向隐藏状态张量。
在此配方中,我们在 LSTM 定义中将`bidirectional`标志设置为`True`。 我们将前向和后向 LSTM 的隐藏状态串联起来,并将它们传递到全连接层中。 因此,全连接层的输入尺寸增加了一倍,以适应前向和后向隐藏状态张量。
`forward()`方法中,我们使用`torch.cat()`连接了向前和向后隐藏状态,并使用了向前和向后 LSTM 的最后一个隐藏状态。 在 PyTorch 中,隐藏状态堆叠为`[forward_layer_0, backward_layer_0, forward_layer_1, backward_layer_1, ..., forward_layer_n, backward_layer_n]`,因此所需的张量为`hidden[-2,:,:], hidden[-1,:,:]`。 串联后,在挤出额外的尺寸后,我们将隐藏的矢量传递到完全连接的层中。
`forward()`方法中,我们使用`torch.cat()`连接了向前和向后隐藏状态,并使用了向前和向后 LSTM 的最后一个隐藏状态。 在 PyTorch 中,隐藏状态堆叠为`[forward_layer_0, backward_layer_0, forward_layer_1, backward_layer_1, ..., forward_layer_n, backward_layer_n]`,因此所需的张量为`hidden[-2,:,:], hidden[-1,:,:]`。 串联后,在挤出额外的尺寸后,我们将隐藏的矢量传递到全连接层中。
# 还有更多...
......
......@@ -27,7 +27,7 @@
# 调整预训练模型
在本食谱中,我们将采用经过预训练的 ResNet 模型,并修改最后一层以适合我们所需的输出。 与 ImageNet 数据集中用于训练 ResNet-50 模型的类的数量相比,我们只需要两个类。 我们将修改 ResNet 模型的最后一个池化层和完全连接的分类器。 我们将进一步将模型的训练限制为仅添加新添加的分类器单元,并且将保留所有其余层以免更新权重。 这称为冻结模型。 让我们看一下如何实现配方。
在本食谱中,我们将采用经过预训练的 ResNet 模型,并修改最后一层以适合我们所需的输出。 与 ImageNet 数据集中用于训练 ResNet-50 模型的类的数量相比,我们只需要两个类。 我们将修改 ResNet 模型的最后一个池化层和全连接分类器。 我们将进一步将模型的训练限制为仅添加新添加的分类器单元,并且将保留所有其余层以免更新权重。 这称为冻结模型。 让我们看一下如何实现配方。
# 做好准备
......@@ -100,9 +100,9 @@ return model
# 这个怎么运作...
在此配方中,我们定义了一个子模块`AdaptiveConcatPool2d`,该子模块在平均 2D 池和最大 2D 池之间执行级联,以便从卷积层到具有最大特征信息的全连接层的平滑过渡。
在此配方中,我们定义了一个子模块`AdaptiveConcatPool2d`,该子模块在平均 2D 池和最大 2D 池之间执行级联,以便从卷积层到具有最大特征信息的全连接层的平滑过渡。
然后,我们定义了`get_model()`函数,该函数首先下载 ResNet-50 模型(本地不可用)并冻结该模型的权重。 通过冻结权重,较低的卷积层不会更新。 然后,我们用`AdaptiveConcatPool2d`层替换了平均池化层,并为两个可用的类添加了具有两个输出单元的完全连接的分类器。 我们最终返回了带有冻结的 ResNet 层的模型。
然后,我们定义了`get_model()`函数,该函数首先下载 ResNet-50 模型(本地不可用)并冻结该模型的权重。 通过冻结权重,较低的卷积层不会更新。 然后,我们用`AdaptiveConcatPool2d`层替换了平均池化层,并为两个可用的类添加了具有两个输出单元的全连接分类器。 我们最终返回了带有冻结的 ResNet 层的模型。
# 实施模型培训
......
......@@ -34,7 +34,7 @@ GAN 中的两个模型称为生成器和鉴别器,其中生成器负责创建
# 创建一个 DCGAN 生成器
在本食谱及其后续食谱中,我们将实现 DCGAN。 DCGAN 代表“深度卷积 GAN”; 与香草 GAN 相比,它们有很大的改进。 在 DCGAN 中,我们使用卷积神经网络,而不是香草 GAN 中的全连接网络。 在[第 3 章](../Text/3.html)*用于计算机视觉的卷积神经网络*中,我们看到了[第 2 章](../Text/2.html)*的全连接分类器如何处理神经网络* ,是该领域的一项改进; DCGAN 与香草 GAN 的情况相同。 在 DCGAN 中,我们将使用批量归一化,这是一种技术,它可以将作为输入输入到下一层的层的输出归一化。 批量归一化允许网络的每一层独立于其他层进行学习,从而减少了协变量偏移。
在本食谱及其后续食谱中,我们将实现 DCGAN。 DCGAN 代表“深度卷积 GAN”; 与香草 GAN 相比,它们有很大的改进。 在 DCGAN 中,我们使用卷积神经网络,而不是香草 GAN 中的全连接网络。 在[第 3 章](../Text/3.html)*用于计算机视觉的卷积神经网络*中,我们看到了[第 2 章](../Text/2.html)*的全连接分类器如何处理神经网络* ,是该领域的一项改进; DCGAN 与香草 GAN 的情况相同。 在 DCGAN 中,我们将使用批量归一化,这是一种技术,它可以将作为输入输入到下一层的层的输出归一化。 批量归一化允许网络的每一层独立于其他层进行学习,从而减少了协变量偏移。
批量归一化是通过缩放来实现的,以使平均值为 0,方差为 1。在此配方中,我们将生成类似于 MNIST 数据集的手写数字,其中包含来自噪声矢量的数据。 我们将扩展此噪声矢量,将其转换为 2D 矩阵,最后将其转换为 28 x 28 黑白图像。 为了增加高度和宽度,我们必须执行与卷积操作相反的操作,这称为反卷积。 我们将在使用卷积执行分类任务时执行此操作。 在执行反卷积时,我们将增加高度和宽度,同时减少通道数。
......@@ -116,11 +116,11 @@ def forward(self, input):
在此食谱中,我们进行了变换以将图像转换为张量并对其进行归一化,就像在[第 3 章](https://cdp.packtpub.com/pytorch_1_0_artificial_intelligence_cookbook/wp-admin/post.php?post=27&action=edit#post_29)*用于计算机视觉的卷积神经网络*中所做的一样。 然后,我们确定了机器上的设备:CPU 或 GPU。 然后,我们定义了从`nn.Module`类继承的`Generator_model`类,就像在所有以前的体系结构中所做的一样。
在构造函数中,我们传递了`z_dim`参数,这是我们的噪声矢量大小。 然后,我们定义了一个完全连接的单元`self.fc`,我们将噪声矢量传递给该单元,并为其提供了`256 * 7 * 7`输出。 然后,我们定义了一个称为`self.gen``nn.Sequential`单元,其中包含用于定义生成器的关键组件。 我们使用 PyTorch 中提供的`nn.ConvTranspose2d``nn.BatchNorm2d``nn.LeakyReLU`使用一组反卷积,批处理规范化和激活层。 `ConvTranspose2d`接受输入通道,输出通道,内核大小,步幅和填充等参数。 `BatchNorm2d`接受上一层的要素/通道数作为其参数,而 LeakyReLU 接受负斜率的角度。
在构造函数中,我们传递了`z_dim`参数,这是我们的噪声矢量大小。 然后,我们定义了一个全连接单元`self.fc`,我们将噪声矢量传递给该单元,并为其提供了`256 * 7 * 7`输出。 然后,我们定义了一个称为`self.gen``nn.Sequential`单元,其中包含用于定义生成器的关键组件。 我们使用 PyTorch 中提供的`nn.ConvTranspose2d``nn.BatchNorm2d``nn.LeakyReLU`使用一组反卷积,批处理规范化和激活层。 `ConvTranspose2d`接受输入通道,输出通道,内核大小,步幅和填充等参数。 `BatchNorm2d`接受上一层的要素/通道数作为其参数,而 LeakyReLU 接受负斜率的角度。
与 ReLU 不同,LeakyReLU 允许传递小的梯度信号以获取负值。 它使来自鉴别器的梯度流入发生器。 我们在输出层中使用了 tanh 激活,但是从 DCGAN 论文中我们观察到,使用有界激活可以使模型学会快速饱和并覆盖训练分布的色彩空间。 tanh 的对称性在这里可能是一个优势,因为网络应该以对称方式处理较深的颜色和较浅的颜色。
让我们看一下`forward`方法的工作方式。 `z_dim`维度的输入噪声矢量经过完全连接的层以提供 12544 输出。 然后,我们将 12544 输出调整为`256 x 7 x 7`,其中 256 是通道数。 `256 x 7 x 7`张量然后通过反卷积层以提供`128 x 14 x 14`输出,然后通过具有 128 个特征和泄漏 ReLU 的 Batchnorm 层。 `128 x 14 x 14`然后在第二次反卷积中转换为`64 x 14 x 14`张量,在第三次反卷积中变为`1 x 28 x 28`张量; 这些只是我们需要的尺寸。 然后,我们创建生成器对象并将其移动到设备。
让我们看一下`forward`方法的工作方式。 `z_dim`维度的输入噪声矢量经过全连接层以提供 12544 输出。 然后,我们将 12544 输出调整为`256 x 7 x 7`,其中 256 是通道数。 `256 x 7 x 7`张量然后通过反卷积层以提供`128 x 14 x 14`输出,然后通过具有 128 个特征和泄漏 ReLU 的 Batchnorm 层。 `128 x 14 x 14`然后在第二次反卷积中转换为`64 x 14 x 14`张量,在第三次反卷积中变为`1 x 28 x 28`张量; 这些只是我们需要的尺寸。 然后,我们创建生成器对象并将其移动到设备。
# 也可以看看
......@@ -171,7 +171,7 @@ self.disc = nn.Sequential(
)
```
4.然后定义最后一个完全连接的层:
4.然后定义最后一个全连接层:
```py
self.fc = nn.Linear(2048, 1)
......@@ -195,7 +195,7 @@ def forward(self, input):
# 这个怎么运作...
在本食谱中,我们定义了一个分类器; 使用`nn.Sequential()`定义卷积,激活和批处理规范化单元的数组; 并且还定义了最后一个完全连接的层,该层采用平坦的张量并给出通过 S 形层的单个输出。 由于只有两个类,因此我们最后使用了 S 形层。 输入是尺寸为`1 x 28 x 28`的图像张量,并经过第一卷积单元以给出尺寸为`32 x 14 x 14`的输出张量。 第二个卷积层使它成为`64 x 7 x 7`张量,然后从那里变成`128 x 4 x 4`。 之后,我们将拉平并使张量穿过完全连接的层。
在本食谱中,我们定义了一个分类器; 使用`nn.Sequential()`定义卷积,激活和批处理规范化单元的数组; 并且还定义了最后一个全连接层,该层采用平坦的张量并给出通过 S 形层的单个输出。 由于只有两个类,因此我们最后使用了 S 形层。 输入是尺寸为`1 x 28 x 28`的图像张量,并经过第一卷积单元以给出尺寸为`32 x 14 x 14`的输出张量。 第二个卷积层使它成为`64 x 7 x 7`张量,然后从那里变成`128 x 4 x 4`。 之后,我们将拉平并使张量穿过全连接层。
# 也可以看看
......
......@@ -76,7 +76,7 @@ ONNX 内置在 PyTorch 的核心中,因此将模型迁移到 ONNX 表单不需
计算图是,是人工智能当前所有先进技术的核心。 他们奠定了深度学习框架的基础。 现在,所有现有的深度学习框架都使用图方法进行计算。 这有助于框架找到独立的节点并作为独立的线程或进程进行计算。 计算图可帮助您轻松进行反向传播,就像从子节点移动到先前的节点一样,并在返回时携带梯度。 此操作称为自动区分,这是 40 年前的想法。 自动微分被认为是上个世纪十大数值算法之一。 具体来说,反向模式自动微分是计算图背后用于反向传播的核心思想。 PyTorch 是基于反向模式自动微分而构建的,因此所有节点都将与它们一起保留操作信息,直到控件到达叶节点为止。 然后,反向传播从叶节点开始并向后遍历。 在向后移动时,流将随其一起获取梯度,并找到与每个节点相对应的偏导数。 1970 年,芬兰数学家和计算机科学家 Seppo Linnainmaa 发现自动微分可以用于算法验证。 几乎同时在同一概念上记录了许多其他并行的工作。
在深度学习中,神经网络用于求解数学方程。 无论任务多么复杂,一切都取决于一个巨大的数学方程式,您可以通过优化神经网络的参数来求解。 解决问题的明显方法是“手工”。 考虑使用大约 150 层神经网络来求解 ResNet 的数学方程; 对于人类来说,要遍历数千次图,每次手动进行相同的操作来优化参数,都是不可能的。 计算图通过将所有操作逐级映射到图并一次求解每个节点来解决此问题。 *图 1.2* 显示了具有三个运算符的简单计算图。
在深度学习中,神经网络用于求解数学方程。 无论任务多么复杂,一切都取决于一个巨大的数学方程式,您可以通过优化神经网络的参数来求解。 解决问题的明显方法是“手工”。 考虑使用大约 150 层神经网络来求解 ResNet 的数学方程; 对于人类来说,要遍历数千次图,每次手动进行相同的操作来优化参数,都是不可能的。 计算图通过将所有操作逐级映射到图并一次求解每个节点来解决此问题。 “图 1.2”显示了具有三个运算符的简单计算图。
两侧的矩阵乘法运算符给出两个矩阵作为输出,它们经过加法运算符,加法运算符又经过另一个 Sigmoid 运算符。 整个图实际上是在尝试求解以下等式:
......@@ -204,7 +204,7 @@ for epoch in range(epochs):
自从人类发明了计算机以来,我们就将它们称为智能系统,但我们一直在努力增强其智能。 在过去,计算机可以做的任何人类无法做到的事情都被认为是人工智能。 记住大量数据,对数百万或数十亿个数字进行数学运算,等等,被认为是人工智能。 我们称其为 Deep Blue,这是一款在国际象棋上击败国际象棋大师 Garry Kasparov 的机器。
最终,人类不能做的事情和计算机可以做的事情变成了计算机程序。 我们意识到对于程序员来说,人类可以轻松完成的某些事情是不可能的。 这种演变改变了一切。 我们可以写下并让像我们这样的计算机正常工作的可能性或规则的数量如此之大。 机器学习解救了人们。 人们找到了一种方法,使计算机可以从示例中学习规则,而不必明确地编写代码。 这就是所谓的机器学习。 *图 1.9* 中给出了一个示例,该示例显示了我们如何根据客户过去的购物历史来预测客户是否会购买产品。
最终,人类不能做的事情和计算机可以做的事情变成了计算机程序。 我们意识到对于程序员来说,人类可以轻松完成的某些事情是不可能的。 这种演变改变了一切。 我们可以写下并让像我们这样的计算机正常工作的可能性或规则的数量如此之大。 机器学习解救了人们。 人们找到了一种方法,使计算机可以从示例中学习规则,而不必明确地编写代码。 这就是所谓的机器学习。 “图 1.9”中给出了一个示例,该示例显示了我们如何根据客户过去的购物历史来预测客户是否会购买产品。
![Exploring deep learning](img/B09475_01_07.jpg)
......@@ -238,13 +238,13 @@ for epoch in range(epochs):
深度学习已经存在了数十年,针对不同的用例演变出了不同的结构和体系结构。 其中一些基于我们对大脑的想法,而另一些则基于大脑的实际工作。 即将到来的所有章节均基于业界正在使用的的最新体系结构。 我们将介绍每种体系结构下的一个或多个应用程序,每一章都涵盖所有概念,规范和技术细节,其中显然都包含 PyTorch 代码。
#### 完全连接的网络
#### 全连接网络
全连接或密集或线性网络是最基本但功能最强大的体系结构。 这是通常所谓的机器学习的直接扩展,在该机器学习中,您使用具有单个隐藏层的神经网络。 完全连接的层充当所有体系结构的端点,以使用下面的深度网络来找到分数的概率分布。 顾名思义,一个完全连接的网络将所有神经元在上一层和下一层相互连接。 网络可能最终决定通过设置权重来关闭某些神经元,但是在理想情况下,最初,所有神经元都参与了通信。
全连接或密集或线性网络是最基本但功能最强大的体系结构。 这是通常所谓的机器学习的直接扩展,在该机器学习中,您使用具有单个隐藏层的神经网络。 全连接层充当所有体系结构的端点,以使用下面的深度网络来找到分数的概率分布。 顾名思义,一个全连接网络将所有神经元在上一层和下一层相互连接。 网络可能最终决定通过设置权重来关闭某些神经元,但是在理想情况下,最初,所有神经元都参与了通信。
#### 编码器和解码器
编码器和解码器可能是深度学习框架下的下一个最基本的体系结构。 所有网络都有一个或多个编码器-解码器层。 您可以将全连接层中的隐藏层视为来自编码器的编码形式,而将输出层视为将隐藏层解码为输出的解码器。 通常,编码器将输入编码为中间状态,其中输入表示为向量,然后解码器网络将其解码为我们想要的输出形式。
编码器和解码器可能是深度学习框架下的下一个最基本的体系结构。 所有网络都有一个或多个编码器-解码器层。 您可以将全连接层中的隐藏层视为来自编码器的编码形式,而将输出层视为将隐藏层解码为输出的解码器。 通常,编码器将输入编码为中间状态,其中输入表示为向量,然后解码器网络将其解码为我们想要的输出形式。
编码器-解码器网络的一个典型示例是**序列到序列****seq2seq**)网络,可以将其用作机器翻译。 用英语说的句子将被编码为中间向量表示,其中整个句子将以一些浮点数的形式进行分块,并且解码器从中间向量以另一种语言解码输出句子。
......@@ -284,7 +284,7 @@ RNN 是最常见的深度学习算法之一,它们席卷全球。 我们现在
**卷积神经网络****CNN**)使我们能够在计算机视觉中获得超人的性能。 在的早期,我们达到了的人类准确性,并且我们仍在逐年提高准确性。
卷积网络是最易理解的网络,因为我们有可视化工具可以显示每一层的功能。 **Facebook AI Research****FAIR**)负责人 Yann LeCun 于 1990 年代发明了 CNN。 那时我们无法使用它们,因为我们没有足够的数据集和计算能力。 CNN 基本上像滑动窗口一样扫描您的输入并进行中间表示,然后在最终到达完全连接的层之前对其进行逐层抽象。 CNN 也成功地用于非图像数据集中。
卷积网络是最易理解的网络,因为我们有可视化工具可以显示每一层的功能。 **Facebook AI Research****FAIR**)负责人 Yann LeCun 于 1990 年代发明了 CNN。 那时我们无法使用它们,因为我们没有足够的数据集和计算能力。 CNN 基本上像滑动窗口一样扫描您的输入并进行中间表示,然后在最终到达全连接层之前对其进行逐层抽象。 CNN 也成功地用于非图像数据集中。
Facebook 研究团队发现了一种具有卷积网络的先进自然语言处理系统,该系统优于 RNN,RNN 被认为是任何序列数据集的首选架构。 尽管一些神经科学家和一些 AI 研究人员不喜欢 CNN,但是由于他们认为大脑不能像 CNN 那样工作,因此基于 CNN 的网络正在击败所有现有实现。
......
......@@ -278,7 +278,7 @@ print(a2.grad, a2.grad_fn, a2)
事情变了! 由于我们使用`required_grad`作为`False`创建了输入张量,因此我们首先进行打印以检查输入的属性没有显示任何差异。 `w1`已更改。 在向后传递之前,`.grad`属性为`None`,现在它具有一些渐变。 令人耳目一新!
权重是我们需要根据渐变更改的参数,因此我们获得了它们的渐变。 我们没有渐变函数,因为它是由用户创建的,因此`grad_fn`仍然是`None`,而`.data`仍然相同。 如果我们尝试打印数据的值,它将仍然是相同的,因为向后传递不会隐式更新张量。 总之,在`x``w1``a2`中,只有`w1`得到了梯度。 这是因为由内部函数(例如`a2`)创建的中间节点将不保存梯度,因为它们是无参数节点。 影响神经网络输出的唯一参数是我们为层定义的权重。
权重是我们需要根据渐变更改的参数,因此我们获得了它们的渐变。 我们没有渐变函数,因为它是由用户创建的,因此`grad_fn`仍然是`None`,而`.data`仍然相同。 如果我们尝试打印数据的值,它将仍然是相同的,因为向后传递不会隐式更新张量。 总之,在`x``w1``a2`中,只有`w1`得到了梯度。 这是因为由内部函数(例如`a2`)创建的中间节点将不保存梯度,因为它们是无参数节点。 影响神经网络输出的唯一参数是我们为层定义的权重。
##### 参数更新
......@@ -368,13 +368,13 @@ class FizBuzNet(nn.Module):
图 2.9:一个简单的网络,用于硬币排名并将输出传递给主要网络
`nn.Module`使您更容易拥有如此漂亮的抽象。 初始化`class`对象时,将调用`__init__()`,这又将初始化层并返回对象。 `nn.Module`实现了两个主要功能,即`__call__``backward()`,并且用户需要覆盖`forward``__init__()`
`nn.Module`使您更容易拥有如此漂亮的抽象。 初始化`class`对象时,将调用`__init__()`,这又将初始化层并返回对象。 `nn.Module`实现了两个主要功能,即`__call__``backward()`,并且用户需要覆盖`forward``__init__()`
一旦返回了层初始化的对象,就可以通过调用`model`对象本身将输入数据传递给模型。 通常,Python 对象不可调用。 要调用对象方法,用户必须显式调用它们。 但是,`nn.Module`实现了魔术函数`__call__()`,该函数又调用了用户定义的`forward`函数。 用户具有在前向呼叫中定义所需内容的特权。
只要 PyTorch 知道如何反向传播`forward`中的内容,您就很安全。 但是,如果您在`forward`中具有自定义功能或层,则 PyTorch 允许您覆盖`backward`功能,并且该功能将在返回磁带时执行。
只要 PyTorch 知道如何反向传播`forward`中的内容,您就很安全。 但是,如果您在`forward`中具有自定义功能或层,则 PyTorch 允许您覆盖`backward`功能,并且该功能将在返回磁带时执行。
用户可以选择在`__init__()`定义中构建层,这将照顾我们在新手模型中手工完成的权重和偏差创建。 在下面的`FizBuzNet`中,`__init__()`中的线创建了线性层。 线性层也称为全连接层或密集层,它在权重和输入之间进行矩阵乘法,并在内部进行偏差加法:
用户可以选择在`__init__()`定义中构建层,这将照顾我们在新手模型中手工完成的权重和偏差创建。 在下面的`FizBuzNet`中,`__init__()`中的线创建了线性层。 线性层也称为全连接层或密集层,它在权重和输入之间进行矩阵乘法,并在内部进行偏差加法:
```py
self.hidden = nn.Linear(input_size, hidden_size)
......
......@@ -12,9 +12,9 @@ CNN 是具有数十年历史的机器学习算法,直到 Geoffrey Hinton 和
CNN 是一种基本上由小型网络组成的网络体系结构,几乎类似于[第 2 章](../Text/2.html "Chapter 2\. A Simple Neural Network")*简单神经网络*中引入的简单前馈网络,但用于解决图像作为输入的问题。 CNN 由神经元组成,这些神经元具有非线性,权重参数,偏差并吐出一个损耗值,基于该值,可以使用反向传播对整个网络进行重新排列。
如果这听起来像简单的完全连接的网络,那么 CNN 为何特别适合处理图像? CNN 让开发人员做出适用于图像的某些假设,例如像素值的空间关系。
如果这听起来像简单的全连接网络,那么 CNN 为何特别适合处理图像? CNN 让开发人员做出适用于图像的某些假设,例如像素值的空间关系。
简单的完全连接的层具有更大的权重,因为它们存储信息以处理所有权重。 全连接层的另一个功能使其无法进行图像处理:它不能考虑空间信息,因为它在处理时会删除像素值的顺序/排列结构。
简单的全连接层具有更大的权重,因为它们存储信息以处理所有权重。 全连接层的另一个功能使其无法进行图像处理:它不能考虑空间信息,因为它在处理时会删除像素值的顺序/排列结构。
CNN 由几个三维内核组成,它们像滑动窗口一样在输入张量中移动,直到覆盖整个张量为止。 核是三维张量,其深度与输入张量的深度(在第一层中为 3;图像的深度在 RGB 通道中)相同。 内核的高度和宽度可以小于或等于输入张量的高度和宽度。 如果内核的高度和宽度与输入张量的高度和宽度相同,则其设置与正常神经网络的设置非常相似。
......@@ -120,7 +120,7 @@ class SimpleCNNModel(nn.Module):
return x
```
该模型具有由最大池层分隔的两个卷积层。 第二个卷积层连接到三个完全连接的层,一个接一个,将十个类的分数吐出来。
该模型具有由最大池层分隔的两个卷积层。 第二个卷积层连接到三个全连接层,一个接一个,将十个类的分数吐出来。
我们为`SimpleCNNModel`构建了自定义卷积和最大池层。 定制层可能是实现这些层的效率最低的方法,但是它们具有很高的可读性和易于理解性。
......@@ -154,7 +154,7 @@ class Conv(nn.Module):
我们在输入张量的外侧添加行和列,其值为零,以便内核中的所有值在输入图像中都有一个对应的值要配对。 我们从乘法中得到的单个值和加法运算是我们对该实例进行的卷积运算的输出。
现在,我们将内核右移一个像素,然后像滑动窗口一样再次执行该操作,并重复此操作,直到覆盖图像为止。 我们可以从每个卷积运算中获得的每个输出一起创建该层的特征图或输出。 下面的代码片段在最后三行中完成了所有这些操作。
现在,我们将内核右移一个像素,然后像滑动窗口一样再次执行该操作,并重复此操作,直到覆盖图像为止。 我们可以从每个卷积运算中获得的每个输出一起创建该层的特征图或输出。 下面的代码片段在最后三行中完成了所有这些操作。
PyTorch 支持普通的 Python 索引,我们使用它来为特定迭代查找滑动窗口所在的插槽,并将其保存到名为`val`的变量中。 但是索引创建的张量可能不是连续的内存块。 通过使用`view()`不能更改非连续存储块张量,因此我们使用`contiguous()`方法将张量移动到连续块。 然后,将该张量与内核(权重)相乘,并对其添加偏倚。 然后将卷积运算的结果保存到`out`张量,将其初始化为零作为占位符。 预先创建占位符并向其中添加元素比最后在一组单个通道上进行堆叠要高效一个数量级。
......@@ -183,7 +183,7 @@ Variable containing:
```
如您所知,如果我们使用大小为 1 x 1 x *深度*的内核,则通过对整个图像进行卷积,将获得与输入相同大小的输出。 在 CNN 中,如果我们想减小输出的大小而与内核的大小无关,我们将使用一个不错的技巧通过跨步来对输出的大小进行下采样。 *图 4.4* 显示了步幅减小对输出大小的影响。 以下公式可用于计算输出的大小以及内核的大小,填充宽度和步幅。
如您所知,如果我们使用大小为 1 x 1 x *深度*的内核,则通过对整个图像进行卷积,将获得与输入相同大小的输出。 在 CNN 中,如果我们想减小输出的大小而与内核的大小无关,我们将使用一个不错的技巧通过跨步来对输出的大小进行下采样。 “图 4.4”显示了步幅减小对输出大小的影响。 以下公式可用于计算输出的大小以及内核的大小,填充宽度和步幅。
*W =(WF + 2P)/ S + 1* ,其中`W`是输入大小,`F`是内核大小,`S`跨步应用`P`填充。
......@@ -231,7 +231,7 @@ PyTorch 的`max()`方法接受尺寸作为输入,并返回具有索引/索引
例如,前面示例中的`max(0)`返回一个元组。 元组中的第一个元素是张量,其值为 3 和 4,这是第 0 维的最大值;另一个张量,其值为 1 和 1,是该维的 3 和 4 的索引。 最大池层的最后一行通过采用第二维的`max()`和第一维的`max()`来获取子部件的最大值。
卷积层和最大池层之后是三个线性层(全连接),这将维数减小到 10,从而为每个类给出了概率得分。 接下来是 PyTorch 模型存储为实际网络图的字符串表示形式。
卷积层和最大池层之后是三个线性层(全连接),这将维数减小到 10,从而为每个类给出了概率得分。 接下来是 PyTorch 模型存储为实际网络图的字符串表示形式。
```py
>>> simple = SimpleCNNModel()
......@@ -352,7 +352,7 @@ LinkNet 体系结构中编码器和解码器之间的平行水平线是跳过连
* `ConvBlock`是自定义的`nn.Module`类,可实现卷积和非线性。
* `DeconvBlock`是一个自定义`nn.Module`类,可实现解卷积和非线性。
* `nn.MaxPool2d`是内置的 PyTorch 层,可进行 2D 最大合并。
* `nn.MaxPool2d`是内置的 PyTorch 层,可进行 2D 最大合并。
* `EncoderBlock`
* `DecoderBlock`
......
......@@ -10,7 +10,7 @@
尽管原始 RNN(在输入中为每个单元展开一个简单的 RNN 单元)是一个革命性的想法,但未能提供可用于生产的结果。 主要障碍是长期依赖问题。 当输入序列的长度增加时,网络到达最后一个单元时将无法从初始单位(单词,如果是自然语言)中记住信息。 我们将在接下来的部分中看到 RNN 单元包含的内容以及如何将其展开。
几次迭代和多年的研究得出了 RNN 架构设计的几种不同方法。 最新的模型现在使用**长短期内存****LSTM**)实现或**门控循环单元****GRU**)。 这两种实现都将 RNN 单元内的门用于不同目的,例如忘记门,它使网络忘记不必要的信息。 这些体系结构具有香草 RNN 所存在的长期依赖性问题,因此使用门不仅要忘记不必要的信息,而且要记住在长距离移动到最后一个单元时所必需的信息。
几次迭代和多年的研究得出了 RNN 架构设计的几种不同方法。 最新的模型现在使用**长短期内存****LSTM**)实现或**门控循环单元****GRU**)。 这两种实现都将 RNN 单元内的门用于不同目的,例如遗忘门,它使网络忘记不必要的信息。 这些体系结构具有香草 RNN 所存在的长期依赖性问题,因此使用门不仅要忘记不必要的信息,而且要记住在长距离移动到最后一个单元时所必需的信息。
注意是下一个重大发明,它可以帮助网络将注意力集中在输入的重要部分上,而不是搜索整个输入并试图找到答案。 实际上,来自 Google Brain 和多伦多大学的一个团队证明,注意力可以击败 LSTM 和 GRU 网络[1]。 但是,大多数实现都同时使用 LSTM / GRU 和注意力。
......@@ -134,7 +134,7 @@ inputs.vocab.load_vectors('glove.6B.300d')
在第一个单词之后,我们具有从 RNN 单元生成的输出和隐藏状态。 输出状态和隐藏状态都有自己的目的。 可以训练输出以预测句子中的下一个字符或单词。 这就是大多数语言建模任务的工作方式。
如果您试图创建一个顺序网络来预测诸如股票价格之类的时间序列数据,那么很可能这就是您构建网络的方式。 但是在我们的例子中,我们只担心句子的整体含义,因此我们将忽略每个单元格生成的输出。 除了输出,我们将重点放在隐藏状态。 如前所述,隐藏状态的目的是保持句子的连续含义。 听起来像我们要找的东西,对吗? 每个 RNN 单元都将一个隐藏状态作为输入之一,并吐出另一个隐藏状态,如*图 5.2* 中所给。
如果您试图创建一个顺序网络来预测诸如股票价格之类的时间序列数据,那么很可能这就是您构建网络的方式。 但是在我们的例子中,我们只担心句子的整体含义,因此我们将忽略每个单元格生成的输出。 除了输出,我们将重点放在隐藏状态。 如前所述,隐藏状态的目的是保持句子的连续含义。 听起来像我们要找的东西,对吗? 每个 RNN 单元都将一个隐藏状态作为输入之一,并吐出另一个隐藏状态,如“图 5.2”中所给。
我们将为每个单词使用相同的 RNN 单元,并将从上一次单词处理生成的隐藏状态作为当前单词执行的输入传递。 因此,RNN 单元在每个字处理阶段具有两个输入:字本身和上一次执行时的隐藏状态。
......@@ -144,13 +144,13 @@ inputs.vocab.load_vectors('glove.6B.300d')
图 5.2:具有输入,隐藏状态和输出展开序列的通用 RNN 单元流程图
*图 5.2* 显示了展开的同一 RNN 单元,以可视化如何处理句子中的每个单词。 由于我们为每个单词使用相同的 RNN 单元,因此大大减少了神经网络所需的参数数量,这使我们能够处理大型迷你批处理。 网络参数学习的方式是处理序列的顺序。 这是 RNN 的核心原则。
“图 5.2”显示了展开的同一 RNN 单元,以可视化如何处理句子中的每个单词。 由于我们为每个单词使用相同的 RNN 单元,因此大大减少了神经网络所需的参数数量,这使我们能够处理大型迷你批处理。 网络参数学习的方式是处理序列的顺序。 这是 RNN 的核心原则。
![RNNCell](img/B09475_05_03.jpg)
图 5.3:RNN 单元流程图
已经尝试了不同的布线机制来设计 RNN 单元以获得最有效的输出。 在本节中,我们将使用最基本的一层,它由两个完全连接的层和一个 softmax 层组成。 但是在现实世界中,人们将 LSTM 或 GRU 用作 RNN 单元,事实证明,这在许多用例中都可以提供最新的结果。 我们将在下一部分中看到它们。 实际上,已经进行了大量比较以找到所有顺序任务的最佳架构,例如 *LSTM:《搜索空间漫游》* [3]。
已经尝试了不同的布线机制来设计 RNN 单元以获得最有效的输出。 在本节中,我们将使用最基本的一层,它由两个全连接层和一个 softmax 层组成。 但是在现实世界中,人们将 LSTM 或 GRU 用作 RNN 单元,事实证明,这在许多用例中都可以提供最新的结果。 我们将在下一部分中看到它们。 实际上,已经进行了大量比较以找到所有顺序任务的最佳架构,例如 *LSTM:《搜索空间漫游》* [3]。
我们开发了一个简单的 RNN,如以下代码所示。 没有复杂的门控机制,也没有架构模式。 这是理所当然的。
......@@ -177,7 +177,7 @@ class RNNCell(nn.Module):
return torch.zeros(1, self.hidden_size)
```
如图*图 5.3* 所示,我们有两个完全连接的层,每个层负责创建输出和输入的隐藏状态。 `RNNCell``forward`功能接受先前状态的当前输入和隐藏状态,然后我们将它们连接在一起。
如图“图 5.3”所示,我们有两个全连接层,每个层负责创建输出和输入的隐藏状态。 `RNNCell``forward`功能接受先前状态的当前输入和隐藏状态,然后我们将它们连接在一起。
一个`Linear`层采用级联张量并为下一个单元生成隐藏状态,而另一`Linear`层为当前单元生成输出。 然后,输出返回`softmax`,然后返回训练循环。 `RNNCell`拥有一个称为`init_hidden`的类方法,可以方便地保留该类方法,以便在初始化`RNNCell`中的对象时使用我们通过的隐藏状态大小生成第一个隐藏状态。 在开始遍历序列以获取第一个隐藏状态之前,我们将调用`init_hidden`,该状态将被初始化为零。
......@@ -295,7 +295,7 @@ class Merger(nn.Module):
`Merger`节点也是我们的简单 RNN 的最终分类器层的一部分,该分类器由其他几个节点组成。
包装类`RNNClassifier`包装到目前为止我们定义的所有组件,并创建最终的分类器层作为`torch.nn.Sequential`的实例。 整个网络的流程显示在*图 5.3* 中,并在以下块中以代码形式表示:
包装类`RNNClassifier`包装到目前为止我们定义的所有组件,并创建最终的分类器层作为`torch.nn.Sequential`的实例。 整个网络的流程显示在“图 5.3”中,并在以下块中以代码形式表示:
```py
class RNNClassifier(nn.Module):
......@@ -329,7 +329,7 @@ class RNNClassifier(nn.Module):
* 使用`RNNCell`的编码器层,该层存储在`self.encoder`
* `self.classifier`中存储的`nn.Sequential`层的实例
最后的顺序层从`Merger`节点开始。 合并后的输出的序列长度维度将增大四倍,因为我们将两个句子,它们的差和它们的乘积都附加到`Merger`的输出中。 然后将其穿过一个完全连接的层,然后在`ReLU`非线性之后使用`batchnorm1d`将其标准化。 之后的辍学减少了过拟合的机会,过拟合的机会随后传递到另一个完全连接的层,该层为我们的输入数据创建了得分。 输入数据决定数据点所属的包围,矛盾或中性类​​别。
最后的顺序层从`Merger`节点开始。 合并后的输出的序列长度维度将增大四倍,因为我们将两个句子,它们的差和它们的乘积都附加到`Merger`的输出中。 然后将其穿过一个全连接层,然后在`ReLU`非线性之后使用`batchnorm1d`将其标准化。 之后的辍学减少了过拟合的机会,过拟合的机会随后传递到另一个全连接层,该层为我们的输入数据创建了得分。 输入数据决定数据点所属的包围,矛盾或中性类​​别。
##### 辍学
......@@ -368,15 +368,15 @@ opt = optim.Adam(model.parameters(), lr=lr)
LSTM 网络由 Sepp Hochreiter 于 1991 年引入,并于 1997 年发布。LSTM 网络在循环单元中建立了多个门,其中正常的`RNNCell`具有`Linear`层,该层通过`softmax`层相互作用以生成输出和 另一个`Linear`层会生成隐藏状态。 有关 LSTM 的详细说明,请参见原始论文或克里斯托弗·奥拉(Christopher Olah)的博客,标题为*了解 LSTM 网络* [4]。
LSTM 主要由忘记门,更新门和单元状态组成,这使得 LSTM 与常规 RNN 单元不同。 该体系结构经过精心设计,可以执行特定任务。 遗忘门使用输入向量和先前状态的隐藏状态来确定例如应忘记的内容,更新门使用当前输入和先前的隐藏状态来确定应添加到信息存储库中的内容。
LSTM 主要由遗忘门,更新门和单元状态组成,这使得 LSTM 与常规 RNN 单元不同。 该体系结构经过精心设计,可以执行特定任务。 遗忘门使用输入向量和先前状态的隐藏状态来确定例如应忘记的内容,更新门使用当前输入和先前的隐藏状态来确定应添加到信息存储库中的内容。
这些决定基于 S 形图层的输出,该图层始终输出一个介于 0 到 1 范围内的值。 因此,“忘记门”中的值 1 表示记住所有内容,而值 0 则表示忘记所有内容。 更新门同样适用。
这些决定基于 S 形层的输出,该层始终输出一个介于 0 到 1 范围内的值。 因此,“遗忘门”中的值 1 表示记住所有内容,而值 0 则表示忘记所有内容。 更新门同样适用。
所有操作都将在并行流经网络的单元状态上执行,这与网络中的信息仅具有线性交互作用,因此允许数据无缝地向前和向后流动。
#### GRU
GRU 是一个相对较新的设计,与 LSTM 相比,它效率高且复杂度低。 简而言之,GRU 将忘记门和更新门合并在一起,并且只对单元状态进行一次一次性更新。 实际上,GRU 没有单独的单元状态和隐藏状态,两者都合并在一起以创建一个状态。 这些简化在不影响网络准确性的前提下,极大地降低了 GRU 的复杂性。 由于 GRU 比 LSTM 具有更高的性能,因此 GRU 如今已被广泛使用。
GRU 是一个相对较新的设计,与 LSTM 相比,它效率高且复杂度低。 简而言之,GRU 将遗忘门和更新门合并在一起,并且只对单元状态进行一次一次性更新。 实际上,GRU 没有单独的单元状态和隐藏状态,两者都合并在一起以创建一个状态。 这些简化在不影响网络准确性的前提下,极大地降低了 GRU 的复杂性。 由于 GRU 比 LSTM 具有更高的性能,因此 GRU 如今已被广泛使用。
![GRUs](img/B09475_05_07.jpg)
......
......@@ -63,7 +63,7 @@ PixelCNN 一次生成一个像素,并使用该像素生成下一个像素,
与 PixelRNN 不同,PixelCNN 使用卷积层作为接收场,从而缩短了输入的读取时间。 考虑一下图像被某些东西遮挡了; 假设我们只有一半的图像。 因此,我们有一半的图像,并且我们的算法需要生成后半部分。 在 PixelRNN 中,网络需要像图像中的单词序列一样逐个获取每个像素,并生成一半的图像,而 PixelCNN 则通过卷积层一次获取图像。 但是,无论如何,PixelCNN 的生成都必须是顺序的。 您可能想知道只有一半的图像会进行卷积。 答案是屏蔽卷积,我们将在后面解释。
*图 6.5* 显示了如何对像素集应用卷积运算以预测中心像素。 与其他模型相比,自回归模型的主要优点是联合概率学习技术易于处理,可以使用梯度下降进行学习。 没有近似值,也没有解决方法。 我们只是尝试在给定所有先前像素值的情况下预测每个像素值,并且训练完全由反向传播支持。 但是,由于生成始终是顺序的,因此我们很难使用自回归模型来实现可伸缩性。 PixelCNN 是一个结构良好的模型,在生成新像素的同时,将各个概率的乘积作为所有先前像素的联合概率。 在 RNN 模型中,这是默认行为,但是 CNN 模型通过使用巧妙设计的遮罩来实现此目的,如前所述。
“图 6.5”显示了如何对像素集应用卷积运算以预测中心像素。 与其他模型相比,自回归模型的主要优点是联合概率学习技术易于处理,可以使用梯度下降进行学习。 没有近似值,也没有解决方法。 我们只是尝试在给定所有先前像素值的情况下预测每个像素值,并且训练完全由反向传播支持。 但是,由于生成始终是顺序的,因此我们很难使用自回归模型来实现可伸缩性。 PixelCNN 是一个结构良好的模型,在生成新像素的同时,将各个概率的乘积作为所有先前像素的联合概率。 在 RNN 模型中,这是默认行为,但是 CNN 模型通过使用巧妙设计的遮罩来实现此目的,如前所述。
PixelCNN 捕获参数中像素之间的依存关系分布,这与其他方法不同。 VAE 通过生成隐藏的潜在向量来学习此分布,该向量引入了独立的假设。 在 PixelCNN 中,学习的依赖性不仅在先前的像素之间,而且在不同的通道之间; 在正常的彩色图像中,它是红色,绿色和蓝色(RGB)。
......@@ -142,7 +142,7 @@ class MaskedConv2d(nn.Conv2d):
self.mask = self.weight.data.clone()
```
但这绝不会成为`state_dict`的一部分,也永远不会保存到磁盘。 使用`register_buffer`,我们可以确保我们创建的新张量将成为`state_dict`的一部分。 然后使用就地`fill_`操作将掩码张量填充为 1s,然后向其添加 0 以得到类似于*图 6.6* 的张量,尽管该图仅显示了二维张量, 实际重量张量是三维的。 `forward`功能仅用于通过乘以遮罩张量来遮罩重量张量。 乘法将保留与掩码具有 1 的索引对应的所有值,同时删除与掩码具有 0 的索引对应的所有值。然后,对父级`Conv2d`层的常规调用使用权重张量,并执行两个操作 维卷积。
但这绝不会成为`state_dict`的一部分,也永远不会保存到磁盘。 使用`register_buffer`,我们可以确保我们创建的新张量将成为`state_dict`的一部分。 然后使用就地`fill_`操作将掩码张量填充为 1s,然后向其添加 0 以得到类似于“图 6.6”的张量,尽管该图仅显示了二维张量, 实际重量张量是三维的。 `forward`功能仅用于通过乘以遮罩张量来遮罩重量张量。 乘法将保留与掩码具有 1 的索引对应的所有值,同时删除与掩码具有 0 的索引对应的所有值。然后,对父级`Conv2d`层的常规调用使用权重张量,并执行两个操作 维卷积。
网络的最后一层是 softmax 层,该层可预测像素的 256 个可能值中的值,从而离散化网络的输出生成,而先前使用的最先进的自回归模型将在网络上继续生成值 最后一层。
......@@ -213,9 +213,9 @@ WaveNet 的基本构件是膨胀卷积,它取代了 RNN 的功能来获取上
来源: *WaveNet:原始音频的生成模型*,Aaron van den Oord 等
*图 6.8* 显示了 WaveNet 在进行新值预测时如何提取有关上下文的信息。 输入以蓝色(图片的底部)给出,它是原始音频样本。 例如,一个 16 kHz 的音频样本具有一秒钟音频的 16,000 个数据点,如果与自然语言的序列长度(每个单词将是一个数据点)相比,这是巨大的。 这些长序列是为什么 RNN 对原始音频样本不太有效的一个很好的原因。
“图 6.8”显示了 WaveNet 在进行新值预测时如何提取有关上下文的信息。 输入以蓝色(图片的底部)给出,它是原始音频样本。 例如,一个 16 kHz 的音频样本具有一秒钟音频的 16,000 个数据点,如果与自然语言的序列长度(每个单词将是一个数据点)相比,这是巨大的。 这些长序列是为什么 RNN 对原始音频样本不太有效的一个很好的原因。
LSTM 网络可以记住上下文信息的实际序列长度为 50 到 100。上图具有三个隐藏层,这些隐藏层使用来自上一层的信息。 第一层输入经过一维卷积层以生成第二层的数据。 卷积可以并行完成,这与 RNN 的情况不同,在卷积中,每个数据点都需要先前的输入顺序地传递。 为了使收集更多上下文,我们可以增加层数。 在*图 6.8* 中,位于第四层的输出将从输入层中的五个节点获取上下文信息。 因此,每一层将另外一个输入节点添加到上下文中。 也就是说,如果我们有 10 个隐藏层,则最后一层将从 12 个输入节点获取上下文信息。
LSTM 网络可以记住上下文信息的实际序列长度为 50 到 100。上图具有三个隐藏层,这些隐藏层使用来自上一层的信息。 第一层输入经过一维卷积层以生成第二层的数据。 卷积可以并行完成,这与 RNN 的情况不同,在卷积中,每个数据点都需要先前的输入顺序地传递。 为了使收集更多上下文,我们可以增加层数。 在“图 6.8”中,位于第四层的输出将从输入层中的五个节点获取上下文信息。 因此,每一层将另外一个输入节点添加到上下文中。 也就是说,如果我们有 10 个隐藏层,则最后一层将从 12 个输入节点获取上下文信息。
![WaveNet](img/B09475_06_10.jpg)
......@@ -231,7 +231,7 @@ LSTM 网络可以记住上下文信息的实际序列长度为 50 到 100。上
资料来源:通过扩散卷积进行的多尺度上下文聚合,Fisher Yu 和 Vladlen Koltun
*图 6.9* 显示了 WaveNet 中使用的膨胀卷积方案(尽管为了更好地理解膨胀卷积,我们在这里使用的是二维图片; WaveNet 使用一维卷积)。 尽管该实现方案跳过了中参数的日志,但最终节点仍然可以通过这种巧妙设计的方案从上下文中的所有节点获取信息。 在具有扩张卷积和三个隐藏层的情况下,先前的实现覆盖了 16 个输入节点,而先前没有扩张卷积的实现仅覆盖了五个输入节点。
“图 6.9”显示了 WaveNet 中使用的膨胀卷积方案(尽管为了更好地理解膨胀卷积,我们在这里使用的是二维图片; WaveNet 使用一维卷积)。 尽管该实现方案跳过了中参数的日志,但最终节点仍然可以通过这种巧妙设计的方案从上下文中的所有节点获取信息。 在具有扩张卷积和三个隐藏层的情况下,先前的实现覆盖了 16 个输入节点,而先前没有扩张卷积的实现仅覆盖了五个输入节点。
```py
dilatedcausalconv = torch.nn.Conv1d(
......@@ -243,7 +243,7 @@ dilatedcausalconv = torch.nn.Conv1d(
bias=False)
```
可以用*图 6.10* 中给出的二维图片直观地解释膨胀卷积的实现。 所有这三个示例均使用大小为 3x3 的内核,其中最左边的块显示的是正常卷积或膨胀卷积,其膨胀因子等于零。 中间块具有相同的内核,但膨胀因子为 2,最后一个块的膨胀因子为 4。 扩张卷积的实现技巧是在内核之间添加零以扩展内核的大小,如图*图 6.11* 所示:
可以用“图 6.10”中给出的二维图片直观地解释膨胀卷积的实现。 所有这三个示例均使用大小为 3x3 的内核,其中最左边的块显示的是正常卷积或膨胀卷积,其膨胀因子等于零。 中间块具有相同的内核,但膨胀因子为 2,最后一个块的膨胀因子为 4。 扩张卷积的实现技巧是在内核之间添加零以扩展内核的大小,如图“图 6.11”所示:
![WaveNet](img/B09475_06_12.jpg)
......@@ -262,7 +262,7 @@ causalconv = torch.nn.Conv1d(
bias=False)
```
WaveNet 的完整架构建立在膨胀卷积网络和卷积后门控激活的基础之上。 WaveNet 中的数据流从因果卷积运算开始,这是一种正常的一维卷积,然后传递到膨胀的卷积节点。 WaveNet 图片中的每个白色圆圈(*图 6.9* )是一个扩展的卷积节点。 然后,将正常卷积的数据点传递到膨胀的卷积节点,然后将其独立地通过 S 型门和 tanh 激活。 然后,两个运算的输出通过逐点乘法运算符和 1x1 卷积进行。 WaveNet 使用剩余连接和跳过连接来平滑数据流。 与主流程并行运行的剩余线程通过加法运算与 1x1 卷积的输出合并。
WaveNet 的完整架构建立在膨胀卷积网络和卷积后门控激活的基础之上。 WaveNet 中的数据流从因果卷积运算开始,这是一种正常的一维卷积,然后传递到膨胀的卷积节点。 WaveNet 图片中的每个白色圆圈(“图 6.9”)是一个扩展的卷积节点。 然后,将正常卷积的数据点传递到膨胀的卷积节点,然后将其独立地通过 S 型门和 tanh 激活。 然后,两个运算的输出通过逐点乘法运算符和 1x1 卷积进行。 WaveNet 使用剩余连接和跳过连接来平滑数据流。 与主流程并行运行的剩余线程通过加法运算与 1x1 卷积的输出合并。
![WaveNet](img/B09475_06_13.jpg)
......@@ -270,7 +270,7 @@ WaveNet 的完整架构建立在膨胀卷积网络和卷积后门控激活的基
来源: *WaveNet:原始音频的生成模型*,Aaron van den Oord 等
*中提供的 WaveNet 的结构图图 6.12* 显示了所有这些小组件以及它们如何连接在一起。 跳过连接之后的部分在程序中称为密集层,尽管它不是上一章介绍的密集层。 通常,密集层表示完全连接的层,以将非线性引入网络并获得所有数据的概览。 但是 WaveNet 的作者发现,正常的致密层可以由一串 ReLU 代替,并且 1x1 卷积可以通过最后的 softmax 层实现更高的精度,该层可以展开为 256 个单位(巨大扇出的 8 位µ律量化) 音频)。
*中提供的 WaveNet 的结构图图 6.12* 显示了所有这些小组件以及它们如何连接在一起。 跳过连接之后的部分在程序中称为密集层,尽管它不是上一章介绍的密集层。 通常,密集层表示全连接层,以将非线性引入网络并获得所有数据的概览。 但是 WaveNet 的作者发现,正常的致密层可以由一串 ReLU 代替,并且 1x1 卷积可以通过最后的 softmax 层实现更高的精度,该层可以展开为 256 个单位(巨大扇出的 8 位µ律量化) 音频)。
```py
class WaveNetModule(torch.nn.Module):
......@@ -457,7 +457,7 @@ def fake_data_target(size):
return torch.zeros(size, 1).to(device)
```
因此,鉴别器的实现很容易实现,因为它本质上只是分类任务。 生成器网络将涉及所有卷积上采样/下采样,因此有点复杂。 但是对于当前示例,由于我们希望它尽可能简单,因此我们将在完全连接的网络而不是卷积网络上进行工作。
因此,鉴别器的实现很容易实现,因为它本质上只是分类任务。 生成器网络将涉及所有卷积上采样/下采样,因此有点复杂。 但是对于当前示例,由于我们希望它尽可能简单,因此我们将在全连接网络而不是卷积网络上进行工作。
```py
def noise(size):
......@@ -543,7 +543,7 @@ loss = nn.BCELoss()
CycleGAN 是 GAN 类型的智能变体之一。 在同一体系结构中,两个 GAN 之间巧妙设计的循环流可教导两个不同分布之间的映射。 先前的方法需要来自不同分布的成对图像,以便网络学习映射。 对于示例,如果目标是建立一个可以将黑白图像转换为彩色图像的网络,则数据集在训练集中需要将同一图像的黑白和彩色版本作为一对。 尽管很难,但在一定程度上这是可能的。 但是,如果要使冬天拍摄的图像看起来像夏天拍摄的图像,则训练集中的这对图像必须是在冬天和夏天拍摄的具有相同对象和相同帧的完全相同的图像。 这是完全不可能的,而那正是 CycleGAN 可以提供帮助的地方。
CycleGAN 学习每种分布的模式,并尝试将图像从一种分布映射到另一种分布。 *图 6.19* 中给出了 CycleGAN 的简单架构图。 上面的图显示了如何训练一个 GAN,下面的图显示了如何使用正在工作的 CycleGAN 典型示例:马和斑马来训练另一个。
CycleGAN 学习每种分布的模式,并尝试将图像从一种分布映射到另一种分布。 “图 6.19”中给出了 CycleGAN 的简单架构图。 上面的图显示了如何训练一个 GAN,下面的图显示了如何使用正在工作的 CycleGAN 典型示例:马和斑马来训练另一个。
在 CycleGAN 中,我们不是从分布中随机采样的数据开始,而是使用来自集合 A(在本例中为一组马)的真实图像。 委托生成器 A 到 B(我们称为 A2B)将同一匹马转换为斑马,但没有将成对的马匹转换为斑马的配对图像。 训练开始时,A2B 会生成无意义的图像。 鉴别器 B 从 A2B 生成的图像或从集合 B(斑马的集合)中获取真实图像。 与其他任何鉴别器一样,它负责预测图像是生成的还是真实的。 这个过程是正常的 GAN,它永远不能保证同一匹马转换为斑马。 而是将马的图像转换为斑马的任何图像,因为损失只是为了确保图像看起来像集合 B 的分布; 它不需要与集合 A 相关。为了强加这种相关性,CycleGAN 引入了循环。
......
......@@ -258,7 +258,7 @@ tensor(0.0811, grad_fn=<NegBackward>) tensor(1.)
现在,我们将重构代码,使其执行与以前相同的操作,只是我们将开始利用 PyTorch 的`nn`类使其更加简洁和灵活。 从这里开始的每一步,我们都应该使代码中的一个或多个:更短,更易理解和/或更灵活。
第一步也是最简单的步骤,就是用`torch.nn.functional`(通常按照惯例将其导入到名称空间`F`中)替换我们的手写激活和丢失函数,从而缩短代码长度。 该模块包含`torch.nn`库中的所有功能(而该库的其他部分包含类)。 除了广泛的损失和激活功能外,您还会在这里找到一些方便的功能来创建神经网络,例如合并功能。 (还有一些用于进行卷积,线性层等的函数,但是正如我们将看到的那样,通常可以使用库的其他部分来更好地处理这些函数。)
第一步也是最简单的步骤,就是用`torch.nn.functional`(通常按照惯例将其导入到名称空间`F`中)替换我们的手写激活和丢失函数,从而缩短代码长度。 该模块包含`torch.nn`库中的所有功能(而该库的其他部分包含类)。 除了广泛的损失和激活功能外,您还会在这里找到一些方便的功能来创建神经网络,例如合并功能。 (还有一些用于进行卷积,线性层等的函数,但是正如我们将看到的那样,通常可以使用库的其他部分来更好地处理这些函数。)
如果您使用的是负对数似然损失和对数 softmax 激活,那么 Pytorch 会提供结合了两者的单一功能`F.cross_entropy`。 因此,我们甚至可以从模型中删除激活函数。
......@@ -625,7 +625,7 @@ valid_dl = DataLoader(valid_ds, batch_size=bs * 2)
我们将在每个时期结束时计算并打印验证损失。
(请注意,我们总是在训练之前调用`model.train()`,并在推理之前调用`model.eval()`,因为诸如`nn.BatchNorm2d``nn.Dropout`之类的层会使用它们,以确保这些不同阶段的行为正确。)
(请注意,我们总是在训练之前调用`model.train()`,并在推理之前调用`model.eval()`,因为诸如`nn.BatchNorm2d``nn.Dropout`之类的层会使用它们,以确保这些不同阶段的行为正确。)
```py
model, opt = get_model()
......@@ -775,7 +775,7 @@ fit(epochs, model, loss_func, opt, train_dl, valid_dl)
`torch.nn`还有另一个方便的类,可以用来简化我们的代码: [Sequential](https://pytorch.org/docs/stable/nn.html#torch.nn.Sequential)`Sequential`对象以顺序方式运行其中包含的每个模块。 这是编写神经网络的一种简单方法。
为了利用这一点,我们需要能够从给定的函数轻松定义**自定义层**。 例如,PyTorch 没有<cite>视图</cite>图层,我们需要为我们的网络创建一个图层。 `Lambda`将创建一个层,然后在使用`Sequential`定义网络时可以使用该层。
为了利用这一点,我们需要能够从给定的函数轻松定义**自定义层**。 例如,PyTorch 没有<cite>视图</cite>层,我们需要为我们的网络创建一个层。 `Lambda`将创建一个层,然后在使用`Sequential`定义网络时可以使用该层。
```py
class Lambda(nn.Module):
......
......@@ -13,7 +13,7 @@
这两个主要的转移学习方案如下所示:
* **对卷积网络进行微调**:代替随机初始化,我们使用经过预训练的网络初始化网络,例如在 imagenet 1000 数据集上进行训练的网络。 其余的培训照常进行。
* **作为固定特征提取器的 ConvNet**:在这里,我们将冻结除最终完全连接层之外的所有网络的权重。 最后一个完全连接的层将替换为具有随机权重的新层,并且仅训练该层。
* **作为固定特征提取器的 ConvNet**:在这里,我们将冻结除最终全连接层之外的所有网络的权重。 最后一个全连接层将替换为具有随机权重的新层,并且仅训练该层。
```py
# License: BSD
......@@ -225,7 +225,7 @@ def visualize_model(model, num_images=6):
## 微调 convnet](docs / modern-java-zh /
加载预训练的模型并重置最终的全连接层。
加载预训练的模型并重置最终的全连接层。
```py
model_ft = models.resnet18(pretrained=True)
......
......@@ -26,7 +26,7 @@ GAN 是用于教授 DL 模型以捕获培训数据分布的框架,因此我们
### 什么是 DCGAN?](docs / modern-java-zh /
DCGAN 是上述 GAN 的直接扩展,不同之处在于,DCGAN 分别在鉴别器和生成器中分别使用卷积和卷积转置层。 它最早由 Radford 等人描述。 等 在论文[中使用深度卷积生成对抗网络](https://arxiv.org/pdf/1511.06434.pdf)进行无监督表示学习。 鉴别器由分层的[卷积](https://pytorch.org/docs/stable/nn.html#torch.nn.Conv2d)层,[批处理规范](https://pytorch.org/docs/stable/nn.html#torch.nn.BatchNorm2d)层和 [LeakyReLU](https://pytorch.org/docs/stable/nn.html#torch.nn.LeakyReLU) 激活组成。 输入是 3x64x64 的输入图像,输出是输入来自真实数据分布的标量概率。 生成器由[卷积转置](https://pytorch.org/docs/stable/nn.html#torch.nn.ConvTranspose2d)层,批处理规范层和 [ReLU](https://pytorch.org/docs/stable/nn.html#relu) 激活组成。 输入是从标准正态分布中提取的潜矢量\(z \),输出是 3x64x64 RGB 图像。 跨步的转置层使潜矢量可以转换为具有与图像相同形状的体积。 在本文中,作者还提供了一些有关如何设置优化器,如何计算损失函数以及如何初始化模型权重的提示,所有这些都将在接下来的部分中进行解释。
DCGAN 是上述 GAN 的直接扩展,不同之处在于,DCGAN 分别在鉴别器和生成器中分别使用卷积和卷积转置层。 它最早由 Radford 等人描述。 等 在论文[中使用深度卷积生成对抗网络](https://arxiv.org/pdf/1511.06434.pdf)进行无监督表示学习。 鉴别器由分层的[卷积](https://pytorch.org/docs/stable/nn.html#torch.nn.Conv2d)层,[批处理规范](https://pytorch.org/docs/stable/nn.html#torch.nn.BatchNorm2d)层和 [LeakyReLU](https://pytorch.org/docs/stable/nn.html#torch.nn.LeakyReLU) 激活组成。 输入是 3x64x64 的输入图像,输出是输入来自真实数据分布的标量概率。 生成器由[卷积转置](https://pytorch.org/docs/stable/nn.html#torch.nn.ConvTranspose2d)层,批处理规范层和 [ReLU](https://pytorch.org/docs/stable/nn.html#relu) 激活组成。 输入是从标准正态分布中提取的潜矢量\(z \),输出是 3x64x64 RGB 图像。 跨步的转置层使潜矢量可以转换为具有与图像相同形状的体积。 在本文中,作者还提供了一些有关如何设置优化器,如何计算损失函数以及如何初始化模型权重的提示,所有这些都将在接下来的部分中进行解释。
```py
from __future__ import print_function
......
......@@ -164,7 +164,7 @@ torch.Size([5, 1, 57])
## 创建网络](docs / modern-java-zh /
在进行自动分级之前,在 Torch 中创建一个循环神经网络涉及在多个时间步长上克隆图层的参数。 图层保留了隐藏状态和渐变,这些图层现在完全由图形本身处理。 这意味着您可以非常“纯”的方式将 RNN 用作常规前馈层。
在进行自动分级之前,在 Torch 中创建一个循环神经网络涉及在多个时间步长上克隆层的参数。 层保留了隐藏状态和渐变,这些层现在完全由图形本身处理。 这意味着您可以非常“纯”的方式将 RNN 用作常规前馈层。
该 RNN 模块(主要从 PyTorch for Torch 用户教程的[复制)只有两个线性层,它们在输入和隐藏状态下运行,在输出之后是 LogSoftmax 层。](https://pytorch.org/tutorials/beginner/former_torchies/nn_tutorial.html#example-2-recurrent-net)
......
......@@ -779,7 +779,7 @@ output = he s a talented young writer . <EOS>
* 聊天→回复
* 问题→答案
* 用预训练的单词嵌入(例如 word2vec 或 GloVe)替换嵌入
* 尝试使用更多的层,更多的隐藏单元和更多的句子。 比较训练时间和结果。
* 尝试使用更多的层,更多的隐藏单元和更多的句子。 比较训练时间和结果。
* 如果您使用翻译对,其中成对具有两个相同的词组(`I am test \t I am test`),则可以将其用作自动编码器。 尝试这个:
* 训练为自动编码器
* 仅保存编码器网络
......
......@@ -66,7 +66,7 @@ def load_data(data_dir="./data"):
## 可配置神经网络] [docs / modern-java-zh /
我们只能调整那些可配置的参数。 在此示例中,我们可以指定完全连接的图层的图层大小:
我们只能调整那些可配置的参数。 在此示例中,我们可以指定全连接层的层大小:
```py
class Net(nn.Module):
......
......@@ -16,7 +16,7 @@
转移学习是指利用预训练的模型应用于不同数据集的技术。 使用转移学习的主要方法有两种:
1. **作为固定特征提取器的 ConvNet**:在这里,您[“冻结”](https://arxiv.org/abs/1706.04983) 网络中所有参数的权重,但最后几层(又称“头部”)的权重通常 连接的层)。 将这些最后一层替换为使用随机权重初始化的新层,并且仅训练这些层。
1. **作为固定特征提取器的 ConvNet**:在这里,您[“冻结”](https://arxiv.org/abs/1706.04983) 网络中所有参数的权重,但最后几层(又称“头部”)的权重通常 连接的层)。 将这些最后一层替换为使用随机权重初始化的新层,并且仅训练这些层。
2. **对 ConvNet 进行微调**:使用随机训练的网络初始化模型,而不是随机初始化,然后像往常一样使用不同的数据集进行训练。 通常,如果输出数量不同,则在网络中也会更换磁头(或磁头的一部分)。 这种方法通常将学习率设置为较小的值。 这样做是因为已经对网络进行了训练,并且只需进行较小的更改即可将其“微调”到新的数据集。
您还可以结合以上两种方法:首先,可以冻结特征提取器,并训练头部。 之后,您可以解冻特征提取器(或其一部分),将学习率设置为较小的值,然后继续进行训练。
......@@ -278,7 +278,7 @@ num_ftrs = model_fe.fc.in_features
此时,您需要修改预训练模型。 该模型在开始和结束时都有量化/去量化块。 但是,由于只使用要素提取器,因此反量化层必须在线性层(头部)之前移动。 最简单的方法是将模型包装在`nn.Sequential`模块中。
第一步是在 ResNet 模型中隔离特征提取器。 尽管在本示例中,您被责成使用`fc`以外的所有层作为特征提取器,但实际上,您可以根据需要选择任意数量的零件。 如果您也想替换一些卷积层,这将很有用。
第一步是在 ResNet 模型中隔离特征提取器。 尽管在本示例中,您被责成使用`fc`以外的所有层作为特征提取器,但实际上,您可以根据需要选择任意数量的零件。 如果您也想替换一些卷积层,这将很有用。
注意
......
......@@ -55,7 +55,7 @@
深度学习问题陈述和算法可以根据其研究和应用领域进一步细分为四个不同的部分:
* **通用深度学习**:密集连接的层或完全连接的网络
* **通用深度学习**:密集连接的层或全连接网络
* **序列模型**:循环神经网络,长期短期记忆网络,门控递归单元等
......@@ -375,7 +375,7 @@ Xavier 初始化是神经网络中权重的初始化,是遵循高斯分布的
* 对聚合信号进行激活以创建更深层的内部表示,这些表示又是相应隐藏节点的值
参考上图,我们有三个输入功能![](img/08e07c6f-3487-48cf-9da0-ac1d5b589468.png)和![](img/45d82003-1dd4-4384-8964-96bab8e65d9c.png)。 显示值为 1 的节点被视为偏置单元。 除输出外,每一层通常都有一个偏置单元。 偏差单位可以看作是一个拦截项,在左右激活函数中起着重要作用。 请记住,隐藏层和其中的节点的数量是我们一开始定义的超参数。 在这里,我们将![](img/b27e3bd1-340c-4576-8805-b25a426e35b0.png)和![](img/dc417ad4-d548-4176-b05e-e4193e26620d.png)的隐藏层数定义为 1,将隐藏节点的数数定义为 3。 因此,可以说我们有三个输入单元,三个隐藏单元和三个输出单元(![](img/e0f0f3bb-5953-45d2-8a1a-cd0303871581.png)和![](img/7ccfb224-70cf-4cf8-b027-7d1eebdb7c8e.png),因为我们要预测的类别是三类)。 这将为我们提供与层关联的权重和偏差的形状。 例如,第 0 层具有 3 个单位,第 1 层具有 3 个单位。与第 i 层相关联的权重矩阵和偏差矢量的形状如下:
参考上图,我们有三个输入功能![](img/08e07c6f-3487-48cf-9da0-ac1d5b589468.png)和![](img/45d82003-1dd4-4384-8964-96bab8e65d9c.png)。 显示值为 1 的节点被视为偏置单元。 除输出外,每一层通常都有一个偏置单元。 偏差单位可以看作是一个拦截项,在左右激活函数中起着重要作用。 请记住,隐藏层和其中的节点的数量是我们一开始定义的超参数。 在这里,我们将![](img/b27e3bd1-340c-4576-8805-b25a426e35b0.png)和![](img/dc417ad4-d548-4176-b05e-e4193e26620d.png)的隐藏层数定义为 1,将隐藏节点的数数定义为 3。 因此,可以说我们有三个输入单元,三个隐藏单元和三个输出单元(![](img/e0f0f3bb-5953-45d2-8a1a-cd0303871581.png)和![](img/7ccfb224-70cf-4cf8-b027-7d1eebdb7c8e.png),因为我们要预测的类别是三类)。 这将为我们提供与层关联的权重和偏差的形状。 例如,第 0 层具有 3 个单位,第 1 层具有 3 个单位。与第 i 层相关联的权重矩阵和偏差矢量的形状如下:
![](img/491169f7-46c4-469b-93cd-1cb8f4f01162.png)
......@@ -503,11 +503,11 @@ RNN 实际上无法处理**长期依赖项**。 随着输出序列中的输出
![](img/3822e6c5-1056-44e1-ad43-c0b7c68a00e0.png)
LSTM 的关键特征是单元状态![](img/03603cb5-2d59-48ad-8d9d-739cc0697bef.png)。 这有助于信息保持不变。 我们将从忘记门层![](img/82ce7d60-d0d1-4066-a9c7-18e6c5b351c1.png)开始,该层将最后一个隐藏状态,![](img/704c9aeb-4394-44d8-b46e-0925d6cbc5fb.png)和![](img/a058a147-2e03-4601-81e3-25816b758255.png)的串联作为输入,并训练一个神经网络,该神经网络对于其中的每个数字得出 0 到 1 之间的数字。 最后一个单元格状态![](img/4168a812-e51e-4afe-9436-8b355131088f.png),其中 1 表示保留该值,0 表示忘记该值。 因此,该层将识别过去要忘记的信息,并保留哪些信息。
LSTM 的关键特征是单元状态![](img/03603cb5-2d59-48ad-8d9d-739cc0697bef.png)。 这有助于信息保持不变。 我们将从遗忘门层![](img/82ce7d60-d0d1-4066-a9c7-18e6c5b351c1.png)开始,该层将最后一个隐藏状态,![](img/704c9aeb-4394-44d8-b46e-0925d6cbc5fb.png)和![](img/a058a147-2e03-4601-81e3-25816b758255.png)的串联作为输入,并训练一个神经网络,该神经网络对于其中的每个数字得出 0 到 1 之间的数字。 最后一个单元格状态![](img/4168a812-e51e-4afe-9436-8b355131088f.png),其中 1 表示保留该值,0 表示忘记该值。 因此,该层将识别过去要忘记的信息,并保留哪些信息。
![](img/8e72b527-34c7-411d-ab7a-e134400a410a.png)
接下来,我们进入输入门层![](img/7977d07d-1440-43ab-881f-7b517978da22.png)和 tanh 层![](img/8302b240-51fa-4079-bb11-2e83d4d114dc.png),它们的任务是确定要添加到过去接收到的信息中的新信息以更新信息,即单元状态。 tanh 层创建新值的向量,而输入门层则标识用于信息更新的那些值中的哪一个。 将此新信息与使用“忘记门”层![](img/cc10c0d9-5827-4e59-8433-aa8a03ef1e68.png)保留的信息结合起来以更新我们的信息,即单元状态![](img/6565e4ff-1c73-4519-929c-be05b74443ea.png)
接下来,我们进入输入门层![](img/7977d07d-1440-43ab-881f-7b517978da22.png)和 tanh 层![](img/8302b240-51fa-4079-bb11-2e83d4d114dc.png),它们的任务是确定要添加到过去接收到的信息中的新信息以更新信息,即单元状态。 tanh 层创建新值的向量,而输入门层则标识用于信息更新的那些值中的哪一个。 将此新信息与使用“遗忘门”层![](img/cc10c0d9-5827-4e59-8433-aa8a03ef1e68.png)保留的信息结合起来以更新我们的信息,即单元状态![](img/6565e4ff-1c73-4519-929c-be05b74443ea.png)
![](img/e014559b-eeb5-4a39-bdcc-87d91ea0c4dc.png)
......@@ -563,7 +563,7 @@ CNN 体系结构由一系列这些卷积层组成。 如果这些卷积层中的
最大池化通常会产生更准确的结果。 类似地,我们具有**平均池**,其中取最大值而不是取池窗口中值的平均值,以提供特征图的低分辨率视图。
通过合并和完全连接的层来操纵卷积层的超参数和排序,已经创建了许多不同的 CNN 变体,这些变体正在研究和工业领域中使用。 其中一些著名的是 LeNet-5,Alexnet,VGG-Net 和 Inception 模型。
通过合并和全连接层来操纵卷积层的超参数和排序,已经创建了许多不同的 CNN 变体,这些变体正在研究和工业领域中使用。 其中一些著名的是 LeNet-5,Alexnet,VGG-Net 和 Inception 模型。
# LeNet-5 卷积神经网络
......@@ -573,20 +573,20 @@ LeNet-5 的体系结构,来自 LeCunn 等人的基于梯度的学习应用于
LeNet-5 是一个七级卷积神经网络,由 Yann LeCunn,Yoshua Bengio,Leon Bottou 和 Patrick Haffner 于 1998 年组成的团队发布,对数字进行了分类,银行将其用于识别支票上的手写数字。 这些层按以下顺序排序:
* 输入图片| 卷积层 1(ReLU)| 池化 1 |卷积层 2(ReLU)|池化 2 |全连接(ReLU)1 | 全连接 2 | 输出量
* 输入图片| 卷积层 1(ReLU)| 池化 1 |卷积层 2(ReLU)|池化 2 |全连接(ReLU)1 | 全连接 2 | 输出量
* LeNet-5 取得了令人瞩目的结果,但是处理高分辨率图像的能力需要更多的卷积层,例如在 AlexNet,VGG-Net 和 Inception 模型中。
# AlexNet 模型
AlexNet 是 LeNet 的一种改进,由 SuperVision 小组设计,该小组由 Alex Krizhevsky,Geoffrey Hinton 和 Ilya Sutskever 组成。 在 2012 年 ImageNet 大规模视觉识别挑战赛中,AlexNet 的前 5 位错误率达到 15.3%,比第二名高出 10 个百分点,创造了历史记录。
该架构使用五个卷积层,三个最大池层和最后三个完全连接的层,如下图所示。 该模型总共训练了 6000 万个参数,训练了 120 万张图像,在两个 NVIDIA GTX 580 3GB GPU 上花费了大约五到六天的时间。 下图显示了 AlexNet 模型:
该架构使用五个卷积层,三个最大池层和最后三个全连接层,如下图所示。 该模型总共训练了 6000 万个参数,训练了 120 万张图像,在两个 NVIDIA GTX 580 3GB GPU 上花费了大约五到六天的时间。 下图显示了 AlexNet 模型:
![](img/d75582a1-ff11-41b9-8162-3c52f80b141f.png)
Hinton 等人从 ImageNet 分类到深度卷积神经网络的 AlexNet 架构。 (https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf)
卷积层 1 | 最大池层 1 | 归一化层 1 | 卷积层 2 | 最大池层 2 |归一化层 2 |卷积层 3 |卷积层 4 | 卷积层 5 | 最大池层 3 |完全连接 6 |完全连接 7 |完全连接 8 | 输出量
卷积层 1 | 最大池层 1 | 归一化层 1 | 卷积层 2 | 最大池层 2 |归一化层 2 |卷积层 3 |卷积层 4 | 卷积层 5 | 最大池层 3 |全连接 6 |全连接 7 |全连接 8 | 输出量
# VGG-Net 模型
......
......@@ -348,7 +348,7 @@ end for
# 使用策略梯度的 Agent 学习 Pong
在本节中,我们将创建一个策略网络,该策略网络将使用来自 pong 环境的原始像素(来自 OpenAI 健身房的 **pong-v0**)作为输入。 策略网络是一个单独的隐藏层神经网络,它完全连接到输入层上 pong 的原始像素,还完全连接到包含单个节点的输出层,该单个节点返回了桨上升的可能性。 我要感谢 Andrej Karpathy 提出了一种使代理使用策略梯度进行学习的解决方案。 我们将尝试实现类似的方法。
在本节中,我们将创建一个策略网络,该策略网络将使用来自 pong 环境的原始像素(来自 OpenAI 健身房的 **pong-v0**)作为输入。 策略网络是一个单独的隐藏层神经网络,它全连接到输入层上 pong 的原始像素,还全连接到包含单个节点的输出层,该单个节点返回了桨上升的可能性。 我要感谢 Andrej Karpathy 提出了一种使代理使用策略梯度进行学习的解决方案。 我们将尝试实现类似的方法。
灰度大小为 80 * 80 的像素图像(我们将不使用 RGB,即 80 * 80 * 3)。 因此,我们有一个 80 * 80 的二进制网格,它告诉我们桨和球的位置,并将其作为输入输入到神经网络。 因此,神经网络将包含以下内容:
......
......@@ -334,7 +334,7 @@ Episode 10 completed with total reward 222.356805259 in 843 steps
让我们讨论游戏环境中的 Q 学习问题以及深度 Q 网络的发展。 考虑将 Q 学习应用于游戏环境,该状态将由玩家,障碍物,对手等的位置来定义,但这将是特定于游戏的,即使在我们创建时也不能在其他游戏环境中推广 一个以某种方式表示该游戏所有可能状态的 Q 表。
好吧,游戏环境有一个共同点,那就是全部由像素组成。 如果可以将像素输入可以映射到动作的模型中,则可以在所有游戏中将其推广。 DeepMind 的卷积神经网络实现具有游戏图像帧,其中输入和输出是该环境中每个可能动作的 Q 值。 卷积神经网络由三个卷积层和两个完全连接的层组成。 **卷积神经网络****CNN**)的一个元素是池化层,在此已避免。 使用池化层的主要原因是在图像中进行对象检测的情况下,其中图像中对象的位置并不重要,而在此处,在游戏框架中对象的位置非常重要时,则不然。
好吧,游戏环境有一个共同点,那就是全部由像素组成。 如果可以将像素输入可以映射到动作的模型中,则可以在所有游戏中将其推广。 DeepMind 的卷积神经网络实现具有游戏图像帧,其中输入和输出是该环境中每个可能动作的 Q 值。 卷积神经网络由三个卷积层和两个全连接层组成。 **卷积神经网络****CNN**)的一个元素是池化层,在此已避免。 使用池化层的主要原因是在图像中进行对象检测的情况下,其中图像中对象的位置并不重要,而在此处,在游戏框架中对象的位置非常重要时,则不然。
因此,在游戏环境中,**深度 Q 网络****DQN**)由连续的游戏帧组成,作为捕获动作的输入,并为游戏中所有可能的动作输出 Q 值。 游戏。 由于将深度神经网络用作 Q 函数的函数逼近器,因此此过程称为深度 Q 学习。
......@@ -350,7 +350,7 @@ Episode 10 completed with total reward 222.356805259 in 843 steps
我们的游戏环境是视频,而卷积神经网络在计算机视觉方面已经显示了最新的成果。 而且,游戏框架中物体检测的水平应该接近人类水平的能力,并且卷积神经网络从图像中学习表示,类似于人类原始视觉皮层的行为。
DeepMind 在其 DQN 网络中使用了三个卷积层和两个完全连接的层,从而在 Atari 游戏中实现了超人水平的性能,如以下流程图所示:
DeepMind 在其 DQN 网络中使用了三个卷积层和两个全连接层,从而在 Atari 游戏中实现了超人水平的性能,如以下流程图所示:
![](img/373d89a3-057c-444c-91b2-bbe4eeb5e1b4.png)
......@@ -945,7 +945,7 @@ if __name__ == "__main__":
* `epsilon`:利用或探索行为的ε贪婪条件的阈值
* `parameter_changing_pointer`:一个整数值(例如`n`),指定在每`n`次迭代之后,将主网络的参数复制到目标网络
* `memory_size`:体验回复的最大长度
* `add_layer(self,inputs,w_shape=None,b_shape=None,layer=None,activation_fn=None,c=None,isconv=False)`:在神经网络中创建层的功能
* `add_layer(self,inputs,w_shape=None,b_shape=None,layer=None,activation_fn=None,c=None,isconv=False)`:在神经网络中创建层的功能
* `weight_variable(self,w_shape,layer,c)`:创建重量参数的功能
* `bias_variable(self,b_shape,layer,c)`:创建偏置参数的功能
* `conv(self,inputs,w)`:对图像帧执行卷积运算的功能
......@@ -985,7 +985,7 @@ def __init__(self,learning_rate,gamma,n_features,n_actions,epsilon,parameter_cha
```
以下代码定义了`add_layer`函数,该函数通过提供`isconv`的布尔参数来帮助根据卷积的要求创建不同的层或完全连接的层,如果`isconv`为 true,则表示是卷积 层:
以下代码定义了`add_layer`函数,该函数通过提供`isconv`的布尔参数来帮助根据卷积的要求创建不同的层或全连接层,如果`isconv`为 true,则表示是卷积 层:
```py
def add_layer(self,inputs,w_shape=None,b_shape=None,layer=None,activation_fn=None,c=None,isconv=False):
......@@ -1045,8 +1045,8 @@ def conv(self,inputs,w):
* 两者具有相同的结构,即:
* 卷积层 1
* 卷积层 2
* 完全连接的第 1 层
* 完全连接的第 2 层
* 全连接第 1 层
* 全连接第 2 层
* 使用的激活功能:ReLU
该功能还有助于:
......
......@@ -202,7 +202,7 @@ Google DeepMind 已经开始使用 AlphaGo Zero 来了解蛋白质折叠,因
为什么我们使用残差架构而不是普通卷积架构? 其背后的原因是残留的体系结构允许梯度信号直接穿过层。 此外,即使在卷积层没有做任何有用的学习的早期阶段,重要的学习信号也会进入卷积层并直接进入其他层。 详细解释残留体系结构超出了本书的范围。
因此,我们采用板的 19 x 19 x 17 张量表示形式的输入,并将其通过残差卷积网络,从而生成特征向量。 该特征向量通过完全连接的层传递,以进行最终的特征提取,其中包含两件事:
因此,我们采用板的 19 x 19 x 17 张量表示形式的输入,并将其通过残差卷积网络,从而生成特征向量。 该特征向量通过全连接层传递,以进行最终的特征提取,其中包含两件事:
* **值表示形式**:AlphaGo 的可能性在当前棋盘位置赢得零的游戏。
* **策略向量**:AlphaGo 可以在当前位置播放的所有可能动作的概率分布。
......@@ -211,7 +211,7 @@ Google DeepMind 已经开始使用 AlphaGo Zero 来了解蛋白质折叠,因
# AlphaGo Zero 中的培训过程
接收板表示的输入,它是 19 x 19 x 17 张量。 它经过残差卷积网络,然后完全连接的层最终输出策略向量和值表示。 最初,策略向量将包含随机值,因为网络最初以随机权重开始。 在获得给定状态下所有可能动作的策略向量后,假设具有高概率的动作也可能是强力动作,它会选择一组概率很高的可能动作:
接收板表示的输入,它是 19 x 19 x 17 张量。 它经过残差卷积网络,然后全连接层最终输出策略向量和值表示。 最初,策略向量将包含随机值,因为网络最初以随机权重开始。 在获得给定状态下所有可能动作的策略向量后,假设具有高概率的动作也可能是强力动作,它会选择一组概率很高的可能动作:
![](img/31213861-ace9-4d22-806f-cff174f04933.png)
......
......@@ -153,7 +153,7 @@ YOLO 还可以预测训练中所有班级每个盒子的班级得分。 因此
对于 Image-Zooms 模型,每个区域的大小调整为 224x224,并通过 Pool5 层馈入 VGG-16,以获得特征图。 对于 Pool45-Crops 模型,全分辨率的图像通过 Pool5 层输入到 VGG-16。 合并从整个图像中提取的所有**感兴趣区域****ROI**)的特征图。
这两个用于特征提取的模型输出 *7x7* 的特征图,该图被馈送到公共块中(如以下架构所示)。 这些特征图和存储向量(前面讨论过)被馈入由两个完全连接的层组成的深层 Q 网络,每个层各有 1024 个神经元。 每个完全连接的层都具有 ReLU 激活功能,并经过辍学训练:
这两个用于特征提取的模型输出 *7x7* 的特征图,该图被馈送到公共块中(如以下架构所示)。 这些特征图和存储向量(前面讨论过)被馈入由两个全连接层组成的深层 Q 网络,每个层各有 1024 个神经元。 每个全连接层都具有 ReLU 激活功能,并经过辍学训练:
![](img/c804ff2f-7264-4eac-99a1-8aeb5a3fd5a7.png)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册