提交 efd806a4 编写于 作者: W wizardforcel

2021-01-24 23:21:32

上级 d4df4d3c
......@@ -290,19 +290,19 @@ CNN 创建的模型使用神经元的子组来识别图像的不同方面。 这
例如,当识别图片中的人脸时,前几层专注于寻找将一个特征与另一个特征分开的边缘。 接下来,后续层强调面部的某些特征,例如鼻子。 最后,最后两层使用此信息将人的整个面孔放在一起。
当遇到某些特征时激活一组神经元的想法是通过使用过滤器(内核)来实现的,过滤器(内核)是 CNN 架构的主要组成部分之一。 但是,它们不是架构中存在的唯一元素,这就是为什么在此将对 CNN 的所有组件进行简要说明的原因:
当遇到某些特征时激活一组神经元的想法是通过使用过滤器(核)来实现的,过滤器(核)是 CNN 架构的主要组成部分之一。 但是,它们不是架构中存在的唯一元素,这就是为什么在此将对 CNN 的所有组件进行简要说明的原因:
注意
在使用 CNN 时可能已经听说过的填充和跨步的概念,将在本书的后续章节中进行解释。
1. **卷积层**。在这些层中,图像(用像素矩阵表示)和过滤器之间进行卷积计算。这种计算产生一个特征作为输出,最终作为下一层的输入。
1. **卷积层**。在这些层中,图像(用像素矩阵表示)和过滤器之间进行卷积计算。这种计算产生一个特征映射作为输出,最终作为下一层的输入。
该计算对滤波器形状相同的图像矩阵进行细分,然后对这些值进行乘法运算。 然后,将乘积之和设置为该图像部分的输出,如下图所示:
该计算对过滤器形状相同的图像矩阵进行细分,然后对这些值进行乘法运算。 然后,将乘积之和设置为该图像部分的输出,如下图所示:
![Figure 2.19: Convolution operation between the image and filter ](img/B15778_02_19.jpg)
图 2.19:图像和滤镜之间的卷积运算
图 2.19:图像和过滤器之间的卷积运算
在这里,左边的矩阵是输入数据,中间的矩阵是过滤器,右边的矩阵是计算的输出。 在方框中突出显示的值所发生的计算可以在这里看到:
......@@ -316,9 +316,9 @@ CNN 创建的模型使用神经元的子组来识别图像的不同方面。 这
图 2.21:卷积运算的进一步步骤
卷积层的一个重要概念是它们是不变的,因此每个滤波器都将具有特定的函数,该函数在训练过程中不会发生变化。 例如,负责检测耳朵的过滤器将仅在整个训练过程中专门用于该函数。
卷积层的一个重要概念是它们是不变的,因此每个过滤器都将具有特定的函数,该函数在训练过程中不会发生变化。 例如,负责检测耳朵的过滤器将仅在整个训练过程中专门用于该函数。
此外,考虑到所使用的滤镜,考虑到每个 CNN 都将专注于识别图像的特定特征或一组特征,因此 CNN 通常将具有多个卷积层。 通常,在两个卷积层之间有一个池化层。
此外,考虑到所使用的过滤器,考虑到每个 CNN 都将专注于识别图像的特定特征或一组特征,因此 CNN 通常将具有多个卷积层。 通常,在两个卷积层之间有一个池化层。
2. **池化层**:尽管卷积层能够从图像中提取相关特征,但是当分析复杂的几何形状时它们的结果可能会变得非常巨大,这将使训练过程在计算能力方面成为不可能,因此发明了池化层。
......@@ -340,13 +340,13 @@ CNN 创建的模型使用神经元的子组来识别图像的不同方面。 这
图 2.23:平均池化操作
在这里,使用`3 x 3`滤镜,我们得到 2.9,这是黄色部分(左上角)中所有数字的平均值,而 3.2 是橙色部分(右上角)中所有数字的平均值。 。
在这里,使用`3 x 3`过滤器,我们得到 2.9,这是黄色部分(左上角)中所有数字的平均值,而 3.2 是橙色部分(右上角)中所有数字的平均值。 。
3. **全连接层**:最后,考虑到如果网络仅能够检测一组特征而不具有将其分类为类标签的能力,则该网络将无用,最后 CNN 使用全连接层采取前一层检测到的特征(称为特征),并输出属于类别标签的那组特征的概率,用于进行最终预测。
3. **全连接层**:最后,考虑到如果网络仅能够检测一组特征而不具有将其分类为类标签的能力,则该网络将无用,最后 CNN 使用全连接层采取前一层检测到的特征(称为特征映射),并输出属于类别标签的那组特征的概率,用于进行最终预测。
像人工神经网络一样,全连接层使用感知器根据给定的输入来计算输出。 此外,至关重要的是要提到 CNN 在架构的末尾通常具有不止一个全连接层。
通过组合所有这些概念,可以获得 CNN 的常规架构。 每个类型可以有任意数量的层,每个卷积层可以具有任意数量的滤镜(每个滤镜用于特定任务)。 此外,池化层应具有与上一个卷积层相同数量的过滤器,如下图所示:
通过组合所有这些概念,可以获得 CNN 的常规架构。 每个类型可以有任意数量的层,每个卷积层可以具有任意数量的过滤器(每个过滤器用于特定任务)。 此外,池化层应具有与上一个卷积层相同数量的过滤器,如下图所示:
![Figure 2.24: Diagram of the CNN architecture ](img/B15778_02_24.jpg)
......@@ -482,7 +482,7 @@ EDA 流程很有用,因为它有助于开发人员发现对于定义操作过
图 2.27:缺失值计数
6. 使用三个标准差作为度量来检测数据集中所有特征的离群值:
6. 使用三个标准差作为度量来检测数据集中所有特征的离群值:
```py
outliers = {}
......@@ -631,9 +631,9 @@ EDA 流程很有用,因为它有助于开发人员发现对于定义操作过
Y_shuffle = Y.sample(frac=1, random_state=0)
```
使用Pandas`sample`函数,可以对特征和目标矩阵中的元素进行混洗。 通过将`frac`设置为 1,我们确保所有实例都经过改组并在函数的输出中返回。 使用`random_state`参数,我们确保两个数据集均被混洗。
使用Pandas`sample`函数,可以对特征和目标矩阵中的元素进行混洗。 通过将`frac`设置为 1,我们确保所有实例都经过打乱并在函数的输出中返回。 使用`random_state`参数,我们确保两个数据集均被混洗。
4. 使用索引将经过改组的数据集分为特征和目标数据这三组:
4. 使用索引将经过打乱的数据集分为特征和目标数据这三组:
```py
x_train = X_shuffle.iloc[:train_end,:]
......@@ -875,7 +875,7 @@ PyTorch 的构建考虑了该领域许多开发人员的意见,其优点是可
可以看出,损失值随时间连续减小。
7. 为了测试模型,对测试集的第一个实例进行预测,并与地面真相(目标值)进行比较。
7. 为了测试模型,对测试集的第一个实例进行预测,并与真实情况(目标值)进行比较。
```py
pred = model(x_test[0])
......
......@@ -549,7 +549,7 @@ batch_size = 100
注意
即使使用种子,考虑到训练集在每个周期之前都经过了改组,该活动的确切结果也无法重现。
即使使用种子,考虑到训练集在每个周期之前都经过了打乱,该活动的确切结果也无法重现。
2. 读取先前准备的数据集,该数据集应已命名为`dccc_prepared.csv`
3. 将特征与目标分开。
......
......@@ -34,9 +34,9 @@ CNN 是处理图像数据问题时的理想架构。 但是,由于它们通常
图 4.1:展平矩阵的表示
CNN 能够捕获图像的空间相关性,因为它根据滤镜的大小将它们作为矩阵进行处理并一次分析整个图像块。 例如,使用大小为`3 x 3`的滤镜的卷积层将一次分析 9 个像素,直到它覆盖了整个图像。
CNN 能够捕获图像的空间相关性,因为它根据过滤器的大小将它们作为矩阵进行处理并一次分析整个图像块。 例如,使用大小为`3 x 3`的过滤器的卷积层将一次分析 9 个像素,直到它覆盖了整个图像。
图像的每个块都具有一组参数(权重和偏差),这些参数将取决于该组像素与整个图像的相关性,具体取决于手边的滤镜。 这意味着垂直边缘滤镜将为包含垂直边缘的图像块分配更大的权重。 据此,通过减少参数数量并通过分块分析图像,CNN 可以呈现更好的图像表示形式。
图像的每个块都具有一组参数(权重和偏差),这些参数将取决于该组像素与整个图像的相关性,具体取决于手边的过滤器。 这意味着垂直边缘过滤器将为包含垂直边缘的图像块分配更大的权重。 据此,通过减少参数数量并通过分块分析图像,CNN 可以呈现更好的图像表示形式。
## 作为输入的图像
......@@ -111,7 +111,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
## CNN 的基础
深度卷积网络是一种将图像作为输入并通过一系列**卷积层**滤镜**池化层****全连接层**(FC)的网络,以最终应用 **softmax** 激活函数,该函数将图像分类为类标签。 与 ANN 一样,这种分类形式是通过为图像赋予每个类别标签一个介于 0 和 1 之间的值来计算属于每个类别标签的图像的概率来执行的。 具有较高概率的类别标签被选择为该图像的最终预测。
深度卷积网络是一种将图像作为输入并通过一系列**卷积层**过滤器**池化层****全连接层**(FC)的网络,以最终应用 **softmax** 激活函数,该函数将图像分类为类标签。 与 ANN 一样,这种分类形式是通过为图像赋予每个类别标签一个介于 0 和 1 之间的值来计算属于每个类别标签的图像的概率来执行的。 具有较高概率的类别标签被选择为该图像的最终预测。
以下是对每个层的详细说明,以及如何在 PyTorch 中定义此类层的代码示例。
......@@ -119,11 +119,11 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
这是从图像中提取特征的第一步。 目的是通过学习图像一小部分的特征来保持附近像素之间的关系。
数学运算在该层中进行,其中给出两个输入(图像和滤波器),并获得一个输出。 如前所述,该操作包括对滤镜和与滤镜大小相同的图像部分进行卷积。 对图像的所有子部分重复此操作。
数学运算在该层中进行,其中给出两个输入(图像和过滤器),并获得一个输出。 如前所述,该操作包括对过滤器和与过滤器大小相同的图像部分进行卷积。 对图像的所有子部分重复此操作。
注意
再次访问 “第 2 章”,“神经网络 CNN 的简介”部分,以提醒您在输入和滤波器之间执行的确切计算。
再次访问 “第 2 章”,“神经网络 CNN 的简介”部分,以提醒您在输入和过滤器之间执行的确切计算。
所得矩阵的形状取决于输入的形状,其中包含大小为[`h`x`w`x`c`的图像矩阵) 大小(`f`hx`f`wx`c`)的大小将根据以下公式输出:
......@@ -131,25 +131,25 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
图 4.7:卷积层的输出高度,宽度和深度
此处,`h`表示输入图像的高度,`w`表示宽度,`c`表示深度(也称为通道),`fh``fw`是用户关于滤镜尺寸设置的值。
此处,`h`表示输入图像的高度,`w`表示宽度,`c`表示深度(也称为通道),`fh``fw`是用户关于过滤器尺寸设置的值。
下图以矩阵形式描述了此尺寸转换,其中左侧的矩阵表示彩色图像,中间的矩阵表示将应用于图像所有通道的单个滤镜,而矩阵将应用于矩阵。 右边是图像和滤镜计算的输出:
下图以矩阵形式描述了此尺寸转换,其中左侧的矩阵表示彩色图像,中间的矩阵表示将应用于图像所有通道的单个过滤器,而矩阵将应用于矩阵。 右边是图像和过滤器计算的输出:
![Figure 4.8: Dimensions of the input, filter, and output ](img/B15778_04_08.jpg)
图 4.8:输入,滤波器和输出的尺寸
图 4.8:输入,过滤器和输出的尺寸
重要的是要提到,在单个卷积层中,可以将多个滤镜应用于相同的图像,所有滤镜都具有相同的形状。 考虑到这一点,将两个滤波器应用于其输入的卷积层的输出形状就其深度而言等于两个,如下图所示:
重要的是要提到,在单个卷积层中,可以将多个过滤器应用于相同的图像,所有过滤器都具有相同的形状。 考虑到这一点,将两个过滤器应用于其输入的卷积层的输出形状就其深度而言等于两个,如下图所示:
![Figure 4.9: Convolutional layer with two filters ](img/B15778_04_09.jpg)
图 4.9:带两个滤镜的卷积层
图 4.9:带两个过滤器的卷积层
这些过滤器中的每一个将执行不同的操作,以发现图像的不同特征。 例如,在具有两个滤波器的单个卷积层中,这些操作可以是垂直边缘检测和水平边缘检测。 随着网络在层数方面的增长,过滤器将执行更复杂的操作,这些操作将利用先前检测到的特征(例如,通过使用边缘检测器的输入来检测人的轮廓)。
这些过滤器中的每一个将执行不同的操作,以发现图像的不同特征。 例如,在具有两个过滤器的单个卷积层中,这些操作可以是垂直边缘检测和水平边缘检测。 随着网络在层数方面的增长,过滤器将执行更复杂的操作,这些操作将利用先前检测到的特征(例如,通过使用边缘检测器的输入来检测人的轮廓)。
过滤器通常每层增加。 这意味着,尽管第一卷积层具有 8 个滤镜,但通常会创建第二个卷积层,使其具有两倍的数量(16),第三层使它具有两倍的数量(32),依此类推 。
过滤器通常每层增加。 这意味着,尽管第一卷积层具有 8 个过滤器,但通常会创建第二个卷积层,使其具有两倍的数量(16),第三层使它具有两倍的数量(32),依此类推 。
但是,必须指出的是,在 PyTorch 中,就像在许多其他框架中一样,您应该仅定义要使用的滤镜数量,而不是滤镜的类型(例如,垂直边缘检测器)。 每种过滤器配置(用于检测特定特征的所包含的数量)都是系统变量的一部分。
但是,必须指出的是,在 PyTorch 中,就像在许多其他框架中一样,您应该仅定义要使用的过滤器数量,而不是过滤器的类型(例如,垂直边缘检测器)。 每种过滤器配置(用于检测特定特征的所包含的数量)都是系统变量的一部分。
将向卷积层主题介绍两个附加概念,如下所示。
......@@ -167,7 +167,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
为了更好地理解填充的概念,请考虑以下情形。
`3 x 3`滤镜应用于形状为`32 x 32 x 3`的彩色图像将得到形状为`30 x 30 x 1`的矩阵。这意味着下一层的输入已缩小。 但是,通过向输入图像添加 1 的填充,输入的形状将更改为`34 x 34 x 3`,这将导致使用相同滤镜的输出为`32 x 32 x 1`
`3 x 3`过滤器应用于形状为`32 x 32 x 3`的彩色图像将得到形状为`30 x 30 x 1`的矩阵。这意味着下一层的输入已缩小。 但是,通过向输入图像添加 1 的填充,输入的形状将更改为`34 x 34 x 3`,这将导致使用相同过滤器的输出为`32 x 32 x 1`
使用填充时,以下公式可用于计算输出宽度:
......@@ -175,7 +175,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
图 4.11:使用填充应用卷积层后的输出宽度
在此,`W`表示输入矩阵的宽度,`F`表示滤波器的宽度,`P`表示填充。 可以使用相同的公式来计算输出的高度。
在此,`W`表示输入矩阵的宽度,`F`表示过滤器的宽度,`P`表示填充。 可以使用相同的公式来计算输出的高度。
要获得形状与输入相等的输出矩阵,请使用以下公式计算填充的值(考虑到我们将在下一节中定义的步幅等于 1):
......@@ -183,11 +183,11 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
图 4.12:填充数字以获得形状与输入相等的输出矩阵
请记住,输出通道(深度)的数量将始终等于已应用于输入的滤波器的数量。
请记住,输出通道(深度)的数量将始终等于已应用于输入的过滤器的数量。
**步幅**
此参数是指滤波器将在水平和垂直方向上在输入矩阵上移动的像素数。 到目前为止,我们已经看到滤镜通过图像的左上角,然后向右移一个像素,依此类推,直到它垂直和水平通过图像的所有部分为止。 此示例是步幅等于 1 的卷积层之一,这是此参数的默认配置。
此参数是指过滤器将在水平和垂直方向上在输入矩阵上移动的像素数。 到目前为止,我们已经看到过滤器通过图像的左上角,然后向右移一个像素,依此类推,直到它垂直和水平通过图像的所有部分为止。 此示例是步幅等于 1 的卷积层之一,这是此参数的默认配置。
当步幅等于 2 时,移位将改为两个像素,如下图所示:
......@@ -207,7 +207,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
图 4.14:使用步幅的卷积层的输出宽度
在此,`W`表示输入矩阵的宽度,`F`表示滤波器的宽度,`S`表示步幅。 可以使用相同的公式来计算输出的高度。
在此,`W`表示输入矩阵的宽度,`F`表示过滤器的宽度,`S`表示步幅。 可以使用相同的公式来计算输出的高度。
引入这些参数后,用于计算从卷积层得出的矩阵的输出形状(宽度和高度)的最终方程式如下:
......@@ -217,7 +217,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
每当值是**浮点型**时,都应四舍五入。 这基本上意味着输入的某些区域将被忽略,并且不会从中提取任何特征。
最后,一旦输入已通过所有滤波器,则将输出馈送到激活函数以破坏线性,这类似于传统神经网络的过程。 尽管在此步骤中可以应用多种激活函数,但是首选函数是 ReLU 函数,因为它在 CNN 中显示了出色的效果。 我们在此处获得的输出将成为后续层(通常是池化层)的输入。
最后,一旦输入已通过所有过滤器,则将输出馈送到激活函数以破坏线性,这类似于传统神经网络的过程。 尽管在此步骤中可以应用多种激活函数,但是首选函数是 ReLU 函数,因为它在 CNN 中显示了出色的效果。 我们在此处获得的输出将成为后续层(通常是池化层)的输入。
## 练习 4.01:计算卷积层的输出形状
......@@ -235,7 +235,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
Output depth = 1
```
2. 计算从卷积层派生的矩阵的输出形状,该卷积层的输入形状为`32 x 32 x 3`,10 个形状为`5 x 5 x 3`滤波器,填充为 2:
2. 计算从卷积层派生的矩阵的输出形状,该卷积层的输入形状为`32 x 32 x 3`,10 个形状为`5 x 5 x 3`过滤器,填充为 2:
```py
Output height = 32 - 5 + (2 * 2) + 1 = 32
......@@ -243,7 +243,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
Output depth = 10
```
3. 计算从卷积层派生的矩阵的输出形状,该卷积层的输入形状为`128 x 128 x 1`,五个形状为`5 x 5 x 1`滤波器,步幅为 3:
3. 计算从卷积层派生的矩阵的输出形状,该卷积层的输入形状为`128 x 128 x 1`,五个形状为`5 x 5 x 1`过滤器,步幅为 3:
```py
Output height = (128 - 5)/ 3 + 1 = 42
......@@ -251,7 +251,7 @@ CNN 可以执行不同的任务,这些任务适用于所有监督学习问题
Output depth = 5
```
4. 计算从卷积层派生的矩阵的输出形状,该卷积层的输入形状为`64 x 64 x 1`,形状为`8 x 8 x 1`滤波器,填充为 3,步幅为 3:
4. 计算从卷积层派生的矩阵的输出形状,该卷积层的输入形状为`64 x 64 x 1`,形状为`8 x 8 x 1`过滤器,填充为 3,步幅为 3:
```py
Output height = ((64 - 8 + (2 * 3)) / 3) +1 = 21.6 ≈ 21
......@@ -275,9 +275,9 @@ class CNN_network(nn.Module):
        return x
