提交 c95f2791 编写于 作者: W wizardforcel

2021-01-11 22:44:46

上级 a05fea6a
......@@ -706,7 +706,7 @@ print("\nTest accuracy: %.1f%%" % (100.0 * acc))
图 1.4.3:卷积运算显示如何计算特征映射的一个元素
为简单起见,显示了应用了`3×3`内核的`3×3`输入图像(或输入特征映射)。 卷积后显示结果特征映射。 要素地图中一个元素的值被加阴影。 您会注意到,结果特征映射小于原始输入图像的,这是因为卷积仅在有效元素上执行。 内核不能超出映像的边界。 如果输入的尺寸应与输出要素图相同,则`Conv2D`接受选项`padding='same'`。 输入在其边界周围填充零,以在卷积后保持尺寸不变。
为简单起见,显示了应用了`3×3`内核的`3×3`输入图像(或输入特征映射)。 卷积后显示结果特征映射。 特征映射中一个元素的值被加阴影。 您会注意到,结果特征映射小于原始输入图像的,这是因为卷积仅在有效元素上执行。 内核不能超出映像的边界。 如果输入的尺寸应与输出特征映射相同,则`Conv2D`接受选项`padding='same'`。 输入在其边界周围填充零,以在卷积后保持尺寸不变。
## 池化操作
......@@ -714,7 +714,7 @@ print("\nTest accuracy: %.1f%%" % (100.0 * acc))
![](img/B14853_01_14.png)
图 1.4.4:`MaxPooling2D`操作。 为简单起见,输入要素图`4×4`,结果为`2×2`特征映射。
图 1.4.4:`MaxPooling2D`操作。 为简单起见,输入特征映射`4×4`,结果为`2×2`特征映射。
`MaxPooling2D`的意义在于特征映射尺寸的减小,这转化为感受野尺寸的增加。 例如,在`MaxPooling2D(2)`之后,2×2 内核现在大约与`4×4`补丁卷积。 CNN 学会了针对不同接收场大小的一组新的特征映射。
......@@ -722,7 +722,7 @@ print("\nTest accuracy: %.1f%%" % (100.0 * acc))
`Conv2D``MaxPooling2D`中,`pool_size``kernel`都可以是非正方形的。 在这些情况下,必须同时指定行和列的大小。 例如,`pool_ size = (1, 2)``kernel = (3, 5)`
最后一个`MaxPooling2D`操作的输出是一堆特征映射。 `Flatten`的作用是,将特征映射的栈转换为适用于`Dropout``Dense`层的向量格式,类似于 MLP 模型输出层。
最后一个`MaxPooling2D`操作的输出是一堆特征映射。 `Flatten`的作用是,将特征映射的栈转换为适用于`Dropout``Dense`层的向量格式,类似于 MLP 模型输出层。
在下一部分中,我们将评估经过训练的 MNIST CNN 分类器模型的表现。
......
......@@ -153,13 +153,13 @@ print("\nTest accuracy: %.1f%%" % (100.0 * score[1]))
要了解接受域的概念,请注意,当内核计算特征映射的每个点时,其输入是前一层特征映射中的补丁,该补丁也取决于其前一层特征映射。 如果我们继续将此依赖关系一直跟踪到输入图像,则内核将依赖于称为接收场的图像补丁。
我们将使用选项`padding='same'`来确保使用扩张的 CNN 时不会出现负张量。 通过使用`padding='same'`,我们将使输入的尺寸与输出要素图相同。 这是通过用零填充输入以确保输出的**大小**相同来实现的。
我们将使用选项`padding='same'`来确保使用扩张的 CNN 时不会出现负张量。 通过使用`padding='same'`,我们将使输入的尺寸与输出特征映射相同。 这是通过用零填充输入以确保输出的**大小**相同来实现的。
![](img/B14853_02_02.png)
图 2.1.2:通过从 1 增加膨胀率,有效的核接受域大小也增加了
“列表 2.1.2”的`cnn-y-network-2.1.2.py`显示了使用函数式 API 的 Y 网络的实现。 两个分支由两个`for`循环创建。 两个分支期望输入形状相同。 两个`for`循环将创建两个`Conv2D-Dropout-MaxPooling2D`的三层栈。 虽然我们使用`concatenate`层组合了左右分支的输出,但我们还可以利用`tf.keras`的其他合并函数,例如`add``dot``multiply`。 合并函数的选择并非纯粹是任意的,而必须基于合理的模型设计决策。
“列表 2.1.2”的`cnn-y-network-2.1.2.py`显示了使用函数式 API 的 Y 网络的实现。 两个分支由两个`for`循环创建。 两个分支期望输入形状相同。 两个`for`循环将创建两个`Conv2D-Dropout-MaxPooling2D`的三层栈。 虽然我们使用`concatenate`层组合了左右分支的输出,但我们还可以利用`tf.keras`的其他合并函数,例如`add``dot``multiply`。 合并函数的选择并非纯粹是任意的,而必须基于合理的模型设计决策。
在 Y 网络中,`concatenate`不会丢弃特征映射的任何部分。 取而代之的是,我们让`Dense`层确定如何处理连接的特征映射。
......@@ -344,7 +344,7 @@ print("\nTest accuracy: %.1f%%" % (100.0 * score[1]))
可以通过`add()`合并函数在`tf.keras`中实现添加操作。 但是,`F(x[l-1])``x[l-2]`应该具有相同的尺寸。
如果尺寸不同,例如,当更改要素地图尺寸时,我们应该在`x[l-2]`上进行线性投影以匹配尺寸`F([l-1])`的含量。 在原始论文中,当特征映射的大小减半时,情况的线性投影是通过`Conv2D`和 1 `strides=2`内核完成的。
如果尺寸不同,例如,当更改特征映射尺寸时,我们应该在`x[l-2]`上进行线性投影以匹配尺寸`F([l-1])`的含量。 在原始论文中,当特征映射的大小减半时,情况的线性投影是通过`Conv2D`和 1 `strides=2`内核完成的。
在“第 1 章”,“Keras 高级深度学习”,我们讨论了`stride > 1`等效于在卷积期间跳过像素。 例如,如果`strides=2`,则在卷积过程中滑动内核时,可以跳过其他每个像素。
......@@ -421,7 +421,7 @@ else:
model = resnet_v1(input_shape=input_shape, depth=depth)
```
`resnet_v1()`方法是 ResNet 的模型构建器。 它使用工具函数`resnet_layer(),`来帮助构建`Conv2D-BN-ReLU`栈。
`resnet_v1()`方法是 ResNet 的模型构建器。 它使用工具函数`resnet_layer(),`来帮助构建`Conv2D-BN-ReLU`的栈。
它将称为版本 1,正如我们将在下一节中看到的那样,提出了一种改进的 ResNet,该版本称为 ResNet 版本 2 或 v2。 通过 ResNet,ResNet v2 改进了残差块设计,从而提高了表现。
......@@ -557,7 +557,7 @@ ResNet v2 的改进主要体现在残块中各层的排列中,如图“图 2.3
ResNet v2 的主要变化是:
* 使用`1 x 1 – 3 x 3 – 1 × 1``BN-ReLU-Conv2D`
* 使用`1 x 1 – 3 x 3 – 1 × 1`的栈`BN-ReLU-Conv2D`
* 批量标准化和 ReLU 激活先于二维卷积
![](img/B14853_02_10.png)
......@@ -738,7 +738,7 @@ ResNet v2 的准确率显示在下面的“表 2.3.1”中:
DenseNet 使用另一种方法攻击梯度消失的问题。 代替使用快捷方式连接,所有先前的特征映射都将成为下一层的输入。 上图显示了一个`Dense`块中密集互连的示例。
为简单起见,在此图中,我们仅显示四层。 注意,层`l`的输入是所有先前要素图的连接。 如果用操作`H`表示`BN-ReLU-Conv2D``x`),则层`l`的输出为:
为简单起见,在此图中,我们仅显示四层。 注意,层`l`的输入是所有先前特征映射的连接。 如果用操作`H`表示`BN-ReLU-Conv2D``x`),则层`l`的输出为:
`x[l] = H(x[0], x[1], x[2], x[l-1])`(公式 2.4.1)
......@@ -760,7 +760,7 @@ DenseNet 建议在`Dense`块之前加上`BN-ReLU-Conv2D`,以及许多是增长
然后`Bottleneck`层将 DenseNet 层修改为`BN-ReLU-Conv2D(1)-BN- ReLU-Conv2D(3)`,而不仅仅是`BN-ReLU-Conv2D(3)`。 为了清楚起见,我们将内核大小作为`Conv2D`的参数。 在瓶颈层,每个`Conv2D(3)`仅处理 4 个`k`特征映射,而不是`(l – 1) x k + k[0]`的,对于层`l`。 例如,对于 101 层网络,最后一个`Conv2D(3)`的输入仍然是`k = 12`而不是先前计算的 1224 的 48 个特征映射。
为了解决特征映射大小不匹配的问题,DenseNet 将深度网络划分为多个 Dense 块,这些块通过过渡层连接在一起,如图“图 2.4.3”所示。 在每个`Dense`块中,要素图的大小(即宽度和高度)将保持不变。
为了解决特征映射大小不匹配的问题,DenseNet 将深度网络划分为多个 Dense 块,这些块通过过渡层连接在一起,如图“图 2.4.3”所示。 在每个`Dense`块中,特征映射的大小(即宽度和高度)将保持不变。
过渡层的作用是在两个`Dense`块之间从一个特征映射大小过渡到较小的特征映射大小。 尺寸通常减少一半。 这是通过平均池化层完成的。 例如,默认值为`pool_size=2``AveragePooling2D`会将大小从`(64, 64, 256)`减小为`(32, 32, 256)`。 过渡层的输入是前一个`Dense`块中最后一个连接层的输出。
......@@ -768,7 +768,7 @@ DenseNet 建议在`Dense`块之前加上`BN-ReLU-Conv2D`,以及许多是增长
图 2.4.3:两个密集块之间的过渡层
但是,在将特征映射传递到平均池之前,使用`Conv2D(1)`将其数量减少某个压缩因子`0 < θ < 1`。DenseNet 在实验中使用`θ = 0.5`。 例如,如果先前`Dense`块的最后连接的输出是`(64, 64, 512)`,则在`Conv2D(1)`之后,要素图的新尺寸将是`(64, 64, 256)`。 当压缩和降维放在一起时,过渡层由`BN-Conv2D(1)-AveragePooling2D`层组成。 实际上,批量归一化在卷积层之前。
但是,在将特征映射传递到平均池之前,使用`Conv2D(1)`将其数量减少某个压缩因子`0 < θ < 1`。DenseNet 在实验中使用`θ = 0.5`。 例如,如果先前`Dense`块的最后连接的输出是`(64, 64, 512)`,则在`Conv2D(1)`之后,特征映射的新尺寸将是`(64, 64, 256)`。 当压缩和降维放在一起时,过渡层由`BN-Conv2D(1)-AveragePooling2D`层组成。 实际上,批量归一化在卷积层之前。
现在,我们已经涵盖了 DenseNet 的重要概念。 接下来,我们将为`tf.keras`中的 CIFAR10 数据集构建并验证 DenseNet-BC。
......
......@@ -81,7 +81,7 @@
首先,我们将通过构建编码器来实现自编码器。
“列表 3.2.1”显示了将 MNIST 数字压缩为 16 维潜在向量的编码器。 编码器是两个`Conv2D`栈。 最后阶段是具有 16 个单位的`Dense`层,以生成潜向量。
“列表 3.2.1”显示了将 MNIST 数字压缩为 16 维潜在向量的编码器。 编码器是两个`Conv2D`的栈。 最后阶段是具有 16 个单位的`Dense`层,以生成潜向量。
“列表 3.2.1”:`autoencoder-mnist-3.2.1.py`
......@@ -246,7 +246,7 @@ plt.show()
列表 3.2.1 中的解码器对潜在向量进行解压缩,以恢复 MNIST 数字。 解码器输入级是`Dense`层,它将接受潜在向量。 单位的数量等于从编码器保存的`Conv2D`输出尺寸的乘积。 这样做是为了便于我们调整`Dense``Dense`层的输出大小,以最终恢复原始 MNIST 图像尺寸。
解码器由三个`Conv2DTranspose`栈组成。 在我们的案例中,我们将使用**转置的 CNN**(有时称为**反卷积**),它是解码器中常用的。 我们可以将转置的 CNN(`Conv2DTranspose`)想象成 CNN 的逆过程。
解码器由三个`Conv2DTranspose`的栈组成。 在我们的案例中,我们将使用**转置的 CNN**(有时称为**反卷积**),它是解码器中常用的。 我们可以将转置的 CNN(`Conv2DTranspose`)想象成 CNN 的逆过程。
在一个简单的示例中,如果 CNN 将图像转换为特征映射,则转置的 CNN 将生成给定特征映射的图像。“图 3.2.2”显示了解码器模型:
......
......@@ -667,7 +667,7 @@ def train(models, data, params):
# 2\. StackedGAN
与 InfoGAN 一样,StackedGAN 提出了一种用于分解潜在表示的方法,以调节生成器输出。 但是,StackedGAN 使用不同的方法来解决此问题。 与其学习如何调节噪声以产生所需的输出,不如将 StackedGAN 分解为 GAN 栈。 每个 GAN 均以通常的区分对手的方式进行独立训练,并带有自己的潜在代码。
与 InfoGAN 一样,StackedGAN 提出了一种用于分解潜在表示的方法,以调节生成器输出。 但是,StackedGAN 使用不同的方法来解决此问题。 与其学习如何调节噪声以产生所需的输出,不如将 StackedGAN 分解为 GAN 栈。 每个 GAN 均以通常的区分对手的方式进行独立训练,并带有自己的潜在代码。
“图 6.2.1”向我们展示了 StackedGAN 在假设名人脸生成的背景下如何工作,假设已经训练了*编码器*网络对名人脸进行分类:
......@@ -679,19 +679,19 @@ def train(models, data, params):
StackedGAN 背后的想法是,如果我们想构建一个可生成假名人面孔的 GAN,则只需将*编码器*反转即可。 StackedGAN 由一堆更简单的 GAN 组成,`GAN[i]`,其中`i = 0 … n-1``n`个特征相对应。 每个`GAN[i]`学会反转其相应编码器`Encoder[i]`的过程。 例如,`GAN[0]`从假发型特征生成假名人脸,这是`Encoder[0]`处理的逆过程。
每个`GAN[i]`使用潜码`z[i]`,以调节其生成器输出。 例如,潜在代码`z[0]`可以将发型从卷曲更改为波浪形。 GAN 的栈也可以用作合成假名人面孔的对象,从而完成整个*编码器*的逆过程。 每个`GAN[i]``z[i]`的潜在代码都可以用来更改假名人面孔的特定属性。
每个`GAN[i]`使用潜码`z[i]`,以调节其生成器输出。 例如,潜在代码`z[0]`可以将发型从卷曲更改为波浪形。 GAN 的栈也可以用作合成假名人面孔的对象,从而完成整个*编码器*的逆过程。 每个`GAN[i]``z[i]`的潜在代码都可以用来更改假名人面孔的特定属性。
有了 StackedGAN 的工作原理的关键思想,让我们继续下一节,看看如何在`tf.keras`中实现它。
## Keras 中 StackedGAN 的实现
StackedGAN 的详细网络模型可以在“图 6.2.2”中看到。 为简洁起见,每个栈仅显示两个编码器 GAN。 该图最初可能看起来很复杂,但这只是一个编码器 GAN 的重复,这意味着如果我们了解如何训练一个编码器 GAN,其余的将使用相同的概念。
StackedGAN 的详细网络模型可以在“图 6.2.2”中看到。 为简洁起见,每个栈仅显示两个编码器 GAN。 该图最初可能看起来很复杂,但这只是一个编码器 GAN 的重复,这意味着如果我们了解如何训练一个编码器 GAN,其余的将使用相同的概念。
在本节中,我们假设 StackedGAN 是为 MNIST 数字生成而设计的。
![](img/B14853_06_09.png)
图 6.2.2:StackedGAN 包含编码器和 GAN 的栈。 对编码器进行预训练以执行分类。 `Generator[1]``G[1]`学会合成特征`f[1f]`,假标签`y[f]`和潜在代码`z[1f]``Generator[0]``G[0]`均使用这两个伪特征`f[1f]`生成伪图像和潜在代码`z[0f]`
图 6.2.2:StackedGAN 包含编码器和 GAN 的栈。 对编码器进行预训练以执行分类。 `Generator[1]``G[1]`学会合成特征`f[1f]`,假标签`y[f]`和潜在代码`z[1f]``Generator[0]``G[0]`均使用这两个伪特征`f[1f]`生成伪图像和潜在代码`z[0f]`
StackedGAN 以*编码器*开头。 它可能是训练有素的分类器,可以预测正确的标签。 可以将中间特征向量`f[1r]`用于 GAN 训练。 对于 MNIST,我们可以使用基于 CNN 的分类器,类似于在“第 1 章”,“Keras 高级深度学习”中讨论的分类器。
......@@ -1351,7 +1351,7 @@ StackedGAN 生成器可以通过以下方式进行定性验证:
“图 6.2.9”至“图 6.2.11”证明 StackedGAN 提供了对生成器输出属性的附加控制。 控件和属性为(标签,哪个数字),(`z0`,数字粗细)和(`z1`,数字倾斜度)。 从此示例中,我们可以控制其他可能的实验,例如:
* 从当前数量 2 增加栈中的元素数量
* 从当前数量 2 增加栈中的元素数量
* 像在 InfoGAN 中一样,减小代码`z[0]``z[1]`的尺寸
“图 6.2.12”显示了 InfoGAN 和 StackedGAN 的潜在代码之间的区别:
......
......@@ -718,7 +718,7 @@ def focal_loss_categorical(y_true, y_pred):
在基础网络之后可以应用其他特征提取模块。 每个特征提取器块都是`Conv2D(strides=2)-BN-ELU`的形式。 在特征提取块之后,特征映射的大小减半,并且过滤器的数量增加一倍。 例如,基本网络之后的第一个特征提取器块具有`20 x 15 x 2 n_filter`特征映射。 根据该特征映射,使用卷积层进行`n[2]`类和`n[2]`偏移量预测。`n[2] = 20 x 15 x 4 = 1,200`
可以继续添加具有类和偏移量预测变量的特征提取块的过程。 在前面的部分中,对于`640 x 480`的图像,最大可达`2 x 1 x 2^5 n_filter`特征映射产生`n[6]`类和`n[6]`抵消了其中`n[6] = 2 x 1 x 4 = 8`的预测。 到 6 层特征提取和预测块。 在第 6 个块之后,一个`640 x 480`图像的锚点地图预测总数为 9,648。
可以继续添加具有类和偏移量预测变量的特征提取块的过程。 在前面的部分中,对于`640 x 480`的图像,最大可达`2 x 1 x 2^5 n_filter`特征映射产生`n[6]`类和`n[6]`抵消了其中`n[6] = 2 x 1 x 4 = 8`的预测。 到 6 层特征提取和预测块。 在第 6 个块之后,一个`640 x 480`图像的锚点映射预测总数为 9,648。
在前面的部分中,锚定框的比例因子大小按降序排列:
......@@ -732,7 +732,7 @@ def focal_loss_categorical(y_true, y_pred):
![](img/B14853_11_052.png) (Equation 11.5.3)
如果要素图的宽度或高度不能被 2 整除(例如:15),则将应用天花板函数(例如:`ceil(15/2) = 8`)。 但是,在原始的 SSD [2]实现中,所使用的缩放因子被简化为`[0.2, 0.9]`范围,该范围通过缩放因子的数量或特征提取块的数量`n_layers`进行线性缩放:
如果特征映射的宽度或高度不能被 2 整除(例如:15),则将应用天花板函数(例如:`ceil(15/2) = 8`)。 但是,在原始的 SSD [2]实现中,所使用的缩放因子被简化为`[0.2, 0.9]`范围,该范围通过缩放因子的数量或特征提取块的数量`n_layers`进行线性缩放:
```py
s = np.linspace(0.2, 0.9, n_layers + 1)
......
......@@ -70,7 +70,7 @@
Zhao 等人的《金字塔场景解析网络(PSPNet)》进行了改进,进一步增强了我们的语义分割网络架构 [3]。 在 PSPNet 中,每个特征映射由另一个卷积层进一步处理。 此外,还使用了第一组特征映射。
FCN 和 PSPNet 都对要素金字塔进行了上采样,以达到与第一组要素图相同的大小。 之后,使用`Concatenate`层将所有上采样特征融合在一起。 然后级联层通过步长等于 2 的转置卷积处理两次,以恢复原始图像的宽度和高度。 最后,使用核大小为 1 且过滤器等于 4(换句话说,类别数)和`Softmax`层的转置卷积生成按像素分类预测。
FCN 和 PSPNet 都对要素金字塔进行了上采样,以达到与第一组特征映射相同的大小。 之后,使用`Concatenate`层将所有上采样特征融合在一起。 然后级联层通过步长等于 2 的转置卷积处理两次,以恢复原始图像的宽度和高度。 最后,使用核大小为 1 且过滤器等于 4(换句话说,类别数)和`Softmax`层的转置卷积生成按像素分类预测。
在下一节中,我们将讨论细分网络的`tf.keras`实现。 我们可以重用“第 11 章”,“对象检测”中的 SSD 中的某些网络块,以加快实现速度。
......
......@@ -510,7 +510,7 @@ gcloud ai-platform local train \
图 9.26:输出目录内容
要显示局部模型训练测试的结果,可以使用 TensorBoard 可视化工具。 使用 TensorBoard,您可以查看 TensorFlow 地图,编辑有关模型运行方式的定量数据以及显示其他数据,例如遍历图表的图片。 作为 TensorFlow 安装的一部分,可以使用 TensorBoard。
要显示局部模型训练测试的结果,可以使用 TensorBoard 可视化工具。 使用 TensorBoard,您可以查看 TensorFlow 映射,编辑有关模型运行方式的定量数据以及显示其他数据,例如遍历图表的图片。 作为 TensorFlow 安装的一部分,可以使用 TensorBoard。
3. 运行以下命令以启动`tensorboard`
......
......@@ -82,7 +82,7 @@ CNN 的总体思想是保持通过过滤器提取特征并增加激活图的深
来自 CS231n 的图像
下图显示了如何使用最大池化层来减小图像和要素图的大小:
下图显示了如何使用最大池化层来减小图像和特征映射的大小:
![](img/78bd04c3-e196-4683-a117-02a039840a43.png)
......@@ -619,9 +619,9 @@ YOLO 中使用的损失函数可分为四个部分:
《SSD:单发多框检测器》原始文件的链接可以[在以下网址找到](https://www.cs.unc.edu/~wliu/papers/ssd.pdf)
第一个特征映射集是从 VGG 16 架构的第 23 层提取的,大小为`38 x 38 x 512`(此处 512 是过滤器的深度或数量)。 第二组要素图的大小为`19 x 19 x 1,024`,适用于捕获稍大的对象。 进一步的特征映射集将尺寸减小到`10 x 10 x 512``5 x 5 x 256``3 x 3 x 256`,最后减小到`1 x 1 x 256`
第一个特征映射集是从 VGG 16 架构的第 23 层提取的,大小为`38 x 38 x 512`(此处 512 是过滤器的深度或数量)。 第二组特征映射的大小为`19 x 19 x 1,024`,适用于捕获稍大的对象。 进一步的特征映射集将尺寸减小到`10 x 10 x 512``5 x 5 x 256``3 x 3 x 256`,最后减小到`1 x 1 x 256`
为了进行预测,SSD 在提取的特征映射上使用`3 x 3 x d``d`表示过滤器的深度)卷积内核。 对于特征映射上的每个点,`3 x 3`内核输出边界框偏移量和类分数。 SSD 为特征映射中的每个点分配了默认框。 `3 x 3`卷积的工作是从覆盖对象的默认边界框预测四个偏移值。 除偏移量外,它还可以预测类别的`c`类别分数。 如果我们在每个位置都有`m x n`尺寸特征映射,并且在每个位置都有`k`默认边界框,则从该层做出的预测总数将为`(c + 4) x k x m x n`。 每个位置的默认框数通常为 4 到 6。 这些默认边界框的比例和大小由网络中最低和最高要素图的比例决定。 假设我们有`m`个特征映射; 然后,默认边界框的比例(`s[k]`)由以下公式给出:
为了进行预测,SSD 在提取的特征映射上使用`3 x 3 x d``d`表示过滤器的深度)卷积内核。 对于特征映射上的每个点,`3 x 3`内核输出边界框偏移量和类分数。 SSD 为特征映射中的每个点分配了默认框。 `3 x 3`卷积的工作是从覆盖对象的默认边界框预测四个偏移值。 除偏移量外,它还可以预测类别的`c`类别分数。 如果我们在每个位置都有`m x n`尺寸特征映射,并且在每个位置都有`k`默认边界框,则从该层做出的预测总数将为`(c + 4) x k x m x n`。 每个位置的默认框数通常为 4 到 6。 这些默认边界框的比例和大小由网络中最低和最高特征映射的比例决定。 假设我们有`m`个特征映射; 然后,默认边界框的比例(`s[k]`)由以下公式给出:
![](img/93c36209-1288-4964-b35e-b1a8b03d31fa.png)
......
......@@ -195,7 +195,7 @@ MobileNetV2 的核心架构仍然依赖于深度方向上可分离的卷积层
# 线性瓶颈层
在 MobileNet 中,`1 x 1`点向卷积负责增加通过网络的特征映射的深度。 MobileNetV2 中的线性瓶颈层执行相反的工作。 它实际上减少了特征映射的深度。 为了保留层中的非线性,ReLU 激活函数会降低负值。 这导致信道中的信息丢失。 为了解决这个问题,要素地图中使用了许多通道,因此很有可能一个通道中的信息丢失会保留在任何其他通道中。
在 MobileNet 中,`1 x 1`点向卷积负责增加通过网络的特征映射的深度。 MobileNetV2 中的线性瓶颈层执行相反的工作。 它实际上减少了特征映射的深度。 为了保留层中的非线性,ReLU 激活函数会降低负值。 这导致信道中的信息丢失。 为了解决这个问题,特征映射中使用了许多通道,因此很有可能一个通道中的信息丢失会保留在任何其他通道中。
但是,MobileNetV2 的作者证明,如果将输入通道投影到低维空间而不是高维空间,则 ReLU 激活能够保留来自输入通道的所有信息。 这是一个重大突破! 作者还提供原始文件中的补充材料来证明这一点。
......
......@@ -2,7 +2,7 @@
深度学习技术可用于开发智能 Web 应用。 在过去的几年中,已经发现在其产品和业务中采用深度学习技术的公司数量急剧增长。 提供人工智能和基于深度学习的解决方案的新兴企业数量激增。 本书介绍了用于使用 Python 在 Web 开发中实现深度学习的众多工具和技术实践。
首先,您将学习机器学习的基础知识,重点是深度学习和神经网络的基础,以及它们的常见变体,例如卷积神经网络,以及如何将它们集成到网站中,其前端使用不同标准 Web 技术栈构建。 您将通过为自定义模型创建 REST API,使用 Django 和 Flask 等 Python 库来创建支持深度学习的 Web 应用。 您将为 Google Cloud 和 AWS 上基于深度学习的 Web 部署设置云环境,并获得有关如何使用经过实践检验的深度学习 API 的指导。 此外,您将使用 Microsoft 的 Intelligent Emotion API,该 API 可以从一张脸部图片中检测出人类的情感。 您还将掌握部署真实世界的网站的知识,并获得丰富的见解,可以使用 reCaptcha 和 Cloudflare 保护这些网站,从而获得可靠的体验。 最后,您将使用自然语言处理从用户评论中推荐餐馆,并通过 Dialogflow 将语音 UX 集成到您的网页上。
首先,您将学习机器学习的基础知识,重点是深度学习和神经网络的基础,以及它们的常见变体,例如卷积神经网络,以及如何将它们集成到网站中,其前端使用不同标准 Web 技术栈构建。 您将通过为自定义模型创建 REST API,使用 Django 和 Flask 等 Python 库来创建支持深度学习的 Web 应用。 您将为 Google Cloud 和 AWS 上基于深度学习的 Web 部署设置云环境,并获得有关如何使用经过实践检验的深度学习 API 的指导。 此外,您将使用 Microsoft 的 Intelligent Emotion API,该 API 可以从一张脸部图片中检测出人类的情感。 您还将掌握部署真实世界的网站的知识,并获得丰富的见解,可以使用 reCaptcha 和 Cloudflare 保护这些网站,从而获得可靠的体验。 最后,您将使用自然语言处理从用户评论中推荐餐馆,并通过 Dialogflow 将语音 UX 集成到您的网页上。
到本书结尾,您将能够借助最佳工具和实践来部署智能 Web 应用和网站。
......@@ -18,7 +18,7 @@
“第 2 章”,“使用 Python 进行深度学习入门”,介绍了与深度学习相关的基本概念和术语,以及如何使用深度学习来构建具有不同深度学习库的简单 Python Web 应用。
“第 3 章”,“创建您的第一个深度学习 Web 应用”讨论了一些专门用于利用深度学习的有关 Web 应用结构的重要概念。 然后继续讨论理解数据集的方法。 本章还显示了如何实现和改进简单的神经网络,以及如何将其包装到用于开发简单 Web 应用的 API 中。 然后,我们继续展示如何使用不同的标准 Web 技术栈来实现 API。
“第 3 章”,“创建您的第一个深度学习 Web 应用”讨论了一些专门用于利用深度学习的有关 Web 应用结构的重要概念。 然后继续讨论理解数据集的方法。 本章还显示了如何实现和改进简单的神经网络,以及如何将其包装到用于开发简单 Web 应用的 API 中。 然后,我们继续展示如何使用不同的标准 Web 技术栈来实现 API。
“第 4 章”,“TensorFlow.js 入门”介绍了最受欢迎的深度学习 JavaScript 库-TensorFlow.js(Tf.js)。 它简要概述了 TensorFlow.js 是什么以及它在浏览器中能够执行的操作。 此外,本章还介绍了如何使用 TensorFlow.js 使用预训练的模型,并使用它构建一个简单的 Web 应用。
......
......@@ -419,7 +419,7 @@ Facebook Messenger 的漫游器平台在向公众开放的前 17 个月内创建
自从互联网发明以来,当今的 Web 应用每时每刻都会生成大量日志。 即使将鼠标指针闲置在网页上,也可能会报告给 Google Analytics(分析)仪表板,从该站点上,网站管理员可以查看用户正在查看哪些页面以及他们在页面上花费了多少时间。 同样,用户在页面之间采取的流量将是一个非常有趣的指标。
最早的网络分析工具仅能衡量网页点击量,能够创建一个地图来访问给定页面的次数以及该页面是一个唯一用户的次数,但除非提供有关用户访问模式的信息,否则它们几乎无法提供任何信息。它们经过了专门的硬编码,将以非常笼统的方式呈现,并且从来都不是特定于网站的。 正在向进行电子商务的公司提供与向个人网站提供的分析相同的形式。
最早的网络分析工具仅能衡量网页点击量,能够创建一个映射来访问给定页面的次数以及该页面是一个唯一用户的次数,但除非提供有关用户访问模式的信息,否则它们几乎无法提供任何信息。它们经过了专门的硬编码,将以非常笼统的方式呈现,并且从来都不是特定于网站的。 正在向进行电子商务的公司提供与向个人网站提供的分析相同的形式。
随着 AI 在网络分析领域带来的革命,如今部署人工智能功能的工具可以对网站的表现做出未来的预测,甚至建议删除或添加网页上的特定内容以提高用户对该页面的参与度 。
......
......@@ -41,7 +41,7 @@ SSD 的主要功能概述如下:
* SSD 原始论文使用 VGG16 作为基础网络提取要素层,但也可以考虑使用其他网络,例如 Inception 和 ResNet。
* SSD 在基础网络之上添加了另外六个功能层,由`conv4_3``conv7``fc7`),`conv8_2``conv9_2``conv10_2``conv11_2`组成,用于对象检测。
* 一组默认框与每个要素图单元相关联,因此默认框位置相对于要素图单元是固定的。 每个默认框都会预测`c`类中每个类别的得分以及相对于地面真实情况的四个偏移,从而产生`(c + 4)k`过滤器。 这些过滤器应用于特征映射(大小为`m x n`),产生`(c + 4)kmn`输出。 下表说明了这一点。 SSD 的独特之处在于默认框适用于不同分辨率的多个特征映射:
* 一组默认框与每个特征映射单元相关联,因此默认框位置相对于特征映射单元是固定的。 每个默认框都会预测`c`类中每个类别的得分以及相对于地面真实情况的四个偏移,从而产生`(c + 4)k`过滤器。 这些过滤器应用于特征映射(大小为`m x n`),产生`(c + 4)kmn`输出。 下表说明了这一点。 SSD 的独特之处在于默认框适用于不同分辨率的多个特征映射:
| **层名称** | **检测** | **过滤器输出** |
| --- | --- | --- |
......@@ -55,7 +55,7 @@ SSD 的主要功能概述如下:
* 默认框的设计是使用比例因子和宽高比创建的,因此特定尺寸(基于真实情况预测)的特征映射与对象的特定比例相匹配。
* 比例范围可以从`smin(0.2)``smax(0.95)`线性变化,而纵横比(`ar`)可以取五个值(`1``2``0.5``3.0``0.33`) ,其中`k``1``m`之间变化。
* 对于长宽比`1`,添加了一个附加的默认框。 因此,每个要素地图位置最多有六个默认框。
* 对于长宽比`1`,添加了一个附加的默认框。 因此,每个特征映射位置最多有六个默认框。
* 默认框中心的坐标为`((i+0.5)/|fk|, (j+0.5)/|fk|)`,其中`|fk|``kth`正方形特征映射的大小,`i``j`的值从`0``|fk|`不等。 对六个默认框的每个重复此操作。
* SSD 通过将给定比例和宽高比的默认框与地面真实物体的默认框匹配,并消除不匹配的框,从而预测各种物体的大小和形状。 默认框与地面真值对象的匹配是通过 Jaccard 重叠(也称为**交并比****IOU**)完成的,这在第 7 章,“使用 YOLO 进行对象检测”中。 例如,如果图像由`human``bus`组成并且都具有不同的宽高比和比例,则 SSD 显然可以识别两者。 问题出现在两个类别彼此接近且纵横比相同时,我们将在后面看到。
* 使用 R-CNN,区域提议网络执行筛选以限制被视为 2K 的样本数量。 另一方面,SSD 没有区域提议,因此它会生成大量的边界框(如我们先前所知,为 8,732 个),其中许多都是负面示例。 SSD 拒绝了额外的负面示例,它使用硬性负面挖掘来使正面与负面之间的平衡保持至多 3:1。 硬否定挖掘是一种用于使用置信度损失进行排序以便保留最高值的技术。
......
......@@ -70,7 +70,7 @@ CNN 的图像过滤和处理方法包括执行多种操作,所有这些操作
![](img/f7b861f9-ab93-4a27-aecc-567fe346bf5e.png)
通常,在卷积层中,有许多执行不同类型边缘检测的过滤器。 在前面的示例中,我们有 32 个过滤器,这将导致 32 个不同的堆栈,每个堆栈由`5 x 5`层组成。
通常,在卷积层中,有许多执行不同类型边缘检测的过滤器。 在前面的示例中,我们有 32 个过滤器,这将导致 32 个不同的栈,每个栈由`5 x 5`层组成。
`3 x 3`过滤器将在本书的其余部分中广泛用于神经网络开发。 例如,您将在 ResNet 和 Inception 层中看到大量使用它,我们将在“第 5 章”,“神经网络架构和模型”中进行讨论。 TensorFlow 中可以将大小为`3 x 3`的 32 个过滤器表示为`.tf.keras.layers.Conv2D(32, (3,3))`。 在本章的后面,您将学习如何将此卷积与 CNN 的其他层一起使用。
......@@ -109,9 +109,9 @@ CNN 的图像过滤和处理方法包括执行多种操作,所有这些操作
# 填充
填充用于保留要素图的大小。 通过卷积,可能会发生两个问题,并且填充会同时解决两个问题:
填充用于保留特征映射的大小。 通过卷积,可能会发生两个问题,并且填充会同时解决两个问题:
* 每次卷积操作时,要素图的大小都会缩小。 例如,在上图中,由于卷积,一个`7 x 7`的特征映射缩小为`5 x 5`
* 每次卷积操作时,特征映射的大小都会缩小。 例如,在上图中,由于卷积,一个`7 x 7`的特征映射缩小为`5 x 5`
* 由于边缘上的像素仅更改一次,因此边缘上的信息会丢失,而中间的像素会通过多次卷积操作进行多次更改。
下图显示了在`7 x 7`输入图像上使用大小为 1 的填充操作:
......
......@@ -421,7 +421,7 @@ R-CNN 和 Fast R-CNN 都依赖于选择性搜索方法来开发 2,000 个区域
| --- | --- | --- | --- |
| 输入值 | 图片 | 图片 | 图片 |
| 输入图像处理 | 基于像素相似度的图像分割 | 输入图像被馈送到 CNN 以生成卷积特征映射。 | 输入图像被馈送到 CNN 以生成卷积特征映射。 |
| 区域提议 | 使用选择性搜索在分割的图像上生成 2K 区域提议。 | 使用卷积特征映射的选择性搜索生成 2K 区域提议。 | 区域提议是使用**区域提议网络****RPN**)生成的。 这个 CNN 使用`60 x 40`的滑动窗口,用于带有 9 个锚点框(3 个比例和 3 个宽高比)的要素地图的每个位置。 |
| 区域提议 | 使用选择性搜索在分割的图像上生成 2K 区域提议。 | 使用卷积特征映射的选择性搜索生成 2K 区域提议。 | 区域提议是使用**区域提议网络****RPN**)生成的。 这个 CNN 使用`60 x 40`的滑动窗口,用于带有 9 个锚点框(3 个比例和 3 个宽高比)的特征映射的每个位置。 |
| 变形为固定大小 | 从区域提议中,每个区域都将变形为固定大小,以输入到 CNN。 | 使用 RoI 池化层中的最大池化,将区域提议扭曲为固定大小的正方形。 | 使用 RoI 池化层将区域提议扭曲为固定大小的正方形。 |
| 特征提取 | 每次将每个图像固定大小的 2K 变形区域提议送入 CNN。 | 2K 扭曲区域被馈送到两个分支,每个分支都包含一个全连接层。 | 2K 扭曲区域被馈送到全连接层。 |
| 侦测 | CNN 的输出传递到 SVM,以分类到边界框回归器以生成边界框。 | 全连接层的一个输出传递到 softmax 层进行分类,另一个输出传递到包围盒回归器以生成包围盒。 | 全连接层的一个输出传递到 softmax 层进行分类,另一个输出传递到包围盒回归器以生成包围盒。 |
......@@ -431,7 +431,7 @@ R-CNN 和 Fast R-CNN 都依赖于选择性搜索方法来开发 2,000 个区域
| 区域提议和检测 | 区域提议和检测是分离的。 | 区域提议和检测是分离的。 | 区域提议和检测是耦合的。 |
| 训练时间 | 84 小时 | 9 小时 | 150 小时 |
| 测试时间 | 49 秒 | 2.43 秒 | 0.2 秒 |
| 地图(VOC 2007) | 66 | 66.9 | 66.9 |
| mAP(VOC 2007) | 66 | 66.9 | 66.9 |
上表清楚地显示了 R-CNN 算法的发展以及用于提高 R-CNN 算法准确率的方法。 这是我们从上表中学到的一些关键点:
......
......@@ -33,7 +33,7 @@ DeepLabV3 的架构基于两种神经网络-空洞卷积和编码器/解码器
# 空洞卷积
我们在“第 4 章”,“图像深度学习”中介绍了卷积的概念,但是我们没有涉及各种空洞卷积。空洞卷积,也称为膨胀卷积,增加了卷积的视野。 传统的 CNN 使用最大池化和跨步来快速减小层的大小,但这样做也会降低要素图的空间分辨率。空洞卷积是一种用于解决此问题的方法。 它通过使用 Atrous 值修改步幅来实现此目的,从而有效地更改了过滤器的值字段,如下图所示:
我们在“第 4 章”,“图像深度学习”中介绍了卷积的概念,但是我们没有涉及各种空洞卷积。空洞卷积,也称为膨胀卷积,增加了卷积的视野。 传统的 CNN 使用最大池化和跨步来快速减小层的大小,但这样做也会降低特征映射的空间分辨率。空洞卷积是一种用于解决此问题的方法。 它通过使用 Atrous 值修改步幅来实现此目的,从而有效地更改了过滤器的值字段,如下图所示:
![](img/add28c06-3e36-4992-90a1-874e884951f1.png)
......
......@@ -516,14 +516,14 @@ Future chooseImageGallery() async {
现在,让我们添加一个小部件以显示在上一节中选择的图像,如下所示:
1. 我们将使用小部件列表,从图库中选择的图像以及彼此堆叠或重叠的预测结果显示在屏幕上。 因此,我们首先声明一个空的小部件列表,其中将包含栈的所有子级。 另外,我们声明一个`size`实例,以使用`MediaQuery`类查询包含应用的窗口的大小,如下所示:
1. 我们将使用小部件列表,从图库中选择的图像以及彼此堆叠或重叠的预测结果显示在屏幕上。 因此,我们首先声明一个空的小部件列表,其中将包含栈的所有子级。 另外,我们声明一个`size`实例,以使用`MediaQuery`类查询包含应用的窗口的大小,如下所示:
```py
List<Widget> stackChildren = [];
Size size = MediaQuery.of(context).size;
```
2. 现在,将图像添加为栈的第一个子项,如下所示:
2. 现在,将图像添加为栈的第一个子项,如下所示:
```py
stackChildren.add(Positioned(
......@@ -534,11 +534,11 @@ stackChildren.add(Positioned(
));
```
`Positioned`类用于控制堆栈的子代的位置。 在这里,通过指定`top``left``width`属性的值。 `top``left`值分别指定子项的顶部和左侧边缘与堆栈顶部和左侧边缘的距离,此处为 0,即设备屏幕的左上角 。 `width`值指定子项的宽度-此处是包含应用的窗口的宽度,这意味着图像将占据整个宽度。
`Positioned`类用于控制栈的子代的位置。 在这里,通过指定`top``left``width`属性的值。 `top``left`值分别指定子项的顶部和左侧边缘与栈顶部和左侧边缘的距离,此处为 0,即设备屏幕的左上角 。 `width`值指定子项的宽度-此处是包含应用的窗口的宽度,这意味着图像将占据整个宽度。
3. 接下来,我们将添加子项,该子项将是一个文本,如果`_image`的值为`null`,则表示未选择任何图像; 否则,它包含用户选择的图像。
为了在屏幕上显示栈,我们将`stackChildren`列表添加为`build()`方法返回的`Scaffold`的主体,如下所示:
为了在屏幕上显示栈,我们将`stackChildren`列表添加为`build()`方法返回的`Scaffold`的主体,如下所示:
```py
return Scaffold(
......@@ -800,7 +800,7 @@ Future chooseImageGallery() async {
# 用结果更新用户界面
在上一节“创建用户界面”中,我们通过向`stackChildren`添加一个额外的子代来更新 UI,以显示用户选择的图像。 现在,我们将另一个子项添加到栈中以显示图像分析的结果,如下所示:
在上一节“创建用户界面”中,我们通过向`stackChildren`添加一个额外的子代来更新 UI,以显示用户选择的图像。 现在,我们将另一个子项添加到栈中以显示图像分析的结果,如下所示:
1. 首先,我们将添加 Cloud Vision API 的结果,如下所示:
......@@ -823,7 +823,7 @@ stackChildren.add( Center (
);
```
回想一下,请求的 JSON 响应已被解析,格式化并存储在`str`变量中。 在这里,我们使用`str`的值创建具有指定颜色和背景的`Text`。 然后,我们将此`Text`作为子级添加到列中,并对齐`Text`以显示在屏幕中央。 最后,我们将整个格式包装在`stackChildren.add()`周围,以将其添加到 UI 元素栈中。
回想一下,请求的 JSON 响应已被解析,格式化并存储在`str`变量中。 在这里,我们使用`str`的值创建具有指定颜色和背景的`Text`。 然后,我们将此`Text`作为子级添加到列中,并对齐`Text`以显示在屏幕中央。 最后,我们将整个格式包装在`stackChildren.add()`周围,以将其添加到 UI 元素栈中。
2. 接下来,我们将添加 TensorFlow Lite 的结果,如下所示:
......@@ -848,7 +848,7 @@ child: Column(
`_recognitions`列表中存储的 TensorFlow Lite 模型的结果逐元素进行迭代,并映射到使用`.map()`指定的列表。 列表中的每个元素都将进一步转换为`Text`,并作为与屏幕中心对齐的列子元素添加。
此外,请注意,需要将 Cloud Vision API 的输出或 TensorFlow Lite 模型的输出添加到栈中。 为了确保这一点,我们将前面的代码包装在`if-else`块中,这样,如果在构造器中传递的值(即`modelChosen`)为 0,则添加前者的输出;如果该值是,则添加后者的输出。 是 1。
此外,请注意,需要将 Cloud Vision API 的输出或 TensorFlow Lite 模型的输出添加到栈中。 为了确保这一点,我们将前面的代码包装在`if-else`块中,这样,如果在构造器中传递的值(即`modelChosen`)为 0,则添加前者的输出;如果该值是,则添加后者的输出。 是 1。
3. 最后,在各种图像集上运行 Cloud Vision API 将提供不同的输出。 以下屏幕快照显示了一些示例:
......
......@@ -230,7 +230,7 @@ enum FormMode { SIGNIN, SIGNUP }
}
```
`build()`内部,添加包含应用标题的`AppBar`变量后,我们返回一个支架。 支架的主体包含一个带有子项的栈,这些子项是`_createBody()``_createCircularProgress()` 函数调用返回的小部件。
`build()`内部,添加包含应用标题的`AppBar`变量后,我们返回一个支架。 支架的主体包含一个带有子项的栈,这些子项是`_createBody()``_createCircularProgress()` 函数调用返回的小部件。
现在,我们已经准备好应用的主要 UI 结构。
......@@ -919,7 +919,7 @@ Widget _createSigninButton() {
}
```
5. 最后,我们将`_createRecaptcha()`添加到`build()`内部的主体栈中:
5. 最后,我们将`_createRecaptcha()`添加到`build()`内部的主体栈中:
```py
@override
......
......@@ -971,7 +971,7 @@ HashMap board = new HashMap<String, String>();
}
```
在前面的方法中,我们使用一个简单的嵌套循环通过从`a``h`的所有行以及从 1 到 8 的所有列进行遍历,使用空白字符串初始化哈希地图板的所有索引。 如“步骤 2”中所述,将其放置在其初始位置上。 为了确保在初始化棋盘时重新绘制 UI,我们将整个分配放在`setState()`中。
在前面的方法中,我们使用一个简单的嵌套循环通过从`a``h`的所有行以及从 1 到 8 的所有列进行遍历,使用空白字符串初始化哈希映射板的所有索引。 如“步骤 2”中所述,将其放置在其初始位置上。 为了确保在初始化棋盘时重新绘制 UI,我们将整个分配放在`setState()`中。
4. 屏幕启动后,板将被初始化。 为了确保这一点,我们需要覆盖`initState()`并从那里调用`initializeBoard()`
......@@ -1092,7 +1092,7 @@ Widget mapImages(String squareName) {
在前面的代码中,我们迭代了`squareList`内部的每一行,这些行表示为一个列表。 我们通过调用`buildRow()`来构建行,并将它们作为子级添加到列中。 此列作为子级添加到容器中并返回。
6. 现在,让我们将所有片段以及实际的棋盘图像放到屏幕上。 我们将覆盖`build()`方法,以构建由棋盘图像及其碎片组成的小部件栈:
6. 现在,让我们将所有片段以及实际的棋盘图像放到屏幕上。 我们将覆盖`build()`方法,以构建由棋盘图像及其碎片组成的小部件栈:
```py
@override
......@@ -1114,7 +1114,7 @@ Widget mapImages(String squareName) {
}
```
前面的方法使用容器来构建堆栈,该容器添加存储在`assets`文件夹中的棋盘图像。 堆栈的下一个子项是居中对齐的容器,其中所有片段图像都通过对`buildChessBoard()`的调用以小部件的形式添加为行和列包装。 整个堆栈作为子级添加到容器中并返回,以便出现在屏幕上。
前面的方法使用容器来构建栈,该容器添加存储在`assets`文件夹中的棋盘图像。 栈的下一个子项是居中对齐的容器,其中所有片段图像都通过对`buildChessBoard()`的调用以小部件的形式添加为行和列包装。 整个栈作为子级添加到容器中并返回,以便出现在屏幕上。
此时,应用显示棋盘,以及所有放置在其初始位置的棋子。 如下所示:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册