```
在定义卷积层时,从左到右传递的参数是指输入通道,输出通道(过滤器数量),核大小(过滤器大小),步幅和填充。
在定义卷积层时,从左到右传递的参数是指输入通道,输出通道(过滤器数量),核大小(过滤器大小),步幅和填充。
前面的示例由一个卷积层组成,该卷积层具有三个输入通道,18 个滤波器,每个滤波器的大小为 3,步幅和填充等于 1。
前面的示例由一个卷积层组成,该卷积层具有三个输入通道,18 个过滤器,每个过滤器的大小为 3,步幅和填充等于 1。
等效于上一个示例的另一种有效方法是将自定义模块的语法与**顺序**容器的使用结合起来,如以下代码片段所示:
......@@ -301,7 +301,7 @@ class CNN_network(nn.Module):
按照惯例,池化层是特征选择步骤的最后部分,这就是为什么池化层通常可以在卷积层之后找到的原因。 正如我们在前几章中所解释的那样,其思想是从图像的各个子部分中提取最相关的信息。 池化层的大小通常为 2,步幅等于其大小。
池化层通常将输入的高度和宽度减小一半。 考虑到要使卷积层找到图像中的所有特征,必须使用多个滤波器,并且此操作的输出可能变得太大,这意味着要考虑许多参数,这一点很重要。 池化层旨在通过保留最相关的特征来减少网络中的参数数量。 从图像的各个子部分中选择相关特征,可以通过获取最大数量或平均该区域中的数量来进行。
池化层通常将输入的高度和宽度减小一半。 考虑到要使卷积层找到图像中的所有特征,必须使用多个过滤器,并且此操作的输出可能变得太大,这意味着要考虑许多参数,这一点很重要。 池化层旨在通过保留最相关的特征来减少网络中的参数数量。 从图像的各个子部分中选择相关特征,可以通过获取最大数量或平均该区域中的数量来进行。
对于图像分类任务,最常见的是在平均池化层上使用最大池化层。 这是因为前者在保留最相关特征的任务中表现出更好的效果,而后者已被证明在诸如平滑图像等任务中表现更好。
......@@ -325,9 +325,9 @@ class CNN_network(nn.Module):
考虑以下几组层,并在所有转换结束时指定输出层的形状,并考虑`256 x 256 x 3`的输入图像:
1. 卷积层,具有 16 个大小为 3 的滤镜,步幅和填充为 1。
1. 卷积层,具有 16 个大小为 3 的过滤器,步幅和填充为 1。
2. 池化层还具有大小为 2 的过滤器以及大小为 2 的步幅。
3. 卷积层,具有八个大小为 7 的滤镜,跨度为 1,填充为 3。
3. 卷积层,具有八个大小为 7 的过滤器,跨度为 1,填充为 3。
4. 池化层,其过滤器的大小为 2,步幅也为 2。
经过每一层后,矩阵的输出大小如下:
......@@ -551,7 +551,7 @@ test_loader = torch.utils.data.DataLoader(test_data, \
5. 使用`DataLoader()`函数定义用于每组数据的批量。
6. 定义您的网络架构。 使用以下信息来这样做:
Conv1:卷积层,将彩色图像作为输入,并将其通过大小为 3 的 10 个滤镜。应将 padding 和 stride 都设置为 1。
Conv1:卷积层,将彩色图像作为输入,并将其通过大小为 3 的 10 个过滤器。应将 padding 和 stride 都设置为 1。
Conv2:一个卷积层,它将输入数据通过大小为 3 的 20 个过滤器传递。填充和跨距都应设置为 1。
......@@ -559,7 +559,7 @@ test_loader = torch.utils.data.DataLoader(test_data, \
在每个卷积层之后使用 ReLU 激活函数。
每个卷积层之后的池化层,滤镜大小和跨度为 2。
每个卷积层之后的池化层,过滤器大小和跨度为 2。
展平图像后,滤除项设置为 20%。
......@@ -686,7 +686,7 @@ test_data = datasets.CIFAR10('data', train=False, download=True, \
注意
由于每个周期的数据改组,结果将无法精确再现。 但是,您应该能够得到类似的结果。
由于每个周期的数据打乱,结果将无法精确再现。 但是,您应该能够得到类似的结果。
4. 计算测试集上所得模型的准确率。
......
......@@ -12,7 +12,7 @@
在本章中,我们将使用这种经过预训练的模型来解决计算机视觉问题,该问题由于专门用于共享图像的社交媒体渠道的普及而特别著名。 它包括执行样式迁移,以便使用一个图像的样式(颜色和纹理)以及另一个图像的内容(形状和对象)创建新图像。
每天对常规图像应用滤镜以提高其质量和吸引力,同时在社交媒体个人资料上发布时,每天执行数百万次此任务。 尽管这看起来很简单,但本章将解释这些图像编辑应用幕后发生的魔术。
每天对常规图像应用过滤器以提高其质量和吸引力,同时在社交媒体个人资料上发布时,每天执行数百万次此任务。 尽管这看起来很简单,但本章将解释这些图像编辑应用幕后发生的魔术。
注意
......@@ -251,7 +251,7 @@ transforms.Compose([transforms.Normalize((-0.5/0.25, \
要访问此源代码的 GPU 版本,请参考[这里](https://packt.live/31uctU5)。 此版本的源代码无法作为在线交互示例使用,需要通过 GPU 设置在本地运行。
这样,您已经成功加载并显示了用于样式传输的内容和样式图像。
这样,您已经成功加载并显示了用于样式迁移的内容和样式图像。
## 载入模型
......@@ -260,7 +260,7 @@ transforms.Compose([transforms.Normalize((-0.5/0.25, \
如前所述,用于执行样式迁移任务的架构是 19 层 VGG 网络的架构,也称为 VGG-19。 在`torchvision``model`子包下提​​供了预训练的模型。 在 PyTorch 中保存的模型分为两部分:
1. `vgg19.features`:这包括网络的所有卷积和池化层以及参数。 这些层负责从图像中提取特征。 有些层专门用于样式特征(例如颜色),而另一些层则专门用于内容特征(例如边缘)。
2. `vgg19.classifier`:这是指位于网络末端的线性层(也称为全连接层),包括其参数。 这些层是将图像分类为标签类别之一的层,例如,识别图像中的动物类型。
2. `vgg19.classifier`:这是指位于网络末端的线性层(也称为全连接层),包括其参数。 这些层是将图像分类为标签类别之一的层,例如,识别图像中的动物类型。
注意
......@@ -358,7 +358,7 @@ for index, layer in model._modules.items():
图 5.4:克矩阵的计算
在上图中,`A`表示具有`4x4`尺寸(高度和宽度)的输入样式图像,而`B`表示将图像通过具有五个滤镜的卷积层后的输出。 最后,`C`表示语法矩阵的计算,其中左侧的图像表示`B`的向量化版本,右侧的图像是其转置版本。 从向量化输出的乘法中,创建一个`5x5` Gram 矩阵,其值表示沿不同通道(过滤器)的样式特征方面的相似性(相关性)。
在上图中,`A`表示具有`4x4`尺寸(高度和宽度)的输入样式图像,而`B`表示将图像通过具有五个过滤器的卷积层后的输出。 最后,`C`表示语法矩阵的计算,其中左侧的图像表示`B`的向量化版本,右侧的图像是其转置版本。 从向量化输出的乘法中,创建一个`5x5` Gram 矩阵,其值表示沿不同通道(过滤器)的样式特征方面的相似性(相关性)。
这些相关性可以用于确定与图像的样式表示相关的那些特征,然后可以将其用于更改目标图像。 考虑到在五个不同的层中获得了样式特征,可以安全地假定网络能够从样式图像中检测大小特征,并考虑到必须为每个层创建一个 gram 矩阵。
......@@ -467,11 +467,11 @@ style_features = features_extractor(style_img, model, \
### 内容损失
它由一个函数组成,该函数基于给定层获得的特征来计算内容图像和目标图像之间的距离。 在 VGG-19 网络的情况下,仅根据`conv4_2`层的输出来计算内容损失。
它由一个函数组成,该函数基于给定层获得的特征映射来计算内容图像和目标图像之间的距离。 在 VGG-19 网络的情况下,仅根据`conv4_2`层的输出来计算内容损失。
内容损失函数背后的主要思想是最小化内容图像和目标图像之间的距离,以便后者在内容方面与前者高度相似。
内容损失可以计算为相关层的内容和目标图像的特征之间的均方差(`conv4_2`),可以使用以下公式实现:
内容损失可以计算为相关层的内容和目标图像的特征映射之间的均方差(`conv4_2`),可以使用以下公式实现:
![Figure 5.6: The content loss function ](img/B15778_05_06.jpg)
......@@ -481,7 +481,7 @@ style_features = features_extractor(style_img, model, \
与内容损失类似,样式损失是一项函数,可通过计算均方差来衡量样式特征(例如颜色和纹理)方面的样式与目标图像之间的距离。
与内容损失的情况相反,它不比较从不同层派生的特征图,而是比较根据样式和目标图像的特征图计算出的语法矩阵。
与内容损失的情况相反,它不比较从不同层派生的特征映射,而是比较根据样式和目标图像的特征映射计算出的语法矩阵。
必须使用循环为所有相关层(在本例中为五层)计算样式损失。 这将导致损失函数考虑来自两个图像的简单和复杂样式表示。
......@@ -512,7 +512,7 @@ style_features = features_extractor(style_img, model, \
与以前的神经网络的优化一样,以下是每次迭代中可以观察到的步骤:
1. 从目标图像获取内容和样式方面的特征。 在初始迭代中,此图像将是内容图像的精确副本。
2. 计算内容损失。 这是通过比较内容和目标图像的内容特征来完成的。
2. 计算内容损失。 这是通过比较内容和目标图像的内容特征映射来完成的。
3. 计算所有相关层的平均样式损失。 这是通过比较样式图像和目标图像所有层的 gram 矩阵来实现的。
4. 计算总损失。
5. 计算总损失函数相对于目标图像参数(权重和偏差)的偏导数。
......@@ -641,7 +641,7 @@ style_features = features_extractor(style_img, model, \
4. 为了能够显示图像,请定义一组新的转换,以恢复图像的规范化并将张量转换为 PIL 图像。
5. 创建一个函数(`tensor2image`),该函数能够对张量执行先前的转换。 调用两个图像的函数并绘制结果。
6. 加载 VGG-19 模型。
7. 创建一个字典,将相关层(键)的索引映射到名称(值)。 然后,创建一个函数以提取相关层的特征。 使用它们提取两个输入图像的特征。
7. 创建一个字典,将相关层(键)的索引映射到名称(值)。 然后,创建一个函数以提取相关层的特征映射。 使用它们提取两个输入图像的特征。
8. 计算样式特征的克矩阵。 另外,创建初始目标图像。
9. 设置不同样式层的权重以及内容和样式损失的权重。
0. 运行模型 500 次迭代。在开始训练模型之前,定义 Adam 优化算法,以 0.001 作为学习率。
......
......@@ -269,7 +269,7 @@
        print(i, loss.item())
```
6. 通过对测试集的第一个实例进行预测,并与地面真相进行比较来测试你的模型。
6. 通过对测试集的第一个实例进行预测,并与真实情况进行比较来测试你的模型。
```py
pred = model(x_test[0])
......@@ -451,7 +451,7 @@
plt.show()
```
考虑到改组训练数据可能会得出略有不同的结果,结果图应与此处显示的图相似,尽管有所不同。
考虑到打乱训练数据可能会得出略有不同的结果,结果图应与此处显示的图相似,尽管有所不同。
![Figure 3.15: A plot displaying the training and validation losses ](img/B15778_03_15.jpg)
......@@ -871,7 +871,7 @@
6. 定义你的网络架构。使用以下信息进行定义。
Conv1:卷积层,将彩色图像作为输入,并将其通过大小为 3 的 10 个滤镜。应将填充和跨步都设置为 1。
Conv1:卷积层,将彩色图像作为输入,并将其通过大小为 3 的 10 个过滤器。应将填充和跨步都设置为 1。
Conv2:一个卷积层,它将输入数据通过大小为 3 的 20 个过滤器传递。填充和跨距都应设置为 1。
......@@ -879,7 +879,7 @@
在每个卷积层之后使用 ReLU 激活函数。
在每个卷积层之后使用池化层,滤镜大小和步幅为 2。
在每个卷积层之后使用池化层,过滤器大小和步幅为 2。
展平图像后,使用掉落项设置为 20%。
......@@ -1200,7 +1200,7 @@
要完成此活动,按照以下步骤,除了在网络架构中添加一些层之外,不会更改任何代码。
2. 将批量归一化添加到每个卷积层,以及第一个全连接层。
2. 将批量归一化添加到每个卷积层,以及第一个全连接层。
网络的最终架构应如下:
......@@ -1372,7 +1372,7 @@
    param.requires_grad_(False)
```
7. 创建一个字典,用于将相关层的索引(键)映射到名称(值)。然后,创建一个函数来提取相关层的特征。用它们来提取两个输入图像的特征。
7. 创建一个字典,用于将相关层的索引(键)映射到名称(值)。然后,创建一个函数来提取相关层的特征映射。用它们来提取两个输入图像的特征。
以下函数应为每个相关层提取给定图像的特征:
......
......@@ -50,7 +50,7 @@
# 机器学习–历史概述
机器学习是一个程序,在给定任务(损失函数)的情况下,可以通过经验(训练数据)进行学习。 凭着经验,该程序将学会按照给定的标准执行给定的任务。 在 1960 年代,机器学习主要集中于创建不同形式的数据预处理过滤器。 随着图像滤镜的引入,重点逐渐转向计算机视觉,并在 1990 年代和 2000 年代在这一领域进行了重大研究。 在开发了传统机器学习算法方面的一些稳定性之后,研究人员转向了概率领域,因为随着高维数据的引入,它变得更有希望。 深度学习在 2012 年赢得 ImageNet 挑战赛时便开始蓬勃发展,并且自此在数据科学领域中发挥了重要作用。
机器学习是一个程序,在给定任务(损失函数)的情况下,可以通过经验(训练数据)进行学习。 凭着经验,该程序将学会按照给定的标准执行给定的任务。 在 1960 年代,机器学习主要集中于创建不同形式的数据预处理过滤器。 随着图像过滤器的引入,重点逐渐转向计算机视觉,并在 1990 年代和 2000 年代在这一领域进行了重大研究。 在开发了传统机器学习算法方面的一些稳定性之后,研究人员转向了概率领域,因为随着高维数据的引入,它变得更有希望。 深度学习在 2012 年赢得 ImageNet 挑战赛时便开始蓬勃发展,并且自此在数据科学领域中发挥了重要作用。
机器学习可以分为两类:
......
......@@ -99,7 +99,7 @@
![](img/67555406-abd0-4471-b5e1-deb9c87c2813.jpg)
我们还需要为相似的数据点(`y = 1`)和不相似的数据点(`y = 0`)相应地创建标签; 然后,将每一对馈入连体体系。 在层的最后,连体网络使用损失函数的区分形式来学习各层之间的区分特征。 通常,对于连体网络,我们仅使用两种类型的函数-对比损失函数和三重损失函数。 我们将在下一节中详细了解这些内容。
我们还需要为相似的数据点(`y = 1`)和不相似的数据点(`y = 0`)相应地创建标签; 然后,将每一对馈入连体体系。 在层的最后,连体网络使用损失函数的微分形式来学习各层之间的微分特征。 通常,对于连体网络,我们仅使用两种类型的函数-对比损失函数和三重损失函数。 我们将在下一节中详细了解这些内容。
# 对比损失函数
......@@ -205,7 +205,7 @@
![](img/725b5feb-44c8-43ed-8a13-b4c530b590e8.png)
它们各自的核值如下:
它们各自的核值如下:
![](img/8c500245-cdfc-485c-8f8b-16692f891db5.png)
......@@ -251,7 +251,7 @@ VGG16 和 Inception Net 是深度学习架构,它们在 ImageNet 数据集上
2. 获取支持集后,它会通过标准特征提取层(`g`),例如 VGG 或 Inception。
3. 在提取支持集(`S`)的嵌入(`g`层的输出)之后,将它们放入双向 LSTM 架构中。 这有助于模型学习支持集中存在的标签的概率分布。
4. 与训练集类似,查询图像(即测试图像)的全上下文嵌入提取也经历了组合的双向 LSTM 架构,同时从`g(x[i)`获得了贡献,从而映射到相同的嵌入空间。
5. 从这两种架构获得输出后,这些输出将通过 softmax 层(也称为注意核步骤`a(h[k-1], g(x[i]))`)传递。
5. 从这两种架构获得输出后,这些输出将通过 softmax 层(也称为注意核步骤`a(h[k-1], g(x[i]))`)传递。
6. 然后,从`g(x[i])``f'(x)`获得的输出用于检查查询图像属于哪个类别:
......
......@@ -121,7 +121,7 @@ MANN 的读取操作与 NTM 的读取操作非常相似,唯一的区别是此
* **元学习器**:元学习器获得有关不同任务的一般知识。 在元网络的情况下,这是一个嵌入函数,用于比较两个不同数据点的特征。
* **基础学习器**:基础学习器尝试学习目标任务(任务目标网络可以是简单的分类器)。
元级学习器的目标是获得有关不同任务的一般知识。 然后可以将知识移到基础级学习器,以在单个任务的上下文中提供概括。
元级学习器的目标是获得有关不同任务的一般知识。 然后可以将知识移到基础级学习器,以在单个任务的上下文中提供概括。
如所讨论的,元网络学习权重的两种形式:慢权重和快权重。 要为元学习器(嵌入函数)和基础学习器(分类模型)两者学习这些权重,我们需要两个不同的网络。 这使得元网络成为迄今为止我们在本书中讨论过的最复杂的网络之一。 简而言之,元网络由四种类型的神经网络组成,它们各自的参数要训练。 在下一节中,我们将遍历元网络中存在的每个网络,并了解其架构。
......@@ -208,7 +208,7 @@ MANN 的读取操作与 NTM 的读取操作非常相似,唯一的区别是此
在选择嵌入网络时,元网络使用 LSTM 架构。 如我们所见,匹配网络和 LSTM 元学习器也遵循相同的策略,分别用于提取数据和元信息的上下文嵌入。 这是因为 LSTM 架构倾向于记住历史,这使得元学习器的目标能够跨任务提取重要信息。
例如,假设我们正在训练我们的网络以完成多种任务,例如猫的品种分类和狗的品种分类。 当我们使用 LSTM 元学习器进行训练时,它会学习例如狗品种分类中重更新的策略,并使用这些学习到的信息以较少的步骤和较少的数据来优化其用于猫品种分类的操作。 使用元网络在 Omniglot 数据集上达到了 95.92% 的准确率,而人类的准确率仅为 95.5%,因此,元网络被认为是最新模型之一。
例如,假设我们正在训练我们的网络以完成多种任务,例如猫的品种分类和狗的品种分类。 当我们使用 LSTM 元学习器进行训练时,它会学习例如狗品种分类中重更新的策略,并使用这些学习到的信息以较少的步骤和较少的数据来优化其用于猫品种分类的操作。 使用元网络在 Omniglot 数据集上达到了 95.92% 的准确率,而人类的准确率仅为 95.5%,因此,元网络被认为是最新模型之一。
# 编码练习
......
......@@ -541,7 +541,7 @@ plt.savefig('daml-sine.png')
要求解任何方程,通常我们可以使用很多方法。 同样,为了进行优化(学习神经网络的参数),许多研究人员也公开了许多方法,但是事实证明梯度下降是一种适用于每种情况的通用方法。 如果我们希望处理特定类型的神经网络问题,那么最好探索可能适合我们任务的不同优化技术。
在这一章中,我们研究了两种最著名的一次学习优化方法:MAML 和 LSTM 元学习器。 我们了解了 MAML 如何通过优化我们的初始参数设置来解决一次学习问题,从而在几个数据点上进行一个或几个梯度下降步骤可以导致更好的概括。 我们还探讨了 LSTM 元学习器对如何训练 LSTM 单元作为元学习器以预测基础学习器重更新的见解。
在这一章中,我们研究了两种最著名的一次学习优化方法:MAML 和 LSTM 元学习器。 我们了解了 MAML 如何通过优化我们的初始参数设置来解决一次学习问题,从而在几个数据点上进行一个或几个梯度下降步骤可以导致更好的概括。 我们还探讨了 LSTM 元学习器对如何训练 LSTM 单元作为元学习器以预测基础学习器重更新的见解。
在下一章中,我们将探讨一种著名的 ML 方法贝叶斯学习。 我们将通过用概率模型表示对象类别来观察几个贝叶斯学习框架的发展。 我们将对判别式`K`-次学习和贝叶斯程序学习及其在现实世界中的应用进行恰当的解释。
......
......@@ -20,7 +20,7 @@
# 小样本领域中的对象检测
[《RepMet:用于分类和几次对象检测的基于代表的度量学习》](https://arxiv.org/abs/1806.04728)是一种小样本学习对象检测方法。 在本文中,作者提出了一种用于对象区域议的特征金字塔网络的变体,并且在其顶部,他们添加了基于度量的分类器,该分类器根据与学习的类代表的距离对建议的区域进行分类。 他们还通过在 ImageNet 数据集上建立了用于少发物体检测任务的基准,为研究界做出了贡献。
[《RepMet:用于分类和几次对象检测的基于代表的度量学习》](https://arxiv.org/abs/1806.04728)是一种小样本学习对象检测方法。 在本文中,作者提出了一种用于对象区域议的特征金字塔网络的变体,并且在其顶部,他们添加了基于度量的分类器,该分类器根据与学习的类代表的距离对建议的区域进行分类。 他们还通过在 ImageNet 数据集上建立了用于少发物体检测任务的基准,为研究界做出了贡献。
同样,[《具有共同注意和共同激励的一次目标检测》](https://arxiv.org/abs/1911.12529)也可以使用传统的视觉方法,在建议的区域基础上进行过滤。 在这项工作中,作者假设将提供目标图像和查询图像。 例如,如果我们要检测笔架,则目标图像将是笔架,而查询图像将是桌子上的笔架。 在这种方法中,我们首先从目标图像中提取有关对象的空间信息,然后从查询图像中提取上下文对象。 上下文和空间信息在确定对象方面起着重要作用。 例如,如果有一张桌子,出现笔架的可能性就会增加。 这类似于人类使用上下文学习的方式。 该模型还通过将输入传递给注意力模型来利用上下文的帮助。
......
......@@ -184,7 +184,7 @@ ReLU 是非常简单的非线性函数,当`x <= 0`,返回`y = 0`;当`x > 0
## 神经网络如何学习?
使用神经网络从数据中学习的行为比使用基本回归学习时的行为稍微复杂一些。 尽管我们仍然像以前一样使用梯度下降,但是我们需要分的实际损失函数变得更加复杂。 在没有激活函数的单层神经网络中,我们很容易计算损失函数的导数,因为很容易看到随着我们改变每个参数损失函数如何变化。 但是,在具有激活函数的多层神经网络中,这更加复杂。
使用神经网络从数据中学习的行为比使用基本回归学习时的行为稍微复杂一些。 尽管我们仍然像以前一样使用梯度下降,但是我们需要分的实际损失函数变得更加复杂。 在没有激活函数的单层神经网络中,我们很容易计算损失函数的导数,因为很容易看到随着我们改变每个参数损失函数如何变化。 但是,在具有激活函数的多层神经网络中,这更加复杂。
我们必须首先执行**正向传播**,即,其中,使用模型的当前状态,我们计算`y`的预测值,并根据`y`的真实值来评估它,以便获得损失的度量。 利用这一损失,我们可以在网络中向后移动,计算网络中每个参数的梯度。 这使我们可以知道向哪个方向更新参数,以便使可以更接近损失最小的点。 这被称为**反向传播**。 我们可以使用**链式规则**计算相对于每个参数的损失函数的导数:
......
......@@ -41,7 +41,7 @@ CNN 背后的基本概念是卷积。 **卷积**本质上是一个滑动窗口
图 6.2 –实际的卷积
左侧是正在处理的图像,而顶部则是希望应用的卷积核。 对于图像中的每个`3x3`块,我们将其乘以核,以在底部处获得卷积矩阵。 然后,我们对卷积矩阵求和(或取平均值),以获得初始图像中该`3x3`块的单个输出值。 请注意,在我们的`5x5`初始图像中,我们可以覆盖 9 个可能的`3x3`块。 当我们对初始图像中的每个`3x3`块应用此卷积过程时,剩下的最终处理卷积为`3x3`
左侧是正在处理的图像,而顶部则是希望应用的卷积核。 对于图像中的每个`3x3`块,我们将其乘以核,以在底部处获得卷积矩阵。 然后,我们对卷积矩阵求和(或取平均值),以获得初始图像中该`3x3`块的单个输出值。 请注意,在我们的`5x5`初始图像中,我们可以覆盖 9 个可能的`3x3`块。 当我们对初始图像中的每个`3x3`块应用此卷积过程时,剩下的最终处理卷积为`3x3`
在大图像中(对于 NLP,则为复杂的句子),我们还需要实现池化层。 在我们前面的示例中,将`3x3`卷积应用于`5x5`图像会产生`3x3`输出。 但是,如果将`3x3`卷积应用于`100x100`像素的图像,则只会将输出降低到`98x98`。 这还不足以降低图像的尺寸,不足以有效地执行深度学习(因为我们必须在每个卷积层学习`98x98`参数)。 因此,我们应用池化层以进一步减小该层的尺寸。
......@@ -53,7 +53,7 @@ CNN 背后的基本概念是卷积。 **卷积**本质上是一个滑动窗口
这些池化层已被证明可以有效降低数据的维数,同时仍保留卷积层中的许多基本信息。
卷积和池化层的这种结合本质上是 CNN 从图像中学习的方式。 我们可以看到,通过应用许多这些卷积过程(也称为**卷积层**),我们能够捕获有关任何给定像素与其相邻像素的关系的信息。 在 CNN 中,我们旨在学习的参数是卷积核本身的值。 这意味着我们的模型可以有效地学习如何对图像进行卷积,以便能够提取进行分类所需的必要信息。
卷积和池化层的这种结合本质上是 CNN 从图像中学习的方式。 我们可以看到,通过应用许多这些卷积过程(也称为**卷积层**),我们能够捕获有关任何给定像素与其相邻像素的关系的信息。 在 CNN 中,我们旨在学习的参数是卷积核本身的值。 这意味着我们的模型可以有效地学习如何对图像进行卷积,以便能够提取进行分类所需的必要信息。
在这种情况下,使用卷积有两个主要的优势。 首先,我们能够将一系列低级特征组合成高级特征; 也就是说,我们初始图像上的`3x3`色块是组成的单个值。 这实际上是减少特征的一种形式,仅允许我们从图像中提取相关信息。 使用卷积的另一个优点是它使我们的模型位置不变。 在我们的数字检测器示例中,我们不在乎数字是否出现在图像的右侧或左侧; 我们只是希望能够检测到它。 由于我们的卷积会检测图像中的特定图案(即边缘),因此我们的模型位置不变,因为从理论上讲,无论这些卷积出现在图像中的哪个位置,相同的特征都将被拾取。
......@@ -73,7 +73,7 @@ CNN 背后的基本概念是卷积。 **卷积**本质上是一个滑动窗口
图 6.4 –词向量
然后,我们在矩阵上应用(`2 x n`)卷积(其中`n`是我们字向量的长度;在这种情况下,`n = 5`) 。 我们可以使用(`2 x n`滤波器对四个不同时间进行卷积,该滤波器可减少为四个输出。 您会注意到,这类似于二元语法模型,在一个五字句子中有四个可能的二元语法:
然后,我们在矩阵上应用(`2 x n`)卷积(其中`n`是我们字向量的长度;在这种情况下,`n = 5`) 。 我们可以使用(`2 x n`过滤器对四个不同时间进行卷积,该过滤器可减少为四个输出。 您会注意到,这类似于二元语法模型,在一个五字句子中有四个可能的二元语法:
![Figure 6.5 – Convolving word vectors into bi-grams ](img/B12365_06_05.jpg)
......@@ -299,9 +299,9 @@ train_iterator, valid_iterator = data.BucketIterator.splits(
     kernel_size = (3, embedding_dim))
```
在此,滤波器尺寸分别为`2`和`3`。 但是,在单个函数中执行此操作效率更高。 此外,如果我们向函数传递不同的过滤器大小,则将自动生成我们的层,而不是每次添加新层时都必须手动定义每个层。
在此,过滤器尺寸分别为`2`和`3`。 但是,在单个函数中执行此操作效率更高。 此外,如果我们向函数传递不同的过滤器大小,则将自动生成我们的层,而不是每次添加新层时都必须手动定义每个层。
我们还将`out_channels`值定义为我们希望训练的过滤器数;`kernel_size`将包含我们嵌入的长度。 因此,我们可以将`ModuleList`函数的长度传递给我们希望训练的滤波器长度以及每个滤波器的数量,它将自动生成卷积层。 该卷积层如何查找给定变量集的示例如下:
我们还将`out_channels`值定义为我们希望训练的过滤器数;`kernel_size`将包含我们嵌入的长度。 因此,我们可以将`ModuleList`函数的长度传递给我们希望训练的过滤器长度以及每个过滤器的数量,它将自动生成卷积层。 该卷积层如何查找给定变量集的示例如下:
![Figure 6.15 – Convolution layer looking for variables ](img/B12365_06_015.jpg)
......@@ -345,7 +345,7 @@ model = CNN(input_dimensions, embedding_dimensions, number_of_filters, filter_si
输入维度将始终是词汇量的长度,而输出维度将是我们希望预测的类的数量。 在这里,我们从六个不同的类别进行预测,因此我们的输出向量的长度为`6`。 我们的嵌入维数是 GLoVe 向量的长度(在这种情况下为`200`)。 填充索引可以从我们的词汇表中手动获取。
可以手动调整接下来的三个超参数,因此您不妨尝试选择不同的值,以了解这如何影响网络的最终输出。 我们传递了一个过滤器大小列表,以便我们的模型将使用大小为`2`,`3`和`4`的卷积训练卷积层。 我们将针对每种滤镜尺寸训练 100 个滤镜,因此总共将有 300 个滤镜。 我们还为我们的网络定义了 50% 的丢弃率,以确保其充分正规化。 如果模型似乎容易过拟合或过拟合,则可以升高/降低此值。 一般的经验法则是,如果模型欠拟合,则尝试降低丢弃率;如果模型过拟合,则尝试提高丢弃率。
可以手动调整接下来的三个超参数,因此您不妨尝试选择不同的值,以了解这如何影响网络的最终输出。 我们传递了一个过滤器大小列表,以便我们的模型将使用大小为`2`,`3`和`4`的卷积训练卷积层。 我们将针对每种过滤器尺寸训练 100 个过滤器,因此总共将有 300 个过滤器。 我们还为我们的网络定义了 50% 的丢弃率,以确保其充分正规化。 如果模型似乎容易过拟合或过拟合,则可以升高/降低此值。 一般的经验法则是,如果模型欠拟合,则尝试降低丢弃率;如果模型过拟合,则尝试提高丢弃率。
初始化模型后,我们需要将权重加载到嵌入层中。 可以很容易地完成以下操作:
......
......@@ -430,7 +430,7 @@ tensor([[2., 2., 2.],
**梯度下降**是一种优化算法,用于通过在梯度的负值所定义的最陡下降方向上反复移动来使函数最小化。 我们在训练模型时会使用它,以使损失最小化。 它用于查找使成本或损失函数最小化的函数参数值(机器学习中的系数或权重)。
那么什么是梯度呢? 梯度度量的是当输入改变很小的时候给定函数的输出有多少变化,这与微积分中的导数概念相同。 梯度会计算所有权重相对于误差变化的变化。 梯度是函数的斜率。 较高的坡度意味着坡度更陡,并且模型可以更快地学习。 梯度指向最陡的倾斜方向。 PyTorch 中的`Autograd`模块在 PyTorch 中执行所有梯度计算。 它是自动差异化的核心 Torch 包。 它使用基于磁带的系统进行自动分。 在前进阶段,`Autograd`磁带将记住它执行的所有操作,而在倒退阶段,它将重放它们。
那么什么是梯度呢? 梯度度量的是当输入改变很小的时候给定函数的输出有多少变化,这与微积分中的导数概念相同。 梯度会计算所有权重相对于误差变化的变化。 梯度是函数的斜率。 较高的坡度意味着坡度更陡,并且模型可以更快地学习。 梯度指向最陡的倾斜方向。 PyTorch 中的`Autograd`模块在 PyTorch 中执行所有梯度计算。 它是自动差异化的核心 Torch 包。 它使用基于磁带的系统进行自动分。 在前进阶段,`Autograd`磁带将记住它执行的所有操作,而在倒退阶段,它将重放它们。
# 操作步骤
......
......@@ -138,7 +138,7 @@ pip install torchvision
准备好转换后,我们定义了合适的批量大小。 较高的批量大小意味着该模型具有较少的训练步骤并且学习速度更快,而较高的批量大小会导致对内存的高要求。
TorchVision 的`datasets`模块附带了许多受欢迎的数据集; 如果机器上没有它,它将为您下载,传递转换并将数据转换为所需的格式以供模型训练。 在我们的案例中,数据集带有训练和测试集,并相应地加载它们。 我们使用`torch.utils.data.DataLoader`将处理后的数据分批加载,并进行其他操作,例如改组和加载到正确的设备(CPU 或 GPU)。
TorchVision 的`datasets`模块附带了许多受欢迎的数据集; 如果机器上没有它,它将为您下载,传递转换并将数据转换为所需的格式以供模型训练。 在我们的案例中,数据集带有训练和测试集,并相应地加载它们。 我们使用`torch.utils.data.DataLoader`将处理后的数据分批加载,并进行其他操作,例如打乱和加载到正确的设备(CPU 或 GPU)。
我们可以用任何名称定义模型类,但是重要的是它是`nn.Module`的子类并具有`super().__init__()`,该类为模型提供了许多有用的方法和属性,并保留了架构的知识。
......
......@@ -14,7 +14,7 @@ CNN 是一种特殊的网络,可以将图像作为张量接收。 彩色图像
![](img/ae0349d2-67ef-4b56-b530-7c349847db18.png)
CNN 使用过滤器从输入图像中拾取特征; 具有足够数量的滤镜的 CNN 可以检测图像中的各种特征。 随着我们越来越向后一层移动,这些滤镜在检测复杂特征方面变得越来越复杂。 卷积网络使用这些过滤器并逐一映射它们以创建特征出现的映射。
CNN 使用过滤器从输入图像中拾取特征; 具有足够数量的过滤器的 CNN 可以检测图像中的各种特征。 随着我们越来越向后一层移动,这些过滤器在检测复杂特征方面变得越来越复杂。 卷积网络使用这些过滤器并逐一映射它们以创建特征出现的映射。
在本章中,我们将介绍以下秘籍:
......@@ -32,12 +32,12 @@ CNN 使用过滤器从输入图像中拾取特征; 具有足够数量的滤镜
# 探索卷积
卷积是 CNN 中的一个组成部分。 它们被定义为 CNN 中的一层。 在卷积层中,我们将滤镜矩阵从左到右,从上到下在整个图像矩阵上滑动,然后取滤镜的点积,此斑块将滤镜的尺寸跨过图像通道。 如果两个矩阵在相同位置具有较高的值,则点积的输出将较高,反之亦然。 点积的输出是标量值,该标量值标识图像中的像素模式和由滤波器表示的像素模式之间的相关性。 不同的滤镜会以不同的复杂度从图像中检测不同的特征。
卷积是 CNN 中的一个组成部分。 它们被定义为 CNN 中的一层。 在卷积层中,我们将过滤器矩阵从左到右,从上到下在整个图像矩阵上滑动,然后取过滤器的点积,此斑块将过滤器的尺寸跨过图像通道。 如果两个矩阵在相同位置具有较高的值,则点积的输出将较高,反之亦然。 点积的输出是标量值,该标量值标识图像中的像素模式和由过滤器表示的像素模式之间的相关性。 不同的过滤器会以不同的复杂度从图像中检测不同的特征。
我们需要了解 CNN 的另外两个关键元素,如下所示:
* **跨步**:这是在图像的下一个小块上使用滤镜应用卷积网络之前,我们水平和垂直移动的像素数。
* **填充**:这是我们在卷积时应用于图像边缘的策略,具体取决于我们是在卷积后要保持张量的尺寸不变还是仅在滤镜适合的情况下对输入图像应用卷积。 如果要保持尺寸不变,则需要对边缘进行零填充,以使原始尺寸在卷积后与输出匹配。 这称为**相同填充**。 但是,如果我们不想保留原始尺寸,则会将过滤器无法完全容纳的位置截断,这称为**有效填充**
* **跨步**:这是在图像的下一个小块上使用过滤器应用卷积网络之前,我们水平和垂直移动的像素数。
* **填充**:这是我们在卷积时应用于图像边缘的策略,具体取决于我们是在卷积后要保持张量的尺寸不变还是仅在过滤器适合的情况下对输入图像应用卷积。 如果要保持尺寸不变,则需要对边缘进行零填充,以使原始尺寸在卷积后与输出匹配。 这称为**相同填充**。 但是,如果我们不想保留原始尺寸,则会将过滤器无法完全容纳的位置截断,这称为**有效填充**
这是这两个填充的示意图:
......@@ -84,7 +84,7 @@ Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1))
Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
```
4. 然后,我们可以使用以下代码创建一个非平方核(过滤器):
4. 然后,我们可以使用以下代码创建一个非平方核(过滤器):
```py
>>nn.Conv2d(3, 16, (3,4), padding=1)
......@@ -124,9 +124,9 @@ Conv2d(3, 16, kernel_size=(3, 4), stride=(3, 3), padding=(1, 2))
# 工作原理
在本秘籍中,我们研究了创建 2D 卷积的多种方法,其中第一个参数是给定输入图像中的通道数,对于彩色图像,通道数将为`3`,对于灰度图像将为`1`。 第二个参数是输出通道的数量,换句话说,就是我们要从给定层获得的滤波器的数量。 第三个参数是内核大小(即内核大小),或者是要使用滤镜卷积的图像的补丁大小。
在本秘籍中,我们研究了创建 2D 卷积的多种方法,其中第一个参数是给定输入图像中的通道数,对于彩色图像,通道数将为`3`,对于灰度图像将为`1`。 第二个参数是输出通道的数量,换句话说,就是我们要从给定层获得的过滤器的数量。 第三个参数是核大小(即核大小),或者是要使用过滤器卷积的图像的补丁大小。
然后,我们创建了一个`Con2d`对象,并将输入传递到 2D 卷积层以获取输出。 使用`nn.Conv2d(3, 16, 3)`,我们创建了一个卷积层,该卷积层接受 3 个通道的输入并输出 16 个通道。 该层的大小为`3 x 3`的正方形核,其高度和宽度的默认跨度为 1。 我们可以使用`padding`参数添加填充,该参数可以具有整数或元组值。 在这里,整数值将为高度和宽度创建相同的填充,而元组值将为高度和宽度创建不同的填充-这对于核大小和跨度都是正确的。
然后,我们创建了一个`Con2d`对象,并将输入传递到 2D 卷积层以获取输出。 使用`nn.Conv2d(3, 16, 3)`,我们创建了一个卷积层,该卷积层接受 3 个通道的输入并输出 16 个通道。 该层的大小为`3 x 3`的正方形核,其高度和宽度的默认跨度为 1。 我们可以使用`padding`参数添加填充,该参数可以具有整数或元组值。 在这里,整数值将为高度和宽度创建相同的填充,而元组值将为高度和宽度创建不同的填充-这对于核大小和跨度都是正确的。
# 更多
......@@ -146,7 +146,7 @@ Conv2d(3, 16, kernel_size=(3, 4), stride=(3, 3), padding=(1, 2))
这是使用池化层的主要原因:
* **减少计算数量**:通过减少输入的空间尺寸而不会损失滤波器,我们可以获得更好的计算表现,因此我们减少了训练所需的时间以及计算资源。
* **减少计算数量**:通过减少输入的空间尺寸而不会损失过滤器,我们可以获得更好的计算表现,因此我们减少了训练所需的时间以及计算资源。
* **防止过拟合**:随着空间尺寸的减小,我们减少了模型具有的参数数量,从而降低了模型的复杂性并有助于我们更好地概括。
* **位置不变性**:这使 CNN 可以捕获图像中的特征,而不管特征在给定图像中的位置。 假设我们正在尝试建立一个分类器来检测芒果。 芒果位于图像的中心,左上角,右下角还是图像中的任何位置都没关系-需要对其进行检测。 池化层可以帮助我们。
......@@ -253,7 +253,7 @@ Conv2d(3, 16, kernel_size=(3, 4), stride=(3, 3), padding=(1, 2))
# 工作原理
在前面的代码中,我们研究了一个张量的示例,以了解实际的池化层。 我们使用大小为`3 x 3`的方形核。池的第一个应用发生在`[0,0,0]``[0,3,3]`的面片上。 由于步幅为 1,因此下一个要操作的音色为`[0,0,1]``[0,3,4]`。 一旦碰到水平端,就对下面的张量进行运算。 `nn.MaxPool2d(3, stride=1)``nn.AvgPool2d(3, stride=1)`都创建了大小为`3x3`的最大和平均池方核,步幅为`1`,将其应用于随机张量`a`
在前面的代码中,我们研究了一个张量的示例,以了解实际的池化层。 我们使用大小为`3 x 3`的方形核。池的第一个应用发生在`[0,0,0]``[0,3,3]`的面片上。 由于步幅为 1,因此下一个要操作的音色为`[0,0,1]``[0,3,4]`。 一旦碰到水平端,就对下面的张量进行运算。 `nn.MaxPool2d(3, stride=1)``nn.AvgPool2d(3, stride=1)`都创建了大小为`3x3`的最大和平均池方核,步幅为`1`,将其应用于随机张量`a`
# 更多
......@@ -676,7 +676,7 @@ CNN(
# 工作原理
此秘籍的工作方式与第 2 章,“处理神经网络”时非常相似,当我们研究一个全连接神经网络时。 我们从`__init__()`方法和父类的构造器开始,定义了从 PyTorch 中的`nn.Module`继承的 CNN 类。 之后,我们通过传入与每一层相关的参数来定义 CNN 中的各个层。 对于我们的第一卷积层,输入通道的数量为 3(RGB),输出通道的数量定义为 16,其平方核大小为 3。第二卷积层采用上一层的张量,并具有 16 个输入通道和 32 个输出通道,内核尺寸为`3 x 3`。类似地,第三卷积层具有 32 个输入通道和 64 个输出通道,内核尺寸为`3 x 3`。 我们还需要一个最大池化层,并使用 2 的内核大小和 2 的步幅。我们使用`.view()`将张量的三个维度展平为一个维度,以便可以将其传递到全连接网络中。 `view`函数中的 -1 通过确保`view`函数之前和之后的元素数量保持相同(在本例中为批量大小)来确保将正确的尺寸自动分配给该尺寸。
此秘籍的工作方式与第 2 章,“处理神经网络”时非常相似,当我们研究一个全连接神经网络时。 我们从`__init__()`方法和父类的构造器开始,定义了从 PyTorch 中的`nn.Module`继承的 CNN 类。 之后,我们通过传入与每一层相关的参数来定义 CNN 中的各个层。 对于我们的第一卷积层,输入通道的数量为 3(RGB),输出通道的数量定义为 16,其平方核大小为 3。第二卷积层采用上一层的张量,并具有 16 个输入通道和 32 个输出通道,核尺寸为`3 x 3`。类似地,第三卷积层具有 32 个输入通道和 64 个输出通道,核尺寸为`3 x 3`。 我们还需要一个最大池化层,并使用 2 的核大小和 2 的步幅。我们使用`.view()`将张量的三个维度展平为一个维度,以便可以将其传递到全连接网络中。 `view`函数中的 -1 通过确保`view`函数之前和之后的元素数量保持相同(在本例中为批量大小)来确保将正确的尺寸自动分配给该尺寸。
对于第一个全连接层,我们有 1,024 个输入(通过将最大池后的`64 x 4 x 4`张量展平而获得)和 512 个输出。 对于最后一个全连接层,我们有 512 个输入和 10 个输出,代表输出类别的数量。 我们还为全连接层定义了一个丢弃层,概率为 0.3。
......
# 迁移学习和 TensorBoard
迁移学习是深度学习中的一个重要概念,它使我们可以将深度学习用于各种日常任务。 这是一种机器学习技术,其中针对任务训练的模型被重用以创建用于类似任务的新模型。 我们采用在大型数据集上训练的模型,并将其知识移到较小的数据集。 对于具有**卷积神经网络****CNN**)的计算机视觉任务,我们冻结了网络的早期卷积层,仅训练了最后几层。 早期的卷积层提取适用于整个图像的通用低级特征,以检测边缘,图案和梯度,而稍后的层识别图像中的特定特征,并且特定于数据集。
迁移学习是深度学习中的一个重要概念,它使我们可以将深度学习用于各种日常任务。 这是一种机器学习技术,其中针对任务训练的模型被重用以创建用于类似任务的新模型。 我们采用在大型数据集上训练的模型,并将其知识移到较小的数据集。 对于具有**卷积神经网络****CNN**)的计算机视觉任务,我们冻结了网络的早期卷积层,仅训练了最后几层。 早期的卷积层提取适用于整个图像的通用低级特征,以检测边缘,图案和梯度,而稍后的层识别图像中的特定特征,并且特定于数据集。
在本章中,我们将训练图像分类器以区分正常患者和肺炎患者的胸部 X 光,并使用经过训练的 ResNet-50 模型进行迁移学习。 我们将替换分类器,并有两个输出单元代表正常和肺炎分类。
......
# 探索生成对抗网络
**生成对抗网络****GAN**)是一种机器学习技术,其中同时训练两种模型:一种专门用于创建伪造数据,另一种专门用于区分伪造数据和伪造数据。 真实数据。 术语*生成*反映了以下事实:这些神经网络用于创建新数据,而术语*对抗*来自以下事实:两个模型相互竞争,从而提高了生成的数据的质量。
**生成对抗网络****GAN**)是一种机器学习技术,其中同时训练两种模型:一种专门用于创建伪造数据,另一种专门用于区分真实数据和伪造数据。 真实数据。 术语*生成*反映了以下事实:这些神经网络用于创建新数据,而术语*对抗*来自以下事实:两个模型相互竞争,从而提高了生成的数据的质量。
GAN 中的两个模型称为生成器和判别器,其中生成器负责创建数据,判别器接收数据并将其分类为真实数据或由生成器生成。 生成器的目标是创建与训练集中的真实数据没有区别的数据样本。
我们可以用一个类比来理解 GAN 的概念,即犯罪分子(产生者)想要伪造金钱,而侦探(鉴别者)则试图抓住他。 假币的外观越真实,侦探在检测到假币时就必须越好,越高效,这意味着伪钞的质量必须提高到足以使侦探无法发现。
我们可以用一个类比来理解 GAN 的概念,即犯罪分子(产生者)想要伪造金钱,而侦探(判别器)则试图抓住他。 假币的外观越真实,侦探在检测到假币时就必须越好,越高效,这意味着伪钞的质量必须提高到足以使侦探无法发现。
生成器从判别器的分类反馈中学习。 判别器的目标是确定其输入是真实的(来自训练数据集)还是伪造的(来自生成器),因此,每当辨别器将虚假图像分类为真实的错误时,生成器都会获得表现良好的正反馈。 相反,每当判别器正确捕捉到生成器生成的图像为伪造图像时,生成器就会收到需要改进的反馈。
......@@ -18,7 +18,7 @@ GAN 中的两个模型称为生成器和判别器,其中生成器负责创建
在此图中,有一个数据源,其中包含训练图像`x`,生成器必须捕获其属性并重新创建。 生成器接收随机向量`z`,该向量充当生成器创建伪图像的种子。 生成器获取种子并生成`x*`图像,判别器从真实和虚假图像中获取图像,并输出给定​​输入为真实的概率(假设真实图像用 1 表示,伪图像用 0 表示)。 然后,我们获得分类误差,并使用它来迭代训练判别器和生成器。 判别器的目的是使分类误差最小,而生成器的目的是使分类误差最大化。
从理论上讲,生成器和判别器达到平衡,其中生成器已捕获了生成的伪图像中真实图像的所有特征,而从进一步的训练中没有任何收获。 类似地,鉴别者只能以 50% 的概率猜测图像是伪造的还是真实的,因为这两个图像就其性质而言完全无法区分。 在那个状态下,GAN 已经收敛。 然而,实际上,这种状态很难实现。 在本章中,我们将探讨 GAN 的概念以及 PyTorch 中各种 GAN 的实现。
从理论上讲,生成器和判别器达到平衡,其中生成器已捕获了生成的伪图像中真实图像的所有特征,而从进一步的训练中没有任何收获。 类似地,判别器只能以 50% 的概率猜测图像是伪造的还是真实的,因为这两个图像就其性质而言完全无法区分。 在那个状态下,GAN 已经收敛。 然而,实际上,这种状态很难实现。 在本章中,我们将探讨 GAN 的概念以及 PyTorch 中各种 GAN 的实现。
在本章中,我们将介绍以下秘籍:
......@@ -116,7 +116,7 @@ def forward(self, input):
在此秘籍中,我们进行了变换以将图像转换为张量并对其进行归一化,就像在第 3 章,“用于计算机视觉的卷积神经网络”中所做的一样。 然后,我们确定了机器上的设备: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 的对称性在这里可能是一个优势,因为网络应该以对称方式处理较深的颜色和较浅的颜色。
......@@ -549,7 +549,7 @@ Epoch : | 005 / 050 |
我们遍历了每个小批量并开始训练判别器。 我们仅从 MNIST 数据集中获取图像,然后使用`real_images = data[0].to(device)`将其移动到设备中; 由于图像全部来自 MNIST 数据集,因此我们知道它们是真实的,因此我们创建了与小批量相同大小的标签向量,并用真实图像标签 1 进行填充。然后,将这些真实图像传递到判别器来预测,然后使用此预测从准则中得出误差`derror_real`并计算梯度。 然后,我们创建了相等数量的噪声向量,并将它们传递给生成器以生成图像,然后将这些生成的图像传递给判别器以获取预测,然后从准则`derror_fake`中获取误差。 然后,我们再次进行此操作以计算和累积梯度。 然后,我们从真实图像和伪图像中获得了误差之和,以得出总的判别器误差,并更新判别器的权重。
然后,我们开始训练生成器,并且生成器应该能够欺骗判别器。 生成器必须纠正鉴别者正确预测生成的图像为假的情况。 因此,只要来自判别器的预测将生成的图像标记为伪造,就会增加生成器损失`gerror`。 然后,我们计算梯度并更新生成器权重。
然后,我们开始训练生成器,并且生成器应该能够欺骗判别器。 生成器必须纠正判别器正确预测生成的图像为假的情况。 因此,只要来自判别器的预测将生成的图像标记为伪造,就会增加生成器损失`gerror`。 然后,我们计算梯度并更新生成器权重。
然后,我们定期显示模型指标,并保存固定噪声生成器生成的图像,以可视化模型在各个周期的表现。
......@@ -563,7 +563,7 @@ Epoch : | 005 / 050 |
# 可视化 DCGAN 结果
以前我们已经看到,使用 GAN,生成器和判别器相互竞争,并且这样做可以产生越来越好的图像。 但是,从理论上讲,它们达到了生成器已捕获真实图像的所有特征的程度,并且生成器无法学习。 同样,鉴别者只能猜测给定图像是真实的还是伪造的,成功机会为 50/50。 在这一点上,据说 GAN 已经收敛。
以前我们已经看到,使用 GAN,生成器和判别器相互竞争,并且这样做可以产生越来越好的图像。 但是,从理论上讲,它们达到了生成器已捕获真实图像的所有特征的程度,并且生成器无法学习。 同样,判别器只能猜测给定图像是真实的还是伪造的,成功机会为 50/50。 在这一点上,据说 GAN 已经收敛。
现在,任何方面的改善都会导致另一面的结果降低,这是**零和**状态或**纳什平衡**; 但是在实践中很难实现,因为生成器和判别器都在不断变化,因此检查 GAN 表现的最佳方法是通过图形和图表。 在本秘籍中,我们将快速了解可视化。
......@@ -668,7 +668,7 @@ PGGAN 的关键创新可以总结如下:
* **高分辨率层中的逐渐增长和平滑淡化**:它从低分辨率卷积变为高分辨率卷积,而不是立即跳变分辨率,而是通过参数平滑地淡化了具有更高分辨率的 nedonew 层`α`(介于 0 和 1 之间)的大小,用于控制我们使用旧的还是放大的较大输出。
* **小批量标准差**:我们计算判别器的统计信息,即生成器生成或来自真实数据的小批量中所有像素的标准差。 现在,判别器需要了解,如果要评估的批量中图像的标准差较低,则该图像很可能是伪造的,因为真实数据的方差更高。 因此,生成器必须增加所生成样本的方差,以欺骗判别器。
* **均衡的学习率**:所有权重(`w`)被归一化(`w'`)在某个范围内,以便`w' = w / c`的常数`c`对于每一层来说都是不同的,具体取决于重量矩阵的形状。
* **均衡的学习率**:所有权重(`w`)被归一化(`w'`)在某个范围内,以便`w' = w / c`的常数`c`对于每一层来说都是不同的,具体取决于权重矩阵的形状。
* **逐像素特征归一化**:对每个像素中的特征向量进行归一化,因为批量规范最适合大型微型批量,并且占用大量内存。
Nvidia 最初执行 PGGAN 的过程要花一到两个月的时间。 但是,为了让我们看到 PGGAN 的表现,我们将使用 PyTorch Hub,它是使用 PyTorch 构建的预训练模型的存储库。
......
......@@ -60,7 +60,7 @@ PyTorch 在研究界获得了广泛的接受,因为大多数人已经在使用
PyTorch 允许用户定义 Python 在向前传递中允许他们执行的任何操作。 向后遍历自动找到遍历图直到根节点的路径,并在向后遍历时计算梯度。 尽管这是一个革命性的想法,但是产品开发社区并未接受 PyTorch,就像他们不能接受遵循类似实现的其他框架一样。 但是,随着时间的流逝,越来越多的人开始迁移到 PyTorch。 Kaggle 目睹了所有顶级玩家都使用 PyTorch 进行的比赛,并且如前所述,大学开始在 PyTorch 中开设课程。 这有助于学生避免像使用基于符号图的框架时那样学习新的图语言。
在 Caffe2 发布之后,自社区宣布 PyTorch 模型向 Caffe2 的迁移策略以来,甚至产品开发人员也开始尝试 PyTorch。 Caffe2 是一个静态图框架,即使在移动电话中也可以运行您的模型,因此使用 PyTorch 进行原型设计是一种双赢的方法。 构建网络时,您可以获得 PyTorch 的灵活性,并且可以将其传输到 Caffe2 并在任何生产环境中使用。 但是,在 1.0 版本说明中,PyTorch 团队从让人们学习两个框架(一个用于生产,一个用于研究)到学习在原型阶段具有动态图功能并且可以突然转换为一个框架的巨大跃进。 需要速度和效率的静态优化图。 PyTorch 团队将 Caffe2 的后端与 PyTorch 的 Aten 后端合并在一起,这使用户可以决定是要运行优化程度较低但高度灵活的图,还是运行优化程度较不灵活的图而无需重写代码库。
在 Caffe2 发布之后,自社区宣布 PyTorch 模型向 Caffe2 的迁移策略以来,甚至产品开发人员也开始尝试 PyTorch。 Caffe2 是一个静态图框架,即使在移动电话中也可以运行您的模型,因此使用 PyTorch 进行原型设计是一种双赢的方法。 构建网络时,您可以获得 PyTorch 的灵活性,并且可以将其转移到 Caffe2 并在任何生产环境中使用。 但是,在 1.0 版本说明中,PyTorch 团队从让人们学习两个框架(一个用于生产,一个用于研究)到学习在原型阶段具有动态图功能并且可以突然转换为一个框架的巨大跃进。 需要速度和效率的静态优化图。 PyTorch 团队将 Caffe2 的后端与 PyTorch 的 Aten 后端合并在一起,这使用户可以决定是要运行优化程度较低但高度灵活的图,还是运行优化程度较不灵活的图而无需重写代码库。
ONNX 和 DLPack 是 AI 社区看到的下两个“大事情”。 微软和 Facebook 共同宣布了 **开放神经网络交换****ONNX**)协议,该协议旨在帮助开发人员将任何模型从任何框架迁移到任何其他框架。 ONNX 与 PyTorch,Caffe2,TensorFlow,MXNet 和 CNTK 兼容,并且社区正在构建/改善对几乎所有流行框架的支持。
......@@ -74,7 +74,7 @@ ONNX 内置在 PyTorch 的核心中,因此将模型迁移到 ONNX 表单不需
计算图可帮助我们解决数学问题并使大型网络变得直观。 神经网络,无论它们有多复杂或多大,都是一组数学运算。 解决方程的明显方法是将方程分成较小的单元,并将一个输出传递给另一个,依此类推。 图方法背后的想法是相同的。 您将网络内部的操作视为节点,并将它们映射到一个图,图中节点之间的关系表示从一个操作到另一个操作的过渡。
计算图是,是人工智能当前所有先进技术的核心。 他们奠定了深度学习框架的基础。 现在,所有现有的深度学习框架都使用图方法进行计算。 这有助于框架找到独立的节点并作为独立的线程或进程进行计算。 计算图可帮助您轻松进行反向传播,就像从子节点移动到先前的节点一样,并在返回时携带梯度。 此操作称为自动分,这是 40 年前的想法。 自动微分被认为是上个世纪十大数值算法之一。 具体来说,反向模式自动微分是计算图背后用于反向传播的核心思想。 PyTorch 是基于反向模式自动微分而构建的,因此所有节点都将与它们一起保留操作信息,直到控件到达叶节点为止。 然后,反向传播从叶节点开始并向后遍历。 在向后移动时,流将随其一起获取梯度,并找到与每个节点相对应的偏导数。 1970 年,芬兰数学家和计算机科学家 Seppo Linnainmaa 发现自动微分可以用于算法验证。 几乎同时在同一概念上记录了许多其他并行的工作。
计算图是,是人工智能当前所有先进技术的核心。 他们奠定了深度学习框架的基础。 现在,所有现有的深度学习框架都使用图方法进行计算。 这有助于框架找到独立的节点并作为独立的线程或进程进行计算。 计算图可帮助您轻松进行反向传播,就像从子节点移动到先前的节点一样,并在返回时携带梯度。 此操作称为自动分,这是 40 年前的想法。 自动微分被认为是上个世纪十大数值算法之一。 具体来说,反向模式自动微分是计算图背后用于反向传播的核心思想。 PyTorch 是基于反向模式自动微分而构建的,因此所有节点都将与它们一起保留操作信息,直到控件到达叶节点为止。 然后,反向传播从叶节点开始并向后遍历。 在向后移动时,流将随其一起获取梯度,并找到与每个节点相对应的偏导数。 1970 年,芬兰数学家和计算机科学家 Seppo Linnainmaa 发现自动微分可以用于算法验证。 几乎同时在同一概念上记录了许多其他并行的工作。
在深度学习中,神经网络用于求解数学方程。 无论任务多么复杂,一切都取决于一个巨大的数学方程式,您可以通过优化神经网络的参数来求解。 解决问题的明显方法是“手工”。 考虑使用大约 150 层神经网络来求解 ResNet 的数学方程; 对于人类来说,要遍历数千次图,每次手动进行相同的操作来优化参数,都是不可能的。 计算图通过将所有操作逐级映射到图并一次求解每个节点来解决此问题。 “图 1.2”显示了具有三个运算符的简单计算图。
......@@ -232,7 +232,7 @@ for epoch in range(epochs):
自编码器是一种特殊的编码器-解码器网络,属于无监督学习类别。 自编码器尝试从未标记的数据中学习,将目标值设置为等于输入值。 例如,如果输入的图像尺寸为`100 x 100`,则输入向量的尺寸为 10,000。 因此,输出大小也将为 10,000,但隐藏层的大小可能为 500。简而言之,您尝试将输入转换为较小尺寸的隐藏状态表示,从而从隐藏状态重新生成相同的输入 。
如果您能够训练一个可以做到这一点的神经网络,那么,您将找到一个很好的压缩算法,可以将高维输入传输到低维向量,并获得一个数量级的幅度的收益。
如果您能够训练一个可以做到这一点的神经网络,那么,您将找到一个很好的压缩算法,可以将高维输入转移到低维向量,并获得一个数量级的幅度的收益。
如今,自编码器被用于不同的情况和行业。 当我们讨论语义分割时,您将在第 4 章,“计算机视觉”中看到类似的架构。
......
......@@ -119,11 +119,11 @@ b2 = torch.zeros(1, output_size, requires_grad=True, device=device, dtype=dtype)
```
对于初学者来说,这可能看起来很吓人,但是一旦您学习了基本的构建块,就只有六行代码。 我们从 PyTorch 中最重要的模块开始,该模块是 PyTorch 框架的主框架 autograd。 它可以帮助用户进行自动分,从而使我们在深度学习领域取得了所有突破。
对于初学者来说,这可能看起来很吓人,但是一旦您学习了基本的构建块,就只有六行代码。 我们从 PyTorch 中最重要的模块开始,该模块是 PyTorch 框架的主框架 autograd。 它可以帮助用户进行自动分,从而使我们在深度学习领域取得了所有突破。
#### 注意
**注意**:自动区分,有时也称为算法区分,是通过计算机程序利用函数执行顺序的技术。 自动区分的两种主要方法是正向模式和反向模式。 在前向模式自动微分中,我们首先找到外部函数的导数,然后递归进入内部,直到我们探索所有子节点。 反向模式自动区分正好相反,并且被深度学习社区和框架使用。 它由 Seppo Linnainmaa 于 1970 年在其硕士论文中首次出版。反向模式微分的主要构建模块是存储中间变量的存储器,以及使这些变量计算导数的功能,同时从子节点移回到父节点。
**注意**:自动微分,有时也称为算法微分,是通过计算机程序利用函数执行顺序的技术。 自动微分的两种主要方法是正向模式和反向模式。 在前向模式自动微分中,我们首先找到外部函数的导数,然后递归进入内部,直到我们探索所有子节点。 反向模式自动微分正好相反,并且被深度学习社区和框架使用。 它由 Seppo Linnainmaa 于 1970 年在其硕士论文中首次出版。反向模式微分的主要构建模块是存储中间变量的存储器,以及使这些变量计算导数的功能,同时从子节点移回到父节点。
正如 PyTorch 主页所说,PyTorch 中所有神经网络的中心都是 Autograd 包。 PyTorch 借助 Autograd 包获得了动态功能。 程序执行时,Autograd 将每个操作写入磁带状数据结构并将其存储在内存中。
......@@ -166,7 +166,7 @@ tensor([1.])
#### 张量的 Autograd 属性
当成为图的一部分时,张量需要存储 Autograd 自动分所需的信息。 张量充当计算图中的一个节点,并通过函数式模块实例连接到其他节点。 张量实例主要具有支持 Autograd 的三个属性:`.grad``.data``grad_fn()`(注意字母大小写:`Function`代表 PyTorch `Function`模块,而`function`代表 Python 函数)。
当成为图的一部分时,张量需要存储 Autograd 自动分所需的信息。 张量充当计算图中的一个节点,并通过函数式模块实例连接到其他节点。 张量实例主要具有支持 Autograd 的三个属性:`.grad``.data``grad_fn()`(注意字母大小写:`Function`代表 PyTorch `Function`模块,而`function`代表 Python 函数)。
`.grad`属性在任何时间点存储梯度,所有向后调用将当前梯度累积到`.grad`属性。 `.data`属性可访问其中包含数据的裸张量对象。
......@@ -253,7 +253,7 @@ print(a2.grad, a2.grad_fn, a2)
##### 反向传播
来自 NumPy 背景的人们,准备被吹走。 在 TensorFlow 或 PyTorch 等高级框架中开始进行深度学习的人,不要认为这是理所当然的。 现代框架的强大功能(自动分)使反向传播成为一线。 图中的最后一个节点是我们刚刚发现的损失结果。 现在,我们有了一个值,该值说明了我们的模型对结果的预测程度(或良好),我们需要根据该值更新参数。 反向传播可以为您提供帮助。 我们需要承担这种损失,然后移回每个神经元以查找每个神经元的贡献。
来自 NumPy 背景的人们,准备被吹走。 在 TensorFlow 或 PyTorch 等高级框架中开始进行深度学习的人,不要认为这是理所当然的。 现代框架的强大功能(自动分)使反向传播成为一线。 图中的最后一个节点是我们刚刚发现的损失结果。 现在,我们有了一个值,该值说明了我们的模型对结果的预测程度(或良好),我们需要根据该值更新参数。 反向传播可以为您提供帮助。 我们需要承担这种损失,然后移回每个神经元以查找每个神经元的贡献。
![Backpropagation](img/B09475_02_07.jpg)
......@@ -302,7 +302,7 @@ SGD 的主要缺点是效率低下。 例如,考虑我们的 *FizzBu​​zz*
除了我们刚才介绍的新超参数,学习率和批量大小以外,其他所有内容均保持不变。 我们用学习率乘以`.grad`属性来更新`.data`属性,并针对每次迭代进行此操作。 选择批量大小几乎总是取决于内存的可用性。 我们尝试使小批量尽可能大,以便可以将其放置在 GPU 内存中。 将整个批量划分为小批量,以确保每次梯度更新都会产生足够的抽动,从而在使用 GPU 提供的全部功能的同时,将模型从局部最小值中剔除。
我们已经到达了模型构建旅程的最后一部分。 到目前为止,所有操作都很直观,简单,但是最后一部分有点令人困惑。 `zero_grad`做什么? 还记得关于重量`w1.grad`的第一份印刷声明吗? 它是空的,现在具有当前反向传递的梯度。 因此,我们需要在下一次反向传播之前清空梯度,因为梯度会累积而不是被重写。 参数更新后,我们在每个迭代的每个张量上调用`zero_grad()`,然后继续进行下一个迭代。
我们已经到达了模型构建旅程的最后一部分。 到目前为止,所有操作都很直观,简单,但是最后一部分有点令人困惑。 `zero_grad`做什么? 还记得关于权重`w1.grad`的第一份印刷声明吗? 它是空的,现在具有当前反向传递的梯度。 因此,我们需要在下一次反向传播之前清空梯度,因为梯度会累积而不是被重写。 参数更新后,我们在每个迭代的每个张量上调用`zero_grad()`,然后继续进行下一个迭代。
`.grad_fn`通过连接函数和张量将图保持在一起。 在`Function`模块中定义了对张量的每种可能的操作。 所有张量的`.grad_fn`始终指向函数对象,除非用户创建了它。 PyTorch 允许您使用`grad_fn`向后浏览图。 从图中的任何节点,可以通过在`grad_fn`的返回值上调用`next_functions`来到达任何父节点。
......@@ -324,7 +324,7 @@ print(output.grad_fn.next_functions[0][0].next_functions[0][0])
## PyTorch 方式
到目前为止,我们已经以 NumPy-PyTorch 混合形式开发了一个简单的两层神经网络。 我们已经在 NumPy 中逐行编码了每个操作,就像我们在 NumPy 中进行编码一样,并且我们采用了与 PyTorch 的自动分,因此我们不必对反向传递进行编码。
到目前为止,我们已经以 NumPy-PyTorch 混合形式开发了一个简单的两层神经网络。 我们已经在 NumPy 中逐行编码了每个操作,就像我们在 NumPy 中进行编码一样,并且我们采用了与 PyTorch 的自动分,因此我们不必对反向传递进行编码。
在途中,我们学习了如何在 PyTorch 中包装矩阵(或张量),这有助于我们进行反向传播。 使用 PyTorch 进行相同操作的方式更加方便,这就是我们将在本节中讨论的内容。 PyTorch 可以访问内置的深度学习项目所需的几乎所有功能。 由于 PyTorch 支持 Python 中所有可用的数学函数,因此,如果在内核中不可用,则构建一个函数并不是一件艰巨的任务。 您不仅可以构建所需的任何函数,而且 PyTorch 隐式定义了所构建函数的导函数。
......@@ -555,9 +555,9 @@ with torch.no_grad():
b2 -= lr * b2.grad
```
但是,对于具有很多参数的大型模型,我们无法做到这一点。 更好的替代方法是像我们以前看到的那样循环遍历`net.parameters()`,但是这样做的主要缺点是,循环遍历了作为样板的 Python 中的参数。 此外,有不同的重更新策略。 我们使用的是最基本的梯度下降方法。 复杂的方法可以处理学习率衰减,动量等等。 这些帮助网络比常规 SGD 更快地达到全局最小值。
但是,对于具有很多参数的大型模型,我们无法做到这一点。 更好的替代方法是像我们以前看到的那样循环遍历`net.parameters()`,但是这样做的主要缺点是,循环遍历了作为样板的 Python 中的参数。 此外,有不同的重更新策略。 我们使用的是最基本的梯度下降方法。 复杂的方法可以处理学习率衰减,动量等等。 这些帮助网络比常规 SGD 更快地达到全局最小值。
`optim`包是 PyTorch 提供的替代方案,可有效处理重量更新。 除此之外,一旦使用模型参数初始化了优化器对象,用户就可以在其上调用`zero_grad`。 因此,不再像以前那样显式地在每个权重和偏置参数上调用`zero_grad`
`optim`包是 PyTorch 提供的替代方案,可有效处理权重更新。 除此之外,一旦使用模型参数初始化了优化器对象,用户就可以在其上调用`zero_grad`。 因此,不再像以前那样显式地在每个权重和偏置参数上调用`zero_grad`
```py
w1.grad.zero_()
......
......@@ -83,7 +83,7 @@ for batch in dataloader:
print(batch)
```
`DataLoader`类接受从`torch.utils.data.Dataset`继承的`dataset`类。 `DataLoader`接受`dataset`并执行不重要的操作,例如小批量,多线程,改组等,以从数据集中获取数据。 它接受来自用户的`dataset`实例,并使用采样器策略以小批量的形式采样数据。
`DataLoader`类接受从`torch.utils.data.Dataset`继承的`dataset`类。 `DataLoader`接受`dataset`并执行不重要的操作,例如小批量,多线程,打乱等,以从数据集中获取数据。 它接受来自用户的`dataset`实例,并使用采样器策略以小批量的形式采样数据。
`num_worker`参数决定应该操作多少个并行线程来获取数据。 这有助于避免 CPU 瓶颈,以便 CPU 可以赶上 GPU 的并行操作。 数据加载器允许用户指定是否使用固定的 CUDA 内存,这会将数据张量复制到 CUDA 的固定的内存中,然后再返回给用户。 使用固定内存是设备之间快速数据传输的关键,因为数据是由数据加载程序本身加载到固定内存中的,而无论如何,这都是由 CPU 的多个内核完成的。
......
......@@ -16,9 +16,9 @@ CNN 是一种基本上由小型网络组成的网络架构,几乎类似于第
简单的全连接层具有更大的权重,因为它们存储信息以处理所有权重。 全连接层的另一个功能使其无法进行图像处理:它不能考虑空间信息,因为它在处理时会删除像素值的顺序/排列结构。
CNN 由几个三维内核组成,它们像滑动窗口一样在输入张量中移动,直到覆盖整个张量为止。 核是三维张量,其深度与输入张量的深度(在第一层中为 3;图像的深度在 RGB 通道中)相同。 内核的高度和宽度可以小于或等于输入张量的高度和宽度。 如果内核的高度和宽度与输入张量的高度和宽度相同,则其设置与正常神经网络的设置非常相似。
CNN 由几个三维核组成,它们像滑动窗口一样在输入张量中移动,直到覆盖整个张量为止。 核是三维张量,其深度与输入张量的深度(在第一层中为 3;图像的深度在 RGB 通道中)相同。 核的高度和宽度可以小于或等于输入张量的高度和宽度。 如果核的高度和宽度与输入张量的高度和宽度相同,则其设置与正常神经网络的设置非常相似。
每次内核通过输入张量移动时,它都可能吐出单个值输出,该输出会经历非线性。 当内核作为滑动窗口移动时,内核从输入图像覆盖的每个插槽都将具有此输出值。 滑动窗口的移动将创建输出特征图(本质上是张量)。 因此,我们可以增加内核数量以获得更多的特征图,并且从理论上讲,每个特征图都能够保存一种特定类型的信息。
每次核通过输入张量移动时,它都可能吐出单个值输出,该输出会经历非线性。 当核作为滑动窗口移动时,核从输入图像覆盖的每个插槽都将具有此输出值。 滑动窗口的移动将创建输出特征映射(本质上是张量)。 因此,我们可以增加核数量以获得更多的特征映射,并且从理论上讲,每个特征映射都能够保存一种特定类型的信息。
![Introduction to CNNs](img/B09075_04_01.jpg)
......@@ -26,13 +26,13 @@ CNN 由几个三维内核组成,它们像滑动窗口一样在输入张量中
来源:《可视化和理解卷积网络》,Matthew D. Zeiler 和 Rob Fergus
由于使用了相同的内核来覆盖整个图像,因此我们正在重用内核参数,从而减少了参数数量。
由于使用了相同的核来覆盖整个图像,因此我们正在重用核参数,从而减少了参数数量。
CNN 实质上会降低`x``y`轴(高度和宽度)中图像的尺寸,并增加深度(`z`轴)。`z`轴上的每个切片都是一个如上所述的特征图,由每个多维内核创建。
CNN 实质上会降低`x``y`轴(高度和宽度)中图像的尺寸,并增加深度(`z`轴)。`z`轴上的每个切片都是一个如上所述的特征映射,由每个多维核创建。
CNN 中的降级有助于 CNN 的位置不变。 位置不变性可帮助其识别图像不同部分中的对象。 例如,如果您有两只猫的图像,其中一只猫在一张图像的左侧,另一只猫在右侧,那么您希望您的网络从这两幅图像中识别出这只猫,对吗?
CNN 通过两种机制实现位置不变:跨步和合并。 步幅值决定了滑动窗口的运动程度。 池化是 CNN 的固有部分。 我们有三种主要的池化类型:最大池化,最小池化和平均池化。 在最大池化的情况下,池化从输入张量的子块中获取最大值,在最小池化的情况下从池中获取最小值,而在平均池化的情况下,池化将取所有值的平均值。 池化层和卷积核的输入和输出基本相同。 两者都作为滑动窗口在输入张量上移动并输出单个值。
CNN 通过两种机制实现位置不变:跨步和合并。 步幅值决定了滑动窗口的运动程度。 池化是 CNN 的固有部分。 我们有三种主要的池化类型:最大池化,最小池化和平均池化。 在最大池化的情况下,池化从输入张量的子块中获取最大值,在最小池化的情况下从池中获取最小值,而在平均池化的情况下,池化将取所有值的平均值。 池化层和卷积核的输入和输出基本相同。 两者都作为滑动窗口在输入张量上移动并输出单个值。
接下来是 CNN 运作方式的描述。 要更深入地了解 CNN,请查看斯坦福大学的 CS231N。 或者,如果您需要通过动画视频快速介绍 CNN,Udacity [1]提供了很好的资源。
......@@ -140,7 +140,7 @@ class Conv(nn.Module):
self.bias = Parameter(torch.zeros(out_channels))
```
图像上的卷积运算使用滤波器对输入图像进行乘法和加法运算,并创建单个输出值。 因此,现在我们有了一个输入映像和一个内核。 为简单起见,让我们考虑输入图像为大小为`7x7`的单通道(灰度)图像,并假设内核的大小为`3x3`,如下图所示。 我们将内核的中间值称为锚点,因为我们将锚点保留在图像中的某些值上进行卷积。
图像上的卷积运算使用过滤器对输入图像进行乘法和加法运算,并创建单个输出值。 因此,现在我们有了一个输入映像和一个核。 为简单起见,让我们考虑输入图像为大小为`7x7`的单通道(灰度)图像,并假设核的大小为`3x3`,如下图所示。 我们将核的中间值称为锚点,因为我们将锚点保留在图像中的某些值上进行卷积。
![Model](img/B09475_04_03.jpg)
......@@ -150,13 +150,13 @@ class Conv(nn.Module):
图 4.3b
我们通过将内核锚定在图像的左上像素开始卷积,如图“图 4.3b”所示。 现在,我们将图像中的每个像素值与相应的内核值相乘,然后将所有像素值相加,得到一个值。 但是我们有一个要处理的问题。 内核的顶行和左列将乘以什么? 为此,我们介绍了填充。
我们通过将核锚定在图像的左上像素开始卷积,如图“图 4.3b”所示。 现在,我们将图像中的每个像素值与相应的核值相乘,然后将所有像素值相加,得到一个值。 但是我们有一个要处理的问题。 核的顶行和左列将乘以什么? 为此,我们介绍了填充。
我们在输入张量的外侧添加行和列,其值为零,以便核中的所有值在输入图像中都有一个对应的值要配对。 我们从乘法中得到的单个值和加法运算是我们对该实例进行的卷积运算的输出。
我们在输入张量的外侧添加行和列,其值为零,以便核中的所有值在输入图像中都有一个对应的值要配对。 我们从乘法中得到的单个值和加法运算是我们对该实例进行的卷积运算的输出。
现在,我们将内核右移一个像素,然后像滑动窗口一样再次执行该操作,并重复此操作,直到覆盖图像为止。 我们可以从每个卷积运算中获得的每个输出一起创建该层的特征图或输出。 下面的代码片段在最后三行中完成了所有这些操作。
现在,我们将核右移一个像素,然后像滑动窗口一样再次执行该操作,并重复此操作,直到覆盖图像为止。 我们可以从每个卷积运算中获得的每个输出一起创建该层的特征映射或输出。 下面的代码片段在最后三行中完成了所有这些操作。
PyTorch 支持普通的 Python 索引,我们使用它来为特定迭代查找滑动窗口所在的插槽,并将其保存到名为`val`的变量中。 但是索引创建的张量可能不是连续的内存块。 通过使用`view()`不能更改非连续存储块张量,因此我们使用`contiguous()`方法将张量移动到连续块。 然后,将该张量与核(权重)相乘,并对其添加偏倚。 然后将卷积运算的结果保存到`out`张量,将其初始化为零作为占位符。 预先创建占位符并向其中添加元素比最后在一组单个通道上进行堆叠要高效一个数量级。
PyTorch 支持普通的 Python 索引,我们使用它来为特定迭代查找滑动窗口所在的插槽,并将其保存到名为`val`的变量中。 但是索引创建的张量可能不是连续的内存块。 通过使用`view()`不能更改非连续存储块张量,因此我们使用`contiguous()`方法将张量移动到连续块。 然后,将该张量与核(权重)相乘,并对其添加偏倚。 然后将卷积运算的结果保存到`out`张量,将其初始化为零作为占位符。 预先创建占位符并向其中添加元素比最后在一组单个通道上进行堆叠要高效一个数量级。
```py
out = torch.zeros(batch_size, new_depth, new_height, new_width)
......@@ -183,9 +183,9 @@ 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`填充。
`W = (WF + 2P) / S + 1`,其中`W`是输入大小,`F`是核大小,`S`跨步应用`P`填充。
![Model](img/B09475_04_05.jpg)
......@@ -195,10 +195,10 @@ Variable containing:
前面的示例使用了一个单通道输入并创建了一个单通道输出。 我们可以将其扩展为使用`n`个输入通道来创建`n`个输出通道,这是卷积网络的基本构建块。 通过进行两次更改,可以推断出相同的概念以处理任意数量的输入通道以创建任意数量的输出通道:
* 由于输入图像具有多个通道,因此用于与相应元素相乘的内核必须为`n`维。 如果输入通道为三个,并且内核大小为五个,则内核形状应为`5 x 5 x 3`
* 但是,如何创建`n`个输出通道? 现在我们知道,不管输入通道有多少,一次卷积都会创建一个单值输出,而完整的滑动窗口会话会创建一个二维矩阵作为输出。 因此,如果我们有两个内核做完全相同的事情,那就是:滑动输入并创建二维输出。 然后,我们将获得两个二维输出,并将它们堆叠在一起将为我们提供具有两个通道的输出。 随着输出中需要更多通道,我们增加了内核数量。
* 由于输入图像具有多个通道,因此用于与相应元素相乘的核必须为`n`维。 如果输入通道为三个,并且核大小为五个,则核形状应为`5 x 5 x 3`
* 但是,如何创建`n`个输出通道? 现在我们知道,不管输入通道有多少,一次卷积都会创建一个单值输出,而完整的滑动窗口会话会创建一个二维矩阵作为输出。 因此,如果我们有两个核做完全相同的事情,那就是:滑动输入并创建二维输出。 然后,我们将获得两个二维输出,并将它们堆叠在一起将为我们提供具有两个通道的输出。 随着输出中需要更多通道,我们增加了核数量。
我们拥有的自定义卷积层可以完成卷积。 它接受输入和输出通道的数量,内核大小,步幅和填充作为参数。 内核的形状为`[kernel_size, kernel_size, input_channels]`。 我们没有创建`n`个内核并将输出堆叠在一起以获得多通道输出,而是创建了一个大小为`output_channel, input_channel, kernal_size, kernal_size`的单个权重张量,这给出了我们想要的。
我们拥有的自定义卷积层可以完成卷积。 它接受输入和输出通道的数量,核大小,步幅和填充作为参数。 核的形状为`[kernel_size, kernel_size, input_channels]`。 我们没有创建`n`核并将输出堆叠在一起以获得多通道输出,而是创建了一个大小为`output_channel, input_channel, kernal_size, kernal_size`的单个权重张量,这给出了我们想要的。
在所有池化选项中,人们倾向于使用最大池化。 合并操作采用张量的一个子部分,并获取单个值作为输出。 最大池从概念上讲获取该子部件的突出特征,而平均池则取平均值并平滑该特征。 而且,从历史上看,最大池化比其他池化算法提供更好的结果,可能是因为它从输入中获取最突出的特征并将其传递到下一个级别。 因此,我们也使用最大池。 定制的最大池化层具有相同的结构,但是复杂的卷积操作由简单的最大操作代替。
......@@ -332,7 +332,7 @@ LinkNet 由一个初始块,一个最终块,一个带有四个卷积模块的
命名操作反卷积很有意义,因为它的作用与卷积相反。 它有许多名称,例如转置卷积(因为之间使用的矩阵已转置)和后向卷积(因为操作是反向传播时卷积的反向传递)。 但是实际上,我们本质上是在进行卷积运算,但是我们更改了像素在输入中的排列方式。
对于具有填充和跨度的反卷积,输入图像将在像素周围具有填充,并且之间将具有零值像素。 在所有情况下,核滑动窗口的移动将保持不变。
对于具有填充和跨度的反卷积,输入图像将在像素周围具有填充,并且之间将具有零值像素。 在所有情况下,核滑动窗口的移动将保持不变。
##### 注意
......@@ -380,7 +380,7 @@ class ConvBlock(nn.Module):
return self.conv_block(x)
```
LinkNet 中的所有卷积都紧随其后的是批量规范化和 ReLU 层,但是有一些例外,没有 ReLU 层。 这就是`ConvBlock`的目标。 如前所述,`ConvBlock``torch.nn.Module`的子类,可以根据正向传播中发生的任何事情进行反向传播。 `__init__`接受输入和输出尺寸,核大小,步幅值,填充宽度,表示是否需要偏置的布尔值和表示是否需要激活(ReLU)的布尔值。
LinkNet 中的所有卷积都紧随其后的是批量规范化和 ReLU 层,但是有一些例外,没有 ReLU 层。 这就是`ConvBlock`的目标。 如前所述,`ConvBlock``torch.nn.Module`的子类,可以根据正向传播中发生的任何事情进行反向传播。 `__init__`接受输入和输出尺寸,核大小,步幅值,填充宽度,表示是否需要偏置的布尔值和表示是否需要激活(ReLU)的布尔值。
我们使用`torch.nn.Conv2d``torch.nn.BatchNorm2d``torch.nn.ReLu`来配置`ConvBlock`。 PyTorch 的`Conv2D`接受`ConvBlock``__init__`的所有参数,但表示类似激活要求的布尔值除外。 除此之外,`Conv2D`还接受另外两个用于`dilation``group`的可选参数。 `torch.nn`的 ReLU 函数仅接受一个称为`inplace`的可选参数,默认为`False`。 如果`inplace``True`,则 ReLU 将应用于原地数据,而不是创建另一个存储位置。 在许多情况下,这可能会稍微节省内存,但会导致问题,因为我们正在破坏输入。 经验法则是:除非您迫切需要内存优化,否则请远离它。
......@@ -440,7 +440,7 @@ class DeconvBlock(nn.Module):
##### 池化
PyTorch 有几个用于池化操作的选项,我们从其中选择使用`MaxPool`。 正如我们在`SimpleCNN`示例中看到的那样,这是一个显而易见的操作,我们可以通过仅从池中提取突出的特征来减少输入的维数。 `MaxPool2d`接受类似于`Conv2d`的参数来确定核大小,填充和步幅。 但是除了这些参数之外,`MaxPool2d`接受两个额外的参数,即返回索引和`ciel`。 返回索引返回最大值的索引,可在某些网络架构中进行池化时使用。 `ciel`是布尔参数,它通过确定尺寸的上限或下限来确定输出形状。
PyTorch 有几个用于池化操作的选项,我们从其中选择使用`MaxPool`。 正如我们在`SimpleCNN`示例中看到的那样,这是一个显而易见的操作,我们可以通过仅从池中提取突出的特征来减少输入的维数。 `MaxPool2d`接受类似于`Conv2d`的参数来确定核大小,填充和步幅。 但是除了这些参数之外,`MaxPool2d`接受两个额外的参数,即返回索引和`ciel`。 返回索引返回最大值的索引,可在某些网络架构中进行池化时使用。 `ciel`是布尔参数,它通过确定尺寸的上限或下限来确定输出形状。
##### 编码器块
......
......@@ -14,7 +14,7 @@
注意是下一个重大发明,它可以帮助网络将注意力集中在输入的重要部分上,而不是搜索整个输入并试图找到答案。 实际上,来自 Google Brain 和多伦多大学的一个团队证明,注意力可以击败 LSTM 和 GRU 网络[1]。 但是,大多数实现都同时使用 LSTM/GRU 和注意力。
嵌入是通过比较单词在单词簇中的分布来找到单词的概念含义的另一种革命性思想。 嵌入保持单词之间的关系,并将这种关系(它从单词簇中的单词分布中找到)转换为一组浮点数。 嵌入大大减少了输入大小,并极大地提高了表现和准确率。 我们将使用 word2vec 进行实验。
嵌入是通过比较单词在单词群集中的分布来找到单词的概念含义的另一种革命性思想。 嵌入保持单词之间的关系,并将这种关系(它从单词群集中的单词分布中找到)转换为一组浮点数。 嵌入大大减少了输入大小,并极大地提高了表现和准确率。 我们将使用 word2vec 进行实验。
数据处理是序列数据(尤其是自然语言)的主要挑战之一。 PyTorch 提供了一些工具包来处理该问题。 我们将使用预处理后的数据来简化实现,但是我们将遍历工具包以了解它们的工作原理。 与这些工具包一起,我们将使用`torchtext`,它消除了处理输入数据时将面临的许多困难。
......
......@@ -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 个可能值中的值,从而离散化网络的输出生成,而先前使用的最先进的自回归模型将在网络的最后一层上继续生成值。
......@@ -243,11 +243,11 @@ 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)
图 6.11:带有核扩展的膨胀卷积
图 6.11:带有核扩展的膨胀卷积
PyTorch 通过使用户能够将膨胀作为关键字参数传递,从而使进行膨胀卷积变得容易,如先前代码块中的`DilatedCausalConv1d`节点中所给出的。 如前所述,每一层具有不同的扩张因子,并且可以为每一层的扩张卷积节点创建传递该因子。 由于跨步为 1,所以填充保持为 0,目的不是上采样或下采样。 `init_weights_for_test`是通过将权重矩阵填充 1 来进行测试的便捷函数。
......@@ -270,7 +270,7 @@ WaveNet 的完整架构建立在膨胀卷积网络和卷积后门控激活的基
来源: 《WaveNet:原始音频的生成模型》,Aaron van den Oord 等
“图 6.12”中提供的 WaveNet 的结构图显示了所有这些小组件以及它们如何连接在一起。 跳跃连接之后的部分在程序中称为密集层,尽管它不是上一章介绍的密集层。 通常,密集层表示全连接层,以将非线性引入网络并获得所有数据的概览。 但是 WaveNet 的作者发现,正常的致密层可以由一串 ReLU 代替,并且`1x1`卷积可以通过最后的 softmax 层实现更高的精度,该层可以展开为 256 个单元(巨大扇出的 8 位`µ`律量化) 音频)。
“图 6.12”中提供的 WaveNet 的结构图显示了所有这些小组件以及它们如何连接在一起。 跳跃连接之后的部分在程序中称为密集层,尽管它不是上一章介绍的密集层。 通常,密集层表示全连接层,以将非线性引入网络并获得所有数据的概览。 但是 WaveNet 的作者发现,正常的密集层可以由一串 ReLU 代替,并且`1x1`卷积可以通过最后的 softmax 层实现更高的精度,该层可以展开为 256 个单元(巨大扇出的 8 位`µ`律量化) 音频)。
```py
class WaveNetModule(torch.nn.Module):
......@@ -414,7 +414,7 @@ class DiscriminatorNet(torch.nn.Module):
图 6.14:ReLU 和泄漏的 ReLU
我们开发的的简单区分器具有三个连续层。 每个层都有一个线性层,泄漏的 ReLU 和一个夹在中间的漏失层,然后是一个线性层和一个 Sigmoid 门。 通常,概率预测网络使用 softmax 层作为最后一层; 像这样的简单 GAN 最适合 Sigmoid 曲面。
我们开发的的简单判别器具有三个连续层。 每个层都有一个线性层,泄漏的 ReLU 和一个夹在中间的漏失层,然后是一个线性层和一个 Sigmoid 门。 通常,概率预测网络使用 softmax 层作为最后一层; 像这样的简单 GAN 最适合 Sigmoid 曲面。
```py
def train_discriminator(optimizer, real_data, fake_data):
......
......@@ -18,7 +18,7 @@
这似乎很简单,因为智能体程序要做的就是考虑环境的当前状态进行决策,但是我们还想要更多。 通常,座席的目标是在其一生中最大化其累积奖励,重点是“累积”一词。 智能体不仅关心在下一步中获得的报酬,而且还关心将来可能获得的报酬。 这需要有远见,并将使智能体学习得更好。
这个元素使问题变得更加复杂,因为我们必须权衡两个因素:探索与利用。 探索将意味着做出随机决策并对其进行测试,而剥削则意味着做出智能体已经知道的决策将给其带来积极的结果,因此智能体现在需要找到一种方法来平衡这两个因素以获得最大的累积结果。 。 这是强化学习中非常重要的概念。 这个概念催生了各种算法来平衡这两个因素,并且是一个广泛的研究领域。
这个元素使问题变得更加复杂,因为我们必须权衡两个因素:探索与利用。 探索将意味着做出随机决策并对其进行测试,而利用则意味着做出智能体已经知道的决策将给其带来积极的结果,因此智能体现在需要找到一种方法来平衡这两个因素以获得最大的累积结果。 。 这是强化学习中非常重要的概念。 这个概念催生了各种算法来平衡这两个因素,并且是一个广泛的研究领域。
在本章中,我们将使用 OpenAI 名为 Gym 的库。 这是一个开放源代码库,为强化学习算法的训练和基准测试设定了标准。 体育馆提供了许多研究人员用来训练强化学习算法的环境。 它包括许多 Atari 游戏,用于拾取物品的机器人仿真,用于步行和跑步的各种机器人仿真以及驾驶仿真。 该库提供了智能体程序和环境之间相互交互所必需的参数。
......
......@@ -4,7 +4,7 @@
可以使用`torch.nn`包构建神经网络。
现在您已经了解了`autograd``nn`依赖于`autograd`来定义模型并对其进行分。 `nn.Module`包含层,以及返回`output`的方法`forward(input)`
现在您已经了解了`autograd``nn`依赖于`autograd`来定义模型并对其进行分。 `nn.Module`包含层,以及返回`output`的方法`forward(input)`
例如,查看以下对数字图像进行分类的网络:
......
......@@ -288,7 +288,7 @@ tensor(0.0811, grad_fn=<NllLossBackward>) tensor(1.)
## 使用`nn.Module`重构
接下来,我们将使用`nn.Module``nn.Parameter`进行更清晰,更简洁的训练循环。 我们将`nn.Module`子类化(它本身是一个类并且能够跟踪状态)。 在这种情况下,我们要创建一个类,该类包含前进步骤的权重,偏和方法。 `nn.Module`具有许多我们将要使用的属性和方法(例如`.parameters()``.zero_grad()`)。
接下来,我们将使用`nn.Module``nn.Parameter`进行更清晰,更简洁的训练循环。 我们将`nn.Module`子类化(它本身是一个类并且能够跟踪状态)。 在这种情况下,我们要创建一个类,该类包含前进步骤的权重,偏和方法。 `nn.Module`具有许多我们将要使用的属性和方法(例如`.parameters()``.zero_grad()`)。
注意
......@@ -610,7 +610,7 @@ tensor(0.0821, grad_fn=<NllLossBackward>)
在第 1 节中,我们只是试图建立一个合理的训练循环以用于我们的训练数据。 实际上,您也应该**始终**具有[验证集](https://www.fast.ai/2017/11/13/validation-sets/),以便识别您是否过拟合。
[对训练数据进行改组](https://www.quora.com/Does-the-order-of-training-data-matter-when-training-neural-networks)对于防止批量与过拟合之间的相关性很重要。 另一方面,无论我们是否改组验证集,验证损失都是相同的。 由于改组需要花费更多时间,因此改组验证数据没有任何意义。
[对训练数据进行打乱](https://www.quora.com/Does-the-order-of-training-data-matter-when-training-neural-networks)对于防止批量与过拟合之间的相关性很重要。 另一方面,无论我们是否打乱验证集,验证损失都是相同的。 由于打乱需要花费更多时间,因此打乱验证数据没有任何意义。
我们将验证集的批量大小设为训练集的两倍。 这是因为验证集不需要反向传播,因此占用的内存更少(不需要存储梯度)。 我们利用这一优势来使用更大的批量,并更快地计算损失。
......@@ -827,7 +827,7 @@ Our CNN is fairly concise, but it only works with MNIST, because:
* 假设输入为`28 * 28`长向量
* 假设 CNN 的最终网格尺寸为`4 * 4`(因为这是平均值
我们使用的合并核大小)
我们使用的合并核大小)
让我们摆脱这两个假设,因此我们的模型适用于任何 2d 单通道图像。 首先,我们可以删除初始的 Lambda 层,但将数据预处理移至生成器中:
......
......@@ -446,7 +446,7 @@ IoU metric: segm
## 总结
在本教程中,您学习了如何在自定义数据集上为实例细分模型创建自己的训练管道。 为此,您编写了一个`torch.utils.data.Dataset`类,该类返回图像以及地面真相框和分段蒙版。 您还利用了在 COCO train2017 上预先训练的 Mask R-CNN 模型,以便对该新数据集执行迁移学习。
在本教程中,您学习了如何在自定义数据集上为实例细分模型创建自己的训练管道。 为此,您编写了一个`torch.utils.data.Dataset`类,该类返回图像以及真实情况框和分段蒙版。 您还利用了在 COCO train2017 上预先训练的 Mask R-CNN 模型,以便对该新数据集执行迁移学习。
对于更完整的示例(包括多机/多 GPU 训练),请检查在`torchvision`存储库中存在的`references/detection/train.py`
......
......@@ -74,8 +74,8 @@ Random Seed: 999
* `image_size`-用于训练的图像的空间大小。 此实现默认为`64x64`。 如果需要其他尺寸,则必须更改`D``G`的结构。 有关更多详细信息,请参见[此处](https://github.com/pytorch/examples/issues/70)
* `nc`-输入图像中的彩色通道数。 对于彩色图像,这是 3
* `nz`-潜向量的长度
* `ngf`-与通过生成器传送的特征的深度有关
* `ndf`-设置通过判别器传播的特征的深度
* `ngf`-与通过生成器传送的特征映射的深度有关
* `ndf`-设置通过判别器传播的特征映射的深度
* `num_epochs`-要运行的训练周期数。 训练更长的时间可能会导致更好的结果,但也会花费更长的时间
* `lr`-训练的学习率。 如 DCGAN 文件中所述,此数字应为 0.0002
* `beta1`-Adam 优化器的`beta1`超参数。 如论文所述,该数字应为 0.5
......@@ -192,7 +192,7 @@ def weights_init(m):
![dcgan_generator](img/85974d98be6202902f21ce274418953f.png)
请注意,我们在输入部分中设置的输入(`nz``ngf``nc`)如何影响代码中的生成器架构。 `nz``z`输入向量的长度,`ngf`与通过生成器传播的特征的大小有关, `nc`是输出图像中的通道(对于 RGB 图像设置为 3)。 下面是生成器的代码。
请注意,我们在输入部分中设置的输入(`nz``ngf``nc`)如何影响代码中的生成器架构。 `nz``z`输入向量的长度,`ngf`与通过生成器传播的特征映射的大小有关, `nc`是输出图像中的通道(对于 RGB 图像设置为 3)。 下面是生成器的代码。
```py
# Generator Code
......
......@@ -241,9 +241,9 @@ Median relative difference between original and MuLaw reconstucted signals: 1.28
* `gain`:对整个波形进行放大或衰减。
* `dither`:增加以特定位深度存储的音频的动态范围。
* `compute_deltas`:计算张量的增量系数。
* `equalizer_biquad`:设计双二阶峰值均衡器滤波器并执行滤波。
* `lowpass_biquad`:设计双二阶低通滤波器并执行滤波。
* `highpass_biquad`:设计双二阶高通滤波器并执行滤波。
* `equalizer_biquad`:设计双二阶峰值均衡器过滤器并执行滤波。
* `lowpass_biquad`:设计双二阶低通过滤器并执行滤波。
* `highpass_biquad`:设计双二阶高通过滤器并执行滤波。
例如,让我们尝试`mu_law_encoding`函数:
......@@ -311,7 +311,7 @@ Mean of dither_waveform: 0.00010744280007202178
```
`torchaudio.functional`中函数的另一个示例是将滤波器应用于我们的波形。 将低通双二阶滤波器应用于我们的波形,将输出修改了频率信号的新波形。
`torchaudio.functional`中函数的另一个示例是将过滤器应用于我们的波形。 将低通双二阶过滤器应用于我们的波形,将输出修改了频率信号的新波形。
```py
lowpass_waveform = torchaudio.functional.lowpass_biquad(waveform, sample_rate, cutoff_freq=3000)
......@@ -334,7 +334,7 @@ Mean of lowpass_waveform: 9.293757466366515e-05
```
我们还可以使用高通双二阶滤波器可视化波形。
我们还可以使用高通双二阶过滤器可视化波形。
```py
highpass_waveform = torchaudio.functional.highpass_biquad(waveform, sample_rate, cutoff_freq=2000)
......@@ -403,7 +403,7 @@ Shape of spectrogram: torch.Size([1383, 201])
```
我们还支持根据波形计算滤波器组特征,以匹配 Kaldi 的实现。
我们还支持根据波形计算过滤器组特征,以匹配 Kaldi 的实现。
```py
fbank = torchaudio.compliance.kaldi.fbank(waveform, **params)
......
......@@ -210,7 +210,7 @@ test_loader = torch.utils.data.DataLoader(
## 定义网络
在本教程中,我们将使用卷积神经网络来处理原始音频数据。 通常,更高级的转换将应用于音频数据,但是 CNN 可以用于准确处理原始数据。 具体架构是根据[本文](https://arxiv.org/pdf/1610.00087.pdf)中描述的 M5 网络架构建模的。 模型处理原始音频数据的一个重要方面是其第一层过滤器的接收范围。 我们模型的第一个滤波器长度为 80,因此在处理以 8kHz 采样的音频时,接收场约为 10ms(而在 4kHz 时约为 20ms)。 此大小类似于语音处理应用,该应用通常使用 20ms 到 40ms 的接收域。
在本教程中,我们将使用卷积神经网络来处理原始音频数据。 通常,更高级的转换将应用于音频数据,但是 CNN 可以用于准确处理原始数据。 具体架构是根据[本文](https://arxiv.org/pdf/1610.00087.pdf)中描述的 M5 网络架构建模的。 模型处理原始音频数据的一个重要方面是其第一层过滤器的接收范围。 我们模型的第一个过滤器长度为 80,因此在处理以 8kHz 采样的音频时,接收场约为 10ms(而在 4kHz 时约为 20ms)。 此大小类似于语音处理应用,该应用通常使用 20ms 到 40ms 的接收域。
```py
class M5(nn.Module):
......
......@@ -121,7 +121,7 @@ MyCell(
通过以这种方式组成`Module`,我们可以简洁易读地编写具有可重用组件的模型。
您可能已经在输出上注意到`grad_fn`。 这是 PyTorch 自动分方法的详细信息,称为 [autograd](https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html) 。 简而言之,该系统允许我们通过潜在的复杂程序来计算导数。 该设计为模型创作提供了极大的灵活性。
您可能已经在输出上注意到`grad_fn`。 这是 PyTorch 自动分方法的详细信息,称为 [autograd](https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html) 。 简而言之,该系统允许我们通过潜在的复杂程序来计算导数。 该设计为模型创作提供了极大的灵活性。
现在,让我们检查一下灵活性:
......
......@@ -662,7 +662,7 @@ Batch size: 64 | Labels: 7 6 5 7 7 5 2 2 4 9 9 4 8 7 4 8 9 4 5 7 1 2 6 9 8 5 1 2
## 编写训练循环
现在,让我们完成示例的算法部分,并实现生成器和判别器之间的精妙舞蹈。 首先,我们将创建两个优化器,一个用于生成器,一个用于区分器。 我们使用的优化程序实现了 [Adam](https://arxiv.org/pdf/1412.6980.pdf) 算法:
现在,让我们完成示例的算法部分,并实现生成器和判别器之间的精妙舞蹈。 首先,我们将创建两个优化器,一个用于生成器,一个用于判别器。 我们使用的优化程序实现了 [Adam](https://arxiv.org/pdf/1412.6980.pdf) 算法:
```py
torch::optim::Adam generator_optimizer(
......
......@@ -6,7 +6,7 @@
PyTorch 提供了与神经网络,任意张量代数,数据整理和其他目的有关的大量操作。 但是,您仍然可能发现自己需要更多的自定义操作。 例如,您可能想使用论文中发现的新颖的激活函数,或者实现您在研究过程中开发的操作。
在 PyTorch 中集成这样的自定义操作的最简单方法是通过扩展[此处](https://pytorch.org/docs/master/notes/extending.html)概述的`Function``Module`来用 Python 编写它。 这为您提供了自动分的全部功能(使您不必编写导函数)以及 Python 的通常表达能力。 但是,有时您的操作可以用 C++ 更好地实现。 例如,您的代码可能*确实*需要速度,因为在模型中它经常被调用,或者即使很少调用也很昂贵。 另一个合理的原因是它依赖于其他 C 或 C++ 库或与之交互。 为了解决这种情况,PyTorch 提供了一种非常简单的方式来编写自定义 *C++ 扩展*
在 PyTorch 中集成这样的自定义操作的最简单方法是通过扩展[此处](https://pytorch.org/docs/master/notes/extending.html)概述的`Function``Module`来用 Python 编写它。 这为您提供了自动分的全部功能(使您不必编写导函数)以及 Python 的通常表达能力。 但是,有时您的操作可以用 C++ 更好地实现。 例如,您的代码可能*确实*需要速度,因为在模型中它经常被调用,或者即使很少调用也很昂贵。 另一个合理的原因是它依赖于其他 C 或 C++ 库或与之交互。 为了解决这种情况,PyTorch 提供了一种非常简单的方式来编写自定义 *C++ 扩展*
C++ 扩展是我们开发的一种机制,允许用户(您)创建源外定义的 PyTorch 运算符,即与 PyTorch 后端分开。 该方法不同于本机 PyTorch 操作的实现方式。 C++ 扩展旨在为您节省大量与将操作与 PyTorch 后端集成在一起相关的样板,同时为基于 PyTorch 的项目提供高度的灵活性。 但是,一旦将操作定义为 C++ 扩展,将其转换为本地 PyTorch 函数在很大程度上取决于代码组织,如果您决定在上游进行操作,则可以解决此问题。
......
......@@ -274,7 +274,7 @@ ReLU 的导数图,对于`x <= 0`,`f'(x) = 1`,对于`x > 0`,`f'(x) = 0`
# 梯度下降算法
梯度下降算法是一种使用一阶导数查找函数最小值的优化算法,也就是说,我们仅将函数的参数分为一阶。 在此,梯度下降算法的目的是使关于`W``b`的成本函数`J(W, b)`最小化。
梯度下降算法是一种使用一阶导数查找函数最小值的优化算法,也就是说,我们仅将函数的参数分为一阶。 在此,梯度下降算法的目的是使关于`W``b`的成本函数`J(W, b)`最小化。
此方法包括以下步骤,可进行多次迭代以最小化`J(W, b)`
......@@ -292,7 +292,7 @@ ReLU 的导数图,对于`x <= 0`,`f'(x) = 1`,对于`x > 0`,`f'(x) = 0`
# 计算图
基本的神经网络由前向传播和后向传播组成。 结果,它由一系列步骤组成,这些步骤包括不同节点,权重和偏差的值,以及所有权重和偏差的成本函数导数。 为了跟踪这些过程,图片中出现了**计算图**。 无论神经网络的深度如何,计算图还可以跟踪链式规则的分。
基本的神经网络由前向传播和后向传播组成。 结果,它由一系列步骤组成,这些步骤包括不同节点,权重和偏差的值,以及所有权重和偏差的成本函数导数。 为了跟踪这些过程,图片中出现了**计算图**。 无论神经网络的深度如何,计算图还可以跟踪链式规则的分。
# 使用梯度下降法解决逻辑回归的步骤
......@@ -563,7 +563,7 @@ CNN 在计算机视觉和自然语言处理领域具有广泛的应用。 就行
![](img/858a5158-bd38-4ab1-86da-57bdd947e8ed.png)
在这里,我们将 3 个特征图(即 RGB 通道)映射到`k`个特征图
在这里,我们将 3 个特征映射(即 RGB 通道)映射到`k`个特征映射
斑块在图像上的滑动运动称为步幅,而每次移动的像素数(水平或垂直)都称为**步幅**。 如果补丁没有超出图像空间,则将其视为**有效填充**。 另一方面,如果色块超出图像空间以映射色块大小,则在该空间之外的色块像素将填充零。 这称为**相同填充**
......@@ -571,11 +571,11 @@ CNN 在计算机视觉和自然语言处理领域具有广泛的应用。 就行
CNN 架构由一系列这些卷积层组成。 如果这些卷积层中的跨步值大于 1,则会导致空间缩小。 因此,步幅,斑块大小和激活函数成为超参数。 除卷积层外,有时还会添加一个重要的层,称为**池化层**。 这将附近的所有卷积合并起来。 池化的一种形式称为**最大池化**
在最大池中,特征会查看补丁中的所有值,并返回其中的最大值。 因此,池大小(即池补丁/窗口大小)和池跨度是超参数。 下图描述了最大池化的概念:
在最大池中,特征映射会查看补丁中的所有值,并返回其中的最大值。 因此,池大小(即池补丁/窗口大小)和池跨度是超参数。 下图描述了最大池化的概念:
![](img/c026d9c2-b027-4ff9-8b53-1b4cb26dfe9b.png)
最大池化通常会产生更准确的结果。 类似地,我们具有**平均池化**,其中取最大值而不是取池窗口中值的平均值,以提供特征的低分辨率视图。
最大池化通常会产生更准确的结果。 类似地,我们具有**平均池化**,其中取最大值而不是取池窗口中值的平均值,以提供特征映射的低分辨率视图。
通过合并和全连接层来操纵卷积层的超参数和排序,已经创建了许多不同的 CNN 变体,这些变体正在研究和工业领域中使用。 其中一些著名的是 LeNet-5,Alexnet,VGG-Net 和 Inception 模型。
......@@ -604,9 +604,9 @@ Hinton 等人[《用于 ImageNet 分类的深度卷积神经网络的 AlexNet
# VGG-Net 模型
VGG-Net 由牛津大学**视觉几何组****VGG**)的 Karen Simonyan 和 Andrew Zisserman 引入。 他们使用大小为`3 x 3`的小型卷积滤波器训练深度为 16 和 19 的网络。他们的团队分别在 ImageNet Challenge 2014 的本地化和分类任务中获得了第一和第二名。
VGG-Net 由牛津大学**视觉几何组****VGG**)的 Karen Simonyan 和 Andrew Zisserman 引入。 他们使用大小为`3 x 3`的小型卷积过滤器训练深度为 16 和 19 的网络。他们的团队分别在 ImageNet Challenge 2014 的本地化和分类任务中获得了第一和第二名。
通过向模型添加更多非线性来设计更深层的神经网络的想法导致合并了较小的滤波器,以确保网络没有太多参数。 在训练时,很难收敛模型,因此首先使用预先训练的简单神经网络模型来初始化较深架构的权重。 但是,现在我们可以直接使用 xavier 初始化方法,而无需训练神经网络来初始化权重。 由于模型的深度,训练起来很慢。
通过向模型添加更多非线性来设计更深层的神经网络的想法导致合并了较小的过滤器,以确保网络没有太多参数。 在训练时,很难收敛模型,因此首先使用预先训练的简单神经网络模型来初始化较深架构的权重。 但是,现在我们可以直接使用 xavier 初始化方法,而无需训练神经网络来初始化权重。 由于模型的深度,训练起来很慢。
# Inception 模型
......@@ -620,7 +620,7 @@ Inception 由 Google 团队于 2014 年创建。其主要思想是创建更广
# 深度学习的局限性
深度神经网络是权重和偏的黑盒,它们经过大量数据训练,可以通过内部表示找到隐藏的模式。 对于人类来说这将是不可能的,即使有可能,那么可伸缩性也是一个问题。 每个神经可能都有不同的权重。 因此,它们将具有不同的梯度。
深度神经网络是权重和偏的黑盒,它们经过大量数据训练,可以通过内部表示找到隐藏的模式。 对于人类来说这将是不可能的,即使有可能,那么可伸缩性也是一个问题。 每个神经可能都有不同的权重。 因此,它们将具有不同的梯度。
训练在反向传播期间进行。 因此,训练的方向始终是从较后的层(输出/右侧)到较早的层(输入/左侧)。 与早期的层相比,这导致后面的层学习得很好。 网络越深入,情况恶化的程度就越大。 这引起了与深度学习相关的两个可能的问题,它们是:
......@@ -1012,7 +1012,7 @@ Google DeepMind 是一家英国人工智能公司,成立于 2010 年 9 月,
以下是其一些项目:
* 2016 年 7 月,Google DeepMind 与 Moorfields 眼科医院宣布合作,使用眼部扫描技术研究导致失明的疾病的早期征兆
* 2016 年 8 月,Google DeepMind 宣布与伦敦大学学院医院合作研究和开发一种算法,以自动分头部和颈部的健康组织和癌性组织
* 2016 年 8 月,Google DeepMind 宣布与伦敦大学学院医院合作研究和开发一种算法,以自动分头部和颈部的健康组织和癌性组织
* Google DeepMind AI 将 Google 的数据中心散热费用降低了 40%
# AlphaGo 程序
......
......@@ -403,7 +403,7 @@ HFFG
# 将 Q 网络用于实际应用
维护少数州的表是可能的,但在现实世界中,州会变得无限。 因此,需要一种解决方案,其合并状态信息并输出动作的 Q 值而不使用 Q 表。 这是神经网络充当函数逼近器的地方,该函数逼近器针对不同状态信息的数据及其所有动作的相应 Q 值进行训练,从而使它们能够预测任何新状态信息输入的 Q 值。 用于预测 Q 值而不是使用 Q 表的神经网络称为 Q 网络。
维护少数状态的表是可能的,但在现实世界中,状态会变得无限。 因此,需要一种解决方案,其合并状态信息并输出动作的 Q 值而不使用 Q 表。 这是神经网络充当函数逼近器的地方,该函数逼近器针对不同状态信息的数据及其所有动作的相应 Q 值进行训练,从而使它们能够预测任何新状态信息输入的 Q 值。 用于预测 Q 值而不是使用 Q 表的神经网络称为 Q 网络。
在这里,对于`FrozenLake-v0`环境,让我们使用一个将状态信息作为输入的单个神经网络,其中状态信息表示为一个`1 x 状态`形状的单热编码向量(此处为`1 x 16`)并输出形状为`1 x 动作数`的向量(此处为`1 x 4`)。 输出是所有操作的 Q 值:
......
......@@ -33,7 +33,7 @@
这里, `H`地平线的时间步长,因此,如果开始时间步长`t = 0`,则总时间步长为`H + 1`
* 随机策略类消除了策略优化问题,为我们提供了一组可以选择最佳策略的策略。 在网格世界环境中采用确定性策略的情况下,由于动作变化而导致的变化并不平滑,但是如果每个都有动作分布,我们可以稍微改变分布,而这只会稍微改变预期的总和。 奖励。 这是使用随机策略的优势,其中`π[θ](a | s)`给出给定状态`s`的动作`a`的概率。 因此,`π[θ]`给出了给定状态下动作的概率分布。
* 随机策略类消除了策略优化问题,为我们提供了一组可以选择最佳策略的策略。 在网格世界环境中采用确定性策略的情况下,由于动作变化而导致的变化并不平滑,但是如果每个状态都有动作分布,我们可以稍微改变分布,而这只会稍微改变预期的总和。 奖励。 这是使用随机策略的优势,其中`π[θ](a | s)`给出给定状态`s`的动作`a`的概率。 因此,`π[θ]`给出了给定状态下动作的概率分布。
因此,由于随机策略,我们有一个平滑的优化问题,可以应用梯度下降来获得良好的局部最优,从而导致最优策略。
......@@ -157,7 +157,7 @@
![](img/b6666854-9607-4fcd-9536-6ad2779a7ffd.png)
因此,将该方法推广到多步马尔可夫决策过程将导致状态奖励 Q 值函数`Q[π](s, a)`代替瞬时奖励`r`。 这称为**策略梯度定理**。 该定理对前面讨论的其他类型的策略目标函数有效。 因此,对于任何这样的策略目标函数和任何可分的`π[θ](s, a)`,策略梯度如下:
因此,将该方法推广到多步马尔可夫决策过程将导致状态奖励 Q 值函数`Q[π](s, a)`代替瞬时奖励`r`。 这称为**策略梯度定理**。 该定理对前面讨论的其他类型的策略目标函数有效。 因此,对于任何这样的策略目标函数和任何可分的`π[θ](s, a)`,策略梯度如下:
![](img/22aa628a-e90d-49c5-ae2d-c8f5e168393c.png)
......@@ -190,7 +190,7 @@ Episode T
由于这些更新针对所有状态独立发生,因此可以针对所有状态并行执行这些操作。
在完成剧集的最后一步之后扩展每个的计算值估计值时,我们发现基于值的更新与基于结果的更新相同,例如在蒙特卡洛方法中,我们会进行全面的展望,直到剧集的结尾。 因此,我们需要一种更好的方法来更新我们的值函数估计值,而无需多做一步。 通过合并`TD(0)`规则,我们可以解决此问题。
在完成剧集的最后一步之后扩展每个状态的计算值估计值时,我们发现基于值的更新与基于结果的更新相同,例如在蒙特卡洛方法中,我们会进行全面的展望,直到剧集的结尾。 因此,我们需要一种更好的方法来更新我们的值函数估计值,而无需多做一步。 通过合并`TD(0)`规则,我们可以解决此问题。
# `TD(0)`规则
......
......@@ -359,7 +359,7 @@ DeepMind 在其 DQN 网络中使用了三个卷积层和两个全连接层,从
添加到深度 Q 网络的另一个重要功能是**经验回放**。 该功能背后的想法是,智能体可以存储其过去的经验,并分批使用它们来训练深度神经网络。 通过存储经验,智能体可以随机抽取批量,并帮助网络从各种数据中学习,而不仅仅是对即时经验的决策正式化。 这些经历中的每一个都以包括**状态,动作,奖励****下一个状态**的四维向量的形式存储。
为了避免存储问题,体验重放的缓冲区是固定的,并且随着新体验的存储,旧体验将被删除。 为了训练神经网络,从缓冲区中提取均匀批量的随机经验。
为了避免存储问题,经验回放的缓冲区是固定的,并且随着新体验的存储,旧体验将被删除。 为了训练神经网络,从缓冲区中提取均匀批量的随机经验。
# 分离目标网络来计算目标 Q 值
......@@ -947,7 +947,7 @@ if __name__ == "__main__":
* `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)`:在神经网络中创建层的函数
* `weight_variable(self,w_shape,layer,c)`:创建重量参数的函数
* `weight_variable(self,w_shape,layer,c)`:创建权重参数的函数
* `bias_variable(self,b_shape,layer,c)`:创建偏置参数的函数
* `conv(self,inputs,w)`:对图像帧执行卷积运算的函数
* `build_networks()`:此函数用于使用 TensorFlow 创建主要网络和目标网络
......@@ -1024,7 +1024,7 @@ def bias_variable(self,b_shape,layer,c):
现在让我们定义`conv(self,inputs,w)`,该函数调用 TensorFlow 的`tf.nn.conv2d`函数并采用:
* 输入为二维向量
* **权重**:形状的重量`[patch_size,patch_size,input_vector_depth,output_vector_depth]`
* **权重**:形状`[patch_size,patch_size,input_vector_depth,output_vector_depth]`的权重
* **跨步**:以`[1,x_movement,y_movement,1]`形式出现的列表,其中:
* `x_movement`:定义水平移动补丁的步数
* `y_movement`:定义在垂直方向上移动的色块的步数
......
......@@ -193,13 +193,13 @@ Google DeepMind 已经开始使用 AlphaGo Zero 来了解蛋白质折叠,因
网络输入包括:
* `19 x 19`矩阵平面,代表棋盘
* 一个用于白色宝石的特征(在具有白色宝石的位置具有 1,在其他位置具有 0 的二进制矩阵)
* 一个用于黑宝石的特征(在具有黑宝石的位置具有 1,在其他位置具有 0 的二进制矩阵)
* 七个使用白色石头的玩家过去的特征(代表历史,因为它捕获了过去的七个动作)
* 一个用于白色宝石的特征映射(在具有白色宝石的位置具有 1,在其他位置具有 0 的二进制矩阵)
* 一个用于黑宝石的特征映射(在具有黑宝石的位置具有 1,在其他位置具有 0 的二进制矩阵)
* 七个使用白色石头的玩家过去的特征映射(代表历史,因为它捕获了过去的七个动作)
* 七个使用黑石头的玩家过去特征映射(代表历史,因为它捕获了过去七个动作)
* 一个用于转弯指示的特征图(转弯可以用 1 位表示,但此处已在整个特征图上重复出现)
* 一个用于转弯指示的特征映射(转弯可以用 1 位表示,但此处已在整个特征映射上重复出现)
因此,网络输入由`19 x 19 x (1 + 1 + 7 + 7 + 1) = 19 x 19 x 17`张量表示。 使用过去七个动作的特征的原因在于,这段历史就像一个注意力机制。
因此,网络输入由`19 x 19 x (1 + 1 + 7 + 7 + 1) = 19 x 19 x 17`张量表示。 使用过去七个动作的特征映射的原因在于,这段历史就像一个注意力机制。
为什么我们使用残差架构而不是普通卷积架构? 其背后的原因是残留的架构允许梯度信号直接穿过层。 此外,即使在卷积层没有做任何有用的学习的早期阶段,重要的学习信号也会进入卷积层并直接进入其他层。 详细解释残留架构超出了本书的范围。
......
......@@ -25,9 +25,9 @@
| | 基于非参数核的对数最优策略 |
| | 非参数最近邻对数最优策略 |
| | 相关驱动的非参数学习策略 |
| | 基于非参数核的半对数最优策略 |
| | 基于非参数核的 Markowitz 类型策略 |
| | 基于非参数核的 GV 类型策略 |
| | 基于非参数核的半对数最优策略 |
| | 基于非参数核的 Markowitz 类型策略 |
| | 基于非参数核的 GV 类型策略 |
| 元学习 | 聚合算法 |
| | 快速通用算法 |
| | 在线梯度更新 |
......
......@@ -86,7 +86,7 @@ Perkins 和 Barto(2002)提出了一种基于 Lyapunov 函数构造强化学
* 实时创建学习模型以输出要采取的最佳措施
* 延迟接收动作信号和致动导致机器人中的机器运动
由于这些延迟,动作无法立即实现,从而导致延迟效果。 在诸如**马尔科夫决策过程****MDP**)之类的强化学习算法中,假定动作会瞬间影响环境,而忽略了与现实世界相关的延迟。 可以通过汇总一些最近的操作并将其提供给来解决此问题,但这也将导致尺寸的增加(在上一节中讨论的机器人强化学习中的挑战)。 解决该问题的另一种方法是增加时间步长,但这有两个缺点,一个缺点是妨碍了机器人的控制,第二个缺点是由于持续时间的变化而对系统的动态产生不利影响。
由于这些延迟,动作无法立即实现,从而导致延迟效果。 在诸如**马尔科夫决策过程****MDP**)之类的强化学习算法中,假定动作会瞬间影响环境,而忽略了与现实世界相关的延迟。 可以通过汇总一些最近的操作并将其提供给状态来解决此问题,但这也将导致尺寸的增加(在上一节中讨论的机器人强化学习中的挑战)。 解决该问题的另一种方法是增加时间步长,但这有两个缺点,一个缺点是妨碍了机器人的控制,第二个缺点是由于持续时间的变化而对系统的动态产生不利影响。
因此,我们总结了如下讨论的实际挑战:
......
......@@ -57,7 +57,7 @@ SPP 网络的一大缺点是,只能微调网络的全连接层,而不能进
Ross Girshick 的 [Fast R-CNN](https://arxiv.org/pdf/1504.08083.pdf)
在 Fast R-CNN 中,将输入图像和多个兴趣区域作为 CNN 的输入。 完成 RoI 的合并以获得固定大小的特征,然后通过**全连接层****FC**)发送以获得特征向量。 R-CNN 每个兴趣区域具有两个输出向量,如下所示:
在 Fast R-CNN 中,将输入图像和多个兴趣区域作为 CNN 的输入。 完成 RoI 的合并以获得固定大小的特征映射,然后通过**全连接层****FC**)发送以获得特征向量。 R-CNN 每个兴趣区域具有两个输出向量,如下所示:
* Softmax 概率
* 每类边界框回归偏移
......@@ -152,9 +152,9 @@ YOLO 还可以为每个盒子预测训练中所有类的类得分。 因此,
* ImageZooms 模型
* Pool45-作物模型
对于 Image-Zooms 模型,每个区域的大小调整为`224x224`,并通过 Pool5 层馈入 VGG-16,以获得特征图。 对于 Pool45-Crops 模型,全分辨率的图像通过 Pool5 层输入到 VGG-16。 合并从整个图像中提取的所有**兴趣区域****ROI**)的特征图
对于 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)
......
......@@ -33,7 +33,7 @@
为机器翻译创建的基于注意力的编码器解码器模型(Bahdanau 等,2014)是一个序列到序列模型,能够通过获得良好的 ROUGE 得分来生成具有良好表现的抽象摘要(请参见附录 A,“强化学习中的其他主题”)。 在短输入序列上的表现很好,并且随着输入文本序列长度的增加而降低。
在 CNN /每日邮件数据集的更大输入序列和输出摘要数据集上(Hermann 等,2015),Nallapati 等人(2016)提出了抽象摘要模型的应用,其中输入序列最多为 800 个标记,而摘要最多为 100 个标记。 对本实验的分析表明,与较大输入序列的基于注意力的编码器-解码器模型相关的问题是,它们通常会生成异常摘要,这些摘要通常由重复的短语组成。 这是因为仅通过监督学习方法进行训练的编码器解码器模型通常会遭受曝光偏差,即在训练过程中的每个时间步骤都提供了地面真相(实际文本)的假设。
在 CNN /每日邮件数据集的更大输入序列和输出摘要数据集上(Hermann 等,2015),Nallapati 等人(2016)提出了抽象摘要模型的应用,其中输入序列最多为 800 个标记,而摘要最多为 100 个标记。 对本实验的分析表明,与较大输入序列的基于注意力的编码器-解码器模型相关的问题是,它们通常会生成异常摘要,这些摘要通常由重复的短语组成。 这是因为仅通过监督学习方法进行训练的编码器解码器模型通常会遭受曝光偏差,即在训练过程中的每个时间步骤都提供了真实情况(实际文本)的假设。
在这里,我们将讨论 Paulus 等人(2017 年 11 月)的研究出版物《抽象摘要的深度强化模型》。 它向我们介绍了一种抽象摘要的新模型,该模型在 CNN /每日邮件数据集以及**纽约时报****NYT**)数据集上都获得了强大的结果(Sandhaus,2008 年)。
......@@ -127,7 +127,7 @@ Paulus 等人(2017)在[《用于抽象摘要的深度强化模型》](https:
但是,将`L_ml`最小化的目标并不总是产生最佳结果。 此问题背后的两个主要原因如下:
* **暴露偏差**:在训练过程中,神经网络知道直到下一个标记的地面真相序列,但在测试时并非如此。
* **暴露偏差**:在训练过程中,神经网络知道直到下一个标记的真实情况序列,但在测试时并非如此。
* **多个输出候选**(即**多个可能有效的摘要**):有更多方式可以安排标记以生成多个摘要。 最大可能性目标没有考虑这种可能性。
# 策略学习
......@@ -159,7 +159,7 @@ Paulus 等人(2017)在[《用于抽象摘要的深度强化模型》](https:
# 文字问答
问题回答是提供文档上下文以及在给定文档上下文中存在其答案的问题的任务。 现有的问题回答模型用于优化交叉熵损失,该模型用于鼓励准确答案并惩罚与准确答案同等准确的其他可能答案。 这些现有的问题回答模型(Xiong 等人,2017 年的最新动态动态求职网络)经过训练,可以从文档上下文中输出所问问题的准确答案范围。 实际地面真相答案的开始和结束位置将用作此监督学习方法的目标。 因此,该监督模型在两个位置上都使用了交叉熵损失,目的是使两个位置上的总损失最小化。
问题回答是提供文档上下文以及在给定文档上下文中存在其答案的问题的任务。 现有的问题回答模型用于优化交叉熵损失,该模型用于鼓励准确答案并惩罚与准确答案同等准确的其他可能答案。 这些现有的问题回答模型(Xiong 等人,2017 年的最新动态动态求职网络)经过训练,可以从文档上下文中输出所问问题的准确答案范围。 实际真实情况答案的开始和结束位置将用作此监督学习方法的目标。 因此,该监督模型在两个位置上都使用了交叉熵损失,目的是使两个位置上的总损失最小化。
如我们所见,优化是通过使用位置来完成的,评估是通过使用答案的文本内容来完成的。 因此,优化和评估方法之间存在脱节。 由于这种脱节,许多文本上相似的答案由于其在其他位置的存在而受到惩罚,就好像它们是不正确的答案一样,这与真实情况答案的位置不同。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册