diff --git a/docs/dl-tf-2e-zh/ch04.md b/docs/dl-tf-2e-zh/ch04.md index 60f9e77ab728c6b31283b08465f8b3cbc35e238e..3456f3ac6b14f02cf796233b037c5d1ac5ecbf32 100644 --- a/docs/dl-tf-2e-zh/ch04.md +++ b/docs/dl-tf-2e-zh/ch04.md @@ -1,12 +1,12 @@ # 四、CNN 实战 -以前面提到的 5×5 输入矩阵为例,CNN 的输入层由 25 个神经元(5×5)组成,其任务是获取与每个像素对应的输入值并将其转移到下一层。 +以前面提到的`5×5`输入矩阵为例,CNN 的输入层由 25 个神经元(`5×5`)组成,其任务是获取与每个像素对应的输入值并将其转移到下一层。 在多层网络中,输入层中所有神经元的输出将连接到隐藏层(完全连接层)中的每个神经元。然而,在 CNN 网络中,上面定义的连接方案和我们要描述的卷积层是显着不同的。正如您可能猜到的,这是层的主要类型:在 CNN 中使用这些层中的一个或多个是必不可少的。 -在卷积层中,每个神经元连接到输入区域的某个区域,称为感受野。例如,使用 3×3 内核滤波器,每个神经元将具有偏置并且 9 个权重(3×3)连接到单个感受野。为了有效地识别图像,我们需要将各种不同的内核过滤器应用于相同的感受野,因为每个过滤器应该识别来自图像的不同特征。识别相同特征的神经元集定义了单个特征映射。 +在卷积层中,每个神经元连接到输入区域的某个区域,称为感受野。例如,使用`3×3`内核滤波器,每个神经元将具有偏置并且 9 个权重(`3×3`)连接到单个感受野。为了有效地识别图像,我们需要将各种不同的内核过滤器应用于相同的感受野,因为每个过滤器应该识别来自图像的不同特征。识别相同特征的神经元集定义了单个特征映射。 -下图显示了运行中的 CNN 架构:28×28 输入图像将由一个由 28x28x32 特征映射组成的卷积层进行分析。该图还显示了一个感受野和一个 3×3 内核过滤器: +下图显示了运行中的 CNN 架构:`28×28`输入图像将由一个由`28x28x32`特征映射组成的卷积层进行分析。该图还显示了一个感受野和一个`3×3`内核过滤器: ![CNNs in action](img/B09698_04_05.jpg) @@ -34,13 +34,13 @@ LeNet5 架构由三个卷积层和两个交替序列池化层组成。最后两 # 逐步实现 LeNet-5 -在本节中,我们将学习如何构建 LeNet-5 架构来对 MNIST 数据集中的图像进行分类。下图显示了数据如何在前两个卷积层中流动:使用滤波器权重在第一个卷积层中处理输入图像。这导致 32 个新图像,一个用于卷积层中的每个滤波器。图像也通过合并操作进行下采样,因此图像分辨率从 28×28 降低到 14×14。然后在第二卷积层中处理这 32 个较小的图像。我们需要为这 32 个图像中的每一个再次使用滤波器权重,并且我们需要该层的每个输出通道的滤波器权重。通过合并操作再次对图像进行下采样,使得图像分辨率从 14×14 减小到 7×7。此卷积层的特征总数为 64。 +在本节中,我们将学习如何构建 LeNet-5 架构来对 MNIST 数据集中的图像进行分类。下图显示了数据如何在前两个卷积层中流动:使用滤波器权重在第一个卷积层中处理输入图像。这导致 32 个新图像,一个用于卷积层中的每个滤波器。图像也通过合并操作进行下采样,因此图像分辨率从`28×28`降低到`14×14`。然后在第二卷积层中处理这 32 个较小的图像。我们需要为这 32 个图像中的每一个再次使用滤波器权重,并且我们需要该层的每个输出通道的滤波器权重。通过合并操作再次对图像进行下采样,使得图像分辨率从`14×14`减小到`7×7`。此卷积层的特征总数为 64。 ![Implementing a LeNet-5 step by step](img/B09698_04_07.jpg) 图 7:前两个卷积层的数据流 -通过(3×3)第三卷积层再次过滤 64 个结果图像。没有对该层应用池操作。第三卷积层的输出是 128×7×7 像素图像。然后将这些图像展平为单个向量,长度为 4×4×128 = 2048,其用作完全连接层的输入。 +通过(`3×3`)第三卷积层再次过滤 64 个结果图像。没有对该层应用池操作。第三卷积层的输出是`128×7×7`像素图像。然后将这些图像展平为单个向量,长度为`4×4×128 = 2048`,其用作完全连接层的输入。 LeNet-5 的输出层由 625 个神经元作为输入(即完全连接层的输出)和 10 个神经元作为输出,用于确定图像的类别,该数字在图片。 @@ -120,25 +120,25 @@ def init_weights(shape): return tf.Variable(tf.random_normal(shape, stddev=0.01)) ``` -第一卷积层的每个神经元被卷积为输入张量的小子集,尺寸为 3×3×1。值`32`只是我们为第一层考虑的特征图的数量。然后定义权重`w`: +第一卷积层的每个神经元被卷积为输入张量的小子集,尺寸为`3×3×1`。值`32`只是我们为第一层考虑的特征图的数量。然后定义权重`w`: ```py w = init_weights([3, 3, 1, 32]) ``` -然后输入的数量增加到`32`,这意味着第二卷积层中的每个神经元被卷积到第一卷积层的 3×3×32 个神经元。 `w2`权重如下: +然后输入的数量增加到`32`,这意味着第二卷积层中的每个神经元被卷积到第一卷积层的`3×3×32`个神经元。 `w2`权重如下: ```py w2 = init_weights([3, 3, 32, 64]) ``` -值`64`表示获得的输出特征的数量。第三个卷积层被卷积为前一层的 3x3x64 个神经元,而`128`是结果特征。 +值`64`表示获得的输出特征的数量。第三个卷积层被卷积为前一层的`3x3x64`个神经元,而`128`是结果特征。 ```py w3 = init_weights([3, 3, 64, 128]) ``` -第四层完全连接并接收 128x4x4 输入,而输出等于`625`: +第四层完全连接并接收`128x4x4`输入,而输出等于`625`: ```py w4 = init_weights([128 * 4 * 4, 625]) @@ -157,14 +157,14 @@ p_keep_conv = tf.placeholder("float") p_keep_hidden = tf.placeholder("float") ``` -是时候定义网络模型了。就像网络的权重定义一样,它将是一个函数。它接收`X`张量,权重张量和 dropout 参数作为卷积和完全连接层的输入: +是时候定义网络模型了。就像网络的权重定义一样,它将是一个函数。它接收`X`张量,权重张量和丢弃参数作为卷积和完全连接层的输入: ```py def model(X, w, w2, w3, w4, w_o, p_keep_conv, p_keep_hidden): ``` -`tf.nn.conv2d()`执行 TensorFlow 操作进行卷积。请注意,所有尺寸的`strides`都设置为 1.实际上,第一步和最后一步必须始终为 1,因为第一步是图像编号,最后一步是输入通道。 padding 参数设置为`'SAME'`,这意味着输入图像用零填充,因此输出的大小相同: +`tf.nn.conv2d()`执行 TensorFlow 操作进行卷积。请注意,所有尺寸的`strides`都设置为 1。实际上,第一步和最后一步必须始终为 1,因为第一步是图像编号,最后一步是输入通道。 `padding`参数设置为`'SAME'`,这意味着输入图像用零填充,因此输出的大小相同: ```py conv1 = tf.nn.conv2d(X, w,strides=[1, 1, 1, 1],\ @@ -185,7 +185,7 @@ conv1 = tf.nn.conv2d(X, w,strides=[1, 1, 1, 1],\ padding='SAME') ``` -这是一个 2×2 最大池,这意味着我们正在检查 2×2 窗口并在每个窗口中选择最大值。然后我们将 2 个像素移动到下一个窗口。我们尝试通过`tf.nn.dropout()`函数减少过拟合,我们传递`conv1`层和`p_keep_conv`概率值: +这是一个`2×2`最大池,这意味着我们正在检查`2×2`窗口并在每个窗口中选择最大值。然后我们将 2 个像素移动到下一个窗口。我们尝试通过`tf.nn.dropout()`函数减少过拟合,我们传递`conv1`层和`p_keep_conv`概率值: ```py conv1 = tf.nn.dropout(conv1, p_keep_conv) @@ -221,13 +221,13 @@ conv1 = tf.nn.conv2d(X, w,strides=[1, 1, 1, 1],\ [-1, w4.get_shape().as_list()[0]]) ``` -dropout 函数再次用于减少过拟合: +`dropout`函数再次用于减少过拟合: ```py FC_layer = tf.nn.dropout(FC_layer, p_keep_conv) ``` -输出层接收`FC_layer`和`w4`权重张量作为输入。应用 ReLU 和 Dropout 运算符: +输出层接收`FC_layer`和`w4`权重张量作为输入。应用 ReLU 和丢弃运算符: ```py output_layer = tf.nn.relu(tf.matmul(FC_layer, w4)) @@ -267,7 +267,7 @@ cost = tf.reduce_mean(Y_) optimizer = tf.train.RMSPropOptimizer(0.001, 0.9).minimize(cost) ``` -基本上,通用 SGD 算法存在一个问题,即学习率必须以 1 / T(其中 T 是迭代次数)进行缩放以实现收敛。 RMSProp 尝试通过自动调整步长来解决这个问题,以使步长与梯度相同。随着平均梯度变小,SGD 更新中的系数变得更大以进行补偿。 +基本上,通用 SGD 算法存在一个问题,即学习率必须以`1 / T`(其中`T`是迭代次数)进行缩放以实现收敛。 RMSProp 尝试通过自动调整步长来解决这个问题,以使步长与梯度相同。随着平均梯度变小,SGD 更新中的系数变得更大以进行补偿。 ### 注意 @@ -300,7 +300,7 @@ with tf.Session() as sess: batch_size)) ``` -将批量放入`feed_dict`中,并在图中为占位符变量指定相应的名称。我们现在可以使用这批训练数据运行优化器。 TensorFlow 将 feed 中的变量分配给占位符变量,然后运行优化程序: +将批量放入`feed_dict`中,并在图中为占位符变量指定相应的名称。我们现在可以使用这批训练数据运行优化器。 TensorFlow 将馈送中的变量分配给占位符变量,然后运行优化程序: ```py for start, end in training_batch: @@ -392,9 +392,9 @@ AlexNet 的架构如下图所示: 在 AlexNet 架构中,有八层具有可训练参数:一系列五个连续卷积层,后面是三个完全连接的层。每个卷积层之后是 ReLU 层,并且可选地还有最大池层,尤其是在网络的开始处,以便减少网络占用的空间量。 -所有池层都有 3x3 扩展区域,步长率为 2:这意味着您始终使用重叠池。这是因为与没有重叠的普通池相比,这种类型的池提供了稍好的网络表现。在网络的开始,在池化层和下一个卷积层之间,总是使用几个 LRN 标准化层:经过一些测试,可以看出它们倾向于减少网络错误。 +所有池层都有`3x3`扩展区域,步长率为 2:这意味着您始终使用重叠池。这是因为与没有重叠的普通池相比,这种类型的池提供了稍好的网络表现。在网络的开始,在池化层和下一个卷积层之间,总是使用几个 LRN 标准化层:经过一些测试,可以看出它们倾向于减少网络错误。 -前两个完全连接的层拥有 4,096 个神经元,而最后一个拥有 1,000 个单元,对应于 ImageNet 数据集中的类数。考虑到完全连接层中的大量连接,在每对完全连接的层之间添加了比率为 0.5 的 dropout 层,即,每次忽略一半的神经元激活。在这种情况下已经注意到,使用 dropout 技术不仅加速了单次迭代的处理,而且还很好地防止了过拟合。没有 dropout 层,网络制造商声称原始网络过拟合。 +前两个完全连接的层拥有 4,096 个神经元,而最后一个拥有 1,000 个单元,对应于 ImageNet 数据集中的类数。考虑到完全连接层中的大量连接,在每对完全连接的层之间添加了比率为 0.5 的丢弃层,即,每次忽略一半的神经元激活。在这种情况下已经注意到,使用丢弃技术不仅加速了单次迭代的处理,而且还很好地防止了过拟合。没有丢弃层,网络制造商声称原始网络过拟合。 ## 迁移学习 @@ -413,7 +413,7 @@ AlexNet 的架构如下图所示: * `myalexnet_forward.py`:2017 版 TensorFlow 的 AlexNet 实现和测试代码(Python 3.5) * `bvlc_alexnet.npy`:权重,需要在工作目录中 * `caffe_classes.py`:类,与网络输出的顺序相同 -* `poodle.png`,`laska.png`,`dog.png`,`dog2.png`,`quail227.JPEG`:测试图像(图像应为 227×227×3) +* `poodle.png`,`laska.png`,`dog.png`,`dog2.png`,`quail227.JPEG`:测试图像(图像应为`227×227×3`) [从此链接下载这些文件](http://www.cs.toronto.edu/~guerzhoy/tf_alexnet/),或从本书的代码库中下载。 @@ -476,13 +476,13 @@ kuvasz 0.0848062 在此数据集中,训练集包含 20,000 个标记图像,测试和验证集包含 2,500 个图像。 -要使用数据集,必须将每个图像重新整形为 227×227×3。为此,您可以使用`prep_images.py`中的 Python 代码。否则,您可以使用本书仓库中的`trainDir.rar`和`testDir.rar`文件。它们包含 6,000 个用于训练的犬和猫的重塑图像,以及 100 个重新成形的图像用于测试。 +要使用数据集,必须将每个图像重新整形为`227×227×3`。为此,您可以使用`prep_images.py`中的 Python 代码。否则,您可以使用本书仓库中的`trainDir.rar`和`testDir.rar`文件。它们包含 6,000 个用于训练的犬和猫的重塑图像,以及 100 个重新成形的图像用于测试。 以下部分中描述的以下微调实现在`alexnet_finetune.py`中实现,可以在本书的代码库中下载。 # 微调实现 -我们的分类任务包含两个类别,因此网络的新 softmax 层将包含 2 个类别而不是 1,000 个类别。这是输入张量,它是一个 227×227×3 图像,以及等级 2 的输出张量: +我们的分类任务包含两个类别,因此网络的新 softmax 层将包含 2 个类别而不是 1,000 个类别。这是输入张量,它是一个`227×227×3`图像,以及等级 2 的输出张量: ```py n_classes = 2 @@ -600,7 +600,7 @@ Optimization Finished! ``` -要测试我们的模型,我们将预测与标签集(cat = 0,dog = 1)进行比较: +要测试我们的模型,我们将预测与标签集(`cat = 0`,`dog = 1`)进行比较: ```py output = sess.run(prob, feed_dict = {x:imlist, keep_prob: 1.}) @@ -639,13 +639,13 @@ VGG 是在 2014 年 ILSVRC 期间发明神经网络的人的名字。我们谈 表:VGG 网络架构 -请注意, AlexNet 没有具有相当大的感受野的卷积层:这里,所有感受野都是 3×3,除了 VGG-16 中有几个具有 1×1 感受野的卷积层。回想一下,具有 1 步梯度的凸层不会改变输入空间大小,同时修改深度值,该深度值与使用的内核数量相同。因此,VGG 卷积层不会影响输入体积的宽度和高度;只有池化层才能这样做。使用具有较小感受野的一系列卷积层的想法最终总体上模拟具有较大感受野的单个卷积层,这是由于这样的事实,即以这种方式使用多个 ReLU 层而不是单独使用一个,从而增加激活函数的非线性,从而使其更具区别性。它还用于减少使用的参数数量。这些网络被认为是 AlexNet 的演变,因为总体而言,使用相同的数据集,它们的表现优于 AlexNet。 VGG 网络演示的主要概念是拥塞神经网络越来越深刻,其表现也越来越高。但是, 必须拥有越来越强大的硬件,否则网络训练就会成为问题。 +请注意, AlexNet 没有具有相当大的感受野的卷积层:这里,所有感受野都是`3×3`,除了 VGG-16 中有几个具有`1×1`感受野的卷积层。回想一下,具有 1 步梯度的凸层不会改变输入空间大小,同时修改深度值,该深度值与使用的内核数量相同。因此,VGG 卷积层不会影响输入体积的宽度和高度;只有池化层才能这样做。使用具有较小感受野的一系列卷积层的想法最终总体上模拟具有较大感受野的单个卷积层,这是由于这样的事实,即以这种方式使用多个 ReLU 层而不是单独使用一个,从而增加激活函数的非线性,从而使其更具区别性。它还用于减少使用的参数数量。这些网络被认为是 AlexNet 的演变,因为总体而言,使用相同的数据集,它们的表现优于 AlexNet。 VGG 网络演示的主要概念是拥塞神经网络越来越深刻,其表现也越来越高。但是, 必须拥有越来越强大的硬件,否则网络训练就会成为问题。 -对于 VGG,使用了四个 NVIDIA Titan Blacks,每个都有 6 GB 的内存。因此,VGG 具有更好的表现,但需要大量的硬件用于训练,并且还使用大量参数:例如,VGG-19 模型大约为 550 MB(是 AlexNet 的两倍)。较小的 VGG 网络仍然具有大约 507 MB 的模型。 +对于 VGG,使用了四个 NVIDIA Titan Blacks,每个都有 6 GB 的内存。因此,VGG 具有更好的表现,但需要大量的硬件用于训练,并且还使用大量参数:例如,VGG-19 模型大约为 550MB(是 AlexNet 的两倍)。较小的 VGG 网络仍然具有大约 507MB 的模型。 ## 用 VGG-19 学习艺术风格 -在这个项目中,我们使用预训练的 VGG-19 来学习艺术家创建的样式和模式,并将它们转移到图像中(项目文件是`style_transfer.py`,在本书的 GitHub 仓库中) )。这种技术被称为`artistic style learning`([参见 Gatys 等人的文章 A Art Algorithm of Artistic Style](https://arxiv.org/pdf/1508.06576.pdf))。根据学术文献,艺术风格学习定义如下:给定两个图像作为输入,合成具有第一图像的语义内容和第二图像的纹理/风格的第三图像。 +在这个项目中,我们使用预训练的 VGG-19 来学习艺术家创建的样式和模式,并将它们转移到图像中(项目文件是`style_transfer.py`,在本书的 GitHub 仓库中)。这种技术被称为`artistic style learning`([参见 Gatys 等人的文章 A Art Algorithm of Artistic Style](https://arxiv.org/pdf/1508.06576.pdf))。根据学术文献,艺术风格学习定义如下:给定两个图像作为输入,合成具有第一图像的语义内容和第二图像的纹理/风格的第三图像。 为了使其正常工作,我们需要训练一个深度卷积神经网络来构建以下内容: @@ -659,7 +659,7 @@ VGG 是在 2014 年 ILSVRC 期间发明神经网络的人的名字。我们谈 ## 输入图像 -输入图像,每个都是 478×478 像素,是您在本书的代码库中也可以找到的以下图像(`cat.jpg`和`mosaic.jpg`): +输入图像,每个都是`478×478`像素,是您在本书的代码库中也可以找到的以下图像(`cat.jpg`和`mosaic.jpg`): ![Input images](img/B09698_04_13.jpg) @@ -737,7 +737,7 @@ vgg = scipy.io.loadmat('imagenet-vgg-verydeep-19.mat') 每种形状以下列方式表示:`[kernel height, kernel width, number of input channels, number of output channels]`。 -第一层有 3 个输入通道,因为输入是 RGB 图像,而卷积层的输出通道数从 64 到 512,所有内核都是 3x3 矩阵。 +第一层有 3 个输入通道,因为输入是 RGB 图像,而卷积层的输出通道数从 64 到 512,所有内核都是`3x3`矩阵。 然后我们应用转移学习技术,以使 VGG-19 网络适应我们的问题: @@ -803,7 +803,7 @@ content_loss = contentloss\ ## 样式提取器和损失 -样式提取器使用过滤器的 Gram 矩阵作为给定的隐藏层。简单来说,使用这个矩阵,我们可以破坏图像的语义,保留其基本组件并使其成为一个好的纹理提取器: +样式提取器使用过滤器的 Gram 矩阵作为给定的隐藏层。简单来说,使用这个矩阵,我们可以破坏图像的语义,保留其基本组件并使其成为一个好的纹理提取器: ```py def gram_matrix(F, N, M): @@ -892,17 +892,17 @@ iteration: 1000 cost: 5.41755e+08 # Inception-v3 -Szegedy 和其他人在 2014 年的论文“Going Deeper with Convolutions”中首次介绍了 Inception 微架构 : +Szegedy 和其他人在 2014 年的论文“Going Deeper with Convolutions”中首次介绍了 Inception 微架构: ![Inception-v3](img/B09698_04_16.jpg) 图 15:GoogLeNet 中使用的 Original Inception 模块 -初始模块的目标是通过在网络的同一模块内计算 1×1,3×3 和 5×5 卷积来充当多级特征提取器 - 这些滤波器的输出然后,在被馈送到网络中的下一层之前,沿着信道维度堆叠。这种架构的原始版本称为 GoogLeNet,但后续形式简称为 Inception vN,其中 N 表示 Google 推出的版本号。 +初始模块的目标是通过在网络的同一模块内计算`1×1`,`3×3`和`5×5`卷积来充当多级特征提取器 - 这些滤波器的输出然后,在被馈送到网络中的下一层之前,沿着信道维度堆叠。这种架构的原始版本称为 GoogLeNet,但后续形式简称为 InceptionVN,其中 N 表示 Google 推出的版本号。 -您可能想知道为什么我们在同一输入上使用不同类型的卷积。答案是,只要仔细研究了它的参数,就不可能总是获得足够的有用特征来用单个卷积进行精确分类。事实上,使用一些输入它可以更好地使用卷积小内核,而其他输入可以使用其他类型的内核获得更好的结果。可能由于这个原因,GoogLeNet 团队想要在他们自己的网络中考虑一些替代方案。如前所述,为此目的,GoogLeNet 在同一网络级别(即它们并行)使用三种类型的卷积层:1×1 层,3×3 层和 5×5 层。 +您可能想知道为什么我们在同一输入上使用不同类型的卷积。答案是,只要仔细研究了它的参数,就不可能总是获得足够的有用特征来用单个卷积进行精确分类。事实上,使用一些输入它可以更好地使用卷积小内核,而其他输入可以使用其他类型的内核获得更好的结果。可能由于这个原因,GoogLeNet 团队想要在他们自己的网络中考虑一些替代方案。如前所述,为此目的,GoogLeNet 在同一网络级别(即它们并行)使用三种类型的卷积层:`1×1`层,`3×3`层和`5×5`层。 -这个 3 层并行局部结构的结果是它们所有输出值的组合,链接到单个向量输出,它将是下一层的输入。这是通过使用层 concat 完成的。除了三个并行卷积层之外,在相同的本地结构中还添加了一个池化层,因为池化操作对于 CNN 的成功至关重要。 +这个 3 层并行局部结构的结果是它们所有输出值的组合,链接到单个向量输出,它将是下一层的输入。这是通过使用连接层完成的。除了三个并行卷积层之外,在相同的本地结构中还添加了一个池化层,因为池化操作对于 CNN 的成功至关重要。 ## 使用 TensorFlow 探索初始化 @@ -915,7 +915,7 @@ cd models/tutorials/image/imagenet python classify_image.py ``` -当程序第一次运行时,`classify_image.py`从 [tensorflow.org](http://tensorflow.org) 下载经过训练的模型。您的硬盘上需要大约 200 MB 的可用空间。 +当程序第一次运行时,`classify_image.py`从 [tensorflow.org](http://tensorflow.org) 下载经过训练的模型。您的硬盘上需要大约 200MB 的可用空间。 上面的命令将对提供的熊猫图像进行分类。如果模型正确运行,脚本将生成以下输出: @@ -966,9 +966,9 @@ Kaggle 成立于 2010 年,作为预测建模和分析竞赛的平台,公司 图 17:Kaggle 比赛页面 -训练组由 3,761 个灰度图像组成,尺寸为 48×48 像素,3,761 个标签,每个图像有 7 个元素。 +训练组由 3,761 个灰度图像组成,尺寸为`48×48`像素,3,761 个标签,每个图像有 7 个元素。 -每个元素编码一个情感:0 =愤怒,1 =厌恶,2 =恐惧,3 =幸福,4 =悲伤,5 =惊讶,6 =中立。 +每个元素编码一个情感,0:愤怒,1:厌恶,2:恐惧,3:幸福,4:悲伤,5:惊讶,6:中立。 在经典 Kaggle 比赛中,必须由平台评估从测试集获得的标签集。在这个例子中,我们将训练一个来自训练组的神经网络,之后我们将在单个图像上评估模型。 @@ -1020,7 +1020,7 @@ plt.imshow(image_0, cmap='Greys_r') plt.show() ``` -有 3,761 个 48×48 像素的灰度图像: +有 3,761 个`48×48`像素的灰度图像: ```py train images shape = (3761, 48, 48, 1) @@ -1032,7 +1032,7 @@ train images shape = (3761, 48, 48, 1) train labels shape = (3761, 7) ``` -测试集由 1,312 个 48x48 像素灰度图像组成: +测试集由 1,312 个`48x48`像素灰度图像组成: ```py test labels shape = (1312, 48, 48, 1) @@ -1050,7 +1050,7 @@ image_0 shape = (48, 48, 1) label set = [ 0\. 0\. 0\. 1\. 0\. 0\. 0.] ``` -此标签对应于 happy,图像在以下 matplot 图中可视化: +此标签对应于快乐,图像在以下 matplot 图中可视化: ![Emotion recognition with CNNs](img/B09698_04_19.jpg) @@ -1064,9 +1064,9 @@ label set = [ 0\. 0\. 0\. 1\. 0\. 0\. 0.] 图 19:实现的 CNN 的前两个卷积层 -该网络具有两个卷积层,两个完全连接的层,最后是 softmax 分类层。使用 5×5 卷积核在第一卷积层中处理输入图像(48×48 像素)。这导致 32 个图像,每个使用的滤波器一个。通过最大合并操作对图像进行下采样,以将图像从 48×48 减小到 24×24 像素。然后,这些 32 个较小的图像由第二卷积层处理;这导致 64 个新图像(见上图)。通过第二次池化操作,将得到的图像再次下采样到 12×12 像素。 +该网络具有两个卷积层,两个完全连接的层,最后是 softmax 分类层。使用`5×5`卷积核在第一卷积层中处理输入图像(`48×48`像素)。这导致 32 个图像,每个使用的滤波器一个。通过最大合并操作对图像进行下采样,以将图像从`48×48`减小到`24×24`像素。然后,这些 32 个较小的图像由第二卷积层处理;这导致 64 个新图像(见上图)。通过第二次池化操作,将得到的图像再次下采样到`12×12`像素。 -第二合并层的输出是 64×12×12 像素的图像。然后将它们展平为长度为 12×12×64 = 9,126 的单个向量,其用作具有 256 个神经元的完全连接层的输入。这将进入另一个具有 10 个神经元的完全连接的层,每个类对应一个类,用于确定图像的类别,即图像中描绘的情感。 +第二合并层的输出是`64×12×12`像素的图像。然后将它们展平为长度为`12×12×64 = 9,126`的单个向量,其用作具有 256 个神经元的完全连接层的输入。这将进入另一个具有 10 个神经元的完全连接的层,每个类对应一个类,用于确定图像的类别,即图像中描绘的情感。 ![Emotion recognition with CNNs](img/B09698_04_21.jpg) @@ -1283,7 +1283,7 @@ print("Test size: %s" % test_images.shape[0]) global_step = tf.Variable(0, trainable=False) ``` -跟随变量`dropout_prob`,用于 dropout 优化: +跟随变量`dropout_prob`,用于丢弃优化: ```py dropout_prob = tf.placeholder(tf.float32) @@ -1473,7 +1473,7 @@ x = sess.graph.get_tensor_by_name("input:0") y_conv = sess.graph.get_tensor_by_name("output:0") ``` -要测试图像,我们必须将其重新整形为网络的有效 48×48×1 格式: +要测试图像,我们必须将其重新整形为网络的有效`48×48×1`格式: ```py image_test = np.resize(gray,(1,48,48,1)) diff --git a/docs/dl-tf-2e-zh/ch05.md b/docs/dl-tf-2e-zh/ch05.md index 6eec66436dc138f36e93ccb8f7a8e9f7f9d1ac5d..67643984eef86e7c796218c3a3e411f164aae997 100644 --- a/docs/dl-tf-2e-zh/ch05.md +++ b/docs/dl-tf-2e-zh/ch05.md @@ -42,7 +42,7 @@ n_hidden_1 = 256 n_hidden_2 = 128 ``` -最终尺寸对应于 28×28 = 784 像素。 +最终尺寸对应于`28×28 = 784`像素。 我们需要为输入图像定义占位符变量。该张量的数据类型设置为`float`,因为`mnist`值的比例为[0,1],形状设置为`[None, n_input]`。定义`None`参数意味着张量可以包含任意数量的图像: @@ -93,7 +93,7 @@ encoder_in = tf.nn.sigmoid(tf.add\ ![Implementing autoencoders with TensorFlow](img/B09698_05_32.jpg) -这里,W 是权重张量,`encoder_h1`,b 是偏置张量,`encoder_b1`。通过这个操作,我们将初始图像编码为自编码器的有用输入。编码过程的第二步包括数据压缩。输入`encoder_in`张量表示的数据通过第二个矩阵乘法运算减小到较小的大小: +这里,`W`是权重张量,`encoder_h1`,`b`是偏置张量,`encoder_b1`。通过这个操作,我们将初始图像编码为自编码器的有用输入。编码过程的第二步包括数据压缩。输入`encoder_in`张量表示的数据通过第二个矩阵乘法运算减小到较小的大小: ```py encoder_out = tf.nn.sigmoid(tf.add\ @@ -106,7 +106,7 @@ encoder_out = tf.nn.sigmoid(tf.add\ ![Implementing autoencoders with TensorFlow](img/B09698_05_33.jpg) -这里,W 代表权重张量`encoder_h2`,而 b 代表偏差张量,`encoder_b2`。请注意,我们使用 sigmoid 作为编码器阶段的激活函数。 +这里,`W`代表权重张量`encoder_h2`,而`b`代表偏差张量,`encoder_b2`。请注意,我们使用 sigmoid 作为编码器阶段的激活函数。 解码器执行编码器的逆操作。它解压缩输入以获得相同大小的网络输入的输出。该过程的第一步是将大小为 128 的`encoder_out`张量转换为 256 大小的中间表示的张量: @@ -121,7 +121,7 @@ decoder_in = tf.nn.sigmoid(tf.add\ ![Implementing autoencoders with TensorFlow](img/B09698_05_34.jpg) -这里,W 是权重张量,`decoder_h1`,大小 256×128,b 是偏置张量,`decoder_b1`,大小 256.最终解码操作是将数据从其中间表示(大小为 256)解压缩到最终表示(维度 784),这是原始数据的大小: +这里,`W`是权重张量,`decoder_h1`,大小`256×128`,`b`是偏置张量,`decoder_b1`,大小 256。最终解码操作是将数据从其中间表示(大小为 256)解压缩到最终表示(维度 784),这是原始数据的大小: ```py decoder_out = tf.nn.sigmoid(tf.add\ @@ -316,7 +316,7 @@ x = tf.placeholder("float", [None, n_input]) y = tf.placeholder("float", [None, n_output]) ``` -为了减少过拟合,我们在编码和解码过程之前应用一个 dropout,因此我们必须定义一个占位符,以便在 dropout 期间保持神经元输出的概率: +为了减少过拟合,我们在编码和解码过程之前应用一个丢弃,因此我们必须定义一个占位符,以便在丢弃期间保持神经元输出的概率: ```py dropout_keep_prob = tf.placeholder("float") @@ -357,7 +357,7 @@ decode_in = tf.nn.sigmoid\ biases['b2'])) ``` -过拟合的减少是通过 dropout 程序来完成的: +过拟合的减少是通过丢弃程序来完成的: ```py decode_out = tf.nn.dropout(decode_in,\ @@ -526,7 +526,7 @@ Test label is 5 ### 编码器 -编码器由三个卷积层组成。特征数量从输入数据 1 变为第一卷积层的 16;然后,第二层从 16 到 32;最后,从最后一个卷积层的 32 到 64。从卷积层移动到另一个层时,形状经历图像压缩: +编码器由三个卷积层组成。特征数量从输入数据 1 变为第一卷积层的 16;然后,第二层从 16 到 32;最后,从最后一个卷积层的 32 到 64。从卷积层移动到另一个层时,形状经历图像压缩: ![Encoder](img/B09698_05_09.jpg) @@ -576,7 +576,7 @@ x = tf.placeholder(tf.float32, [None, dim]) y = tf.placeholder(tf.float32, [None, dim]) ``` -然后我们定义`keepprob`变量,[用于配置在网络训练期间使用的 dropout 率](https://www.tensorflow.org/tutorials/layers#dropout): +然后我们定义`keepprob`变量,[用于配置在网络训练期间使用的丢弃率](https://www.tensorflow.org/tutorials/layers#dropout): ```py keepprob = tf.placeholder(tf.float32) @@ -631,7 +631,7 @@ biases = { def cae(_X, _W, _b, _keepprob): ``` -最初的 784 像素图像必须重新整形为 28×28 矩阵,随后由下一个卷积层处理: +最初的 784 像素图像必须重新整形为`28×28`矩阵,随后由下一个卷积层处理: ```py _input_r = tf.reshape(_X, shape=[-1, 28, 28, 1]) @@ -648,13 +648,13 @@ def cae(_X, _W, _b, _keepprob): _b['be1'])) ``` -在移动到第二个卷积层之前,我们应用了 dropout 操作: +在移动到第二个卷积层之前,我们应用了丢弃操作: ```py _ce1 = tf.nn.dropout(_ce1, _keepprob) ``` -在下面的两个编码层中,我们应用相同的卷积和 dropout 操作: +在下面的两个编码层中,我们应用相同的卷积和丢弃操作: ```py _ce2 = tf.nn.sigmoid\ @@ -673,7 +673,7 @@ def cae(_X, _W, _b, _keepprob): _ce3 = tf.nn.dropout(_ce3, _keepprob) ``` -特征数量从 1(输入图像)增加到 64,而原始形状图像已减少到 28×28 到 7×7。在解码阶段,压缩(或编码)和重新成形的图像必须为尽可能与原始图像相似。为实现这一目标,我们在接下来的三个层中使用了`conv2d_transpose` TensorFlow 函数: +特征数量从 1(输入图像)增加到 64,而原始形状图像已减少到`28×28`到`7×7`。在解码阶段,压缩(或编码)和重新成形的图像必须为尽可能与原始图像相似。为实现这一目标,我们在接下来的三个层中使用了`conv2d_transpose` TensorFlow 函数: ```py tf.nn.conv2d_transpose(value, filter, output_shape, strides, padding='SAME') @@ -687,7 +687,7 @@ tf.nn.conv2d_transpose(value, filter, output_shape, strides, padding='SAME') * `strides`:整数列表。输入张量的每个维度的滑动窗口的步幅。 * `padding`:一个有效的字符串或`SAME`。 -`conv2d_transpose`函数将返回与`value`参数类型相同的张量。第一个去卷积层`_cd3`具有卷积层`_ce3`作为输入。它返回`_cd3`张量,其形状为(1,7,7,32): +`conv2d_transpose`函数将返回与`value`参数类型相同的张量。第一个去卷积层`_cd3`具有卷积层`_ce3`作为输入。它返回`_cd3`张量,其形状为`(1,7,7,32)`: ```py _cd3 = tf.nn.sigmoid\ @@ -700,7 +700,7 @@ tf.nn.conv2d_transpose(value, filter, output_shape, strides, padding='SAME') _cd3 = tf.nn.dropout(_cd3, _keepprob) ``` -对于第二个去卷积层`_cd2`,我们将反卷积层`_cd3`作为输入传递。它返回`_cd2`张量,其形状为(1,14,14,16): +对于第二个去卷积层`_cd2`,我们将反卷积层`_cd3`作为输入传递。它返回`_cd2`张量,其形状为`(1,14,14,16)`: ```py _cd2 = tf.nn.sigmoid\ @@ -713,7 +713,7 @@ tf.nn.conv2d_transpose(value, filter, output_shape, strides, padding='SAME') _cd2 = tf.nn.dropout(_cd2, _keepprob) ``` -第三个也是最后一个反卷积层`_cd1`将`_cd2`层作为输入传递。它返回结果`_out`张量,其形状为(1,28,28,1),与输入图像相同: +第三个也是最后一个反卷积层`_cd1`将`_cd2`层作为输入传递。它返回结果`_out`张量,其形状为`(1,28,28,1)`,与输入图像相同: ```py _cd1 = tf.nn.sigmoid\ @@ -891,7 +891,7 @@ Andrea Dal Pozzolo,Olivier Caelen,Reid A. Johnson 和 Gianluca Bontempi。 该数据集包含 2013 年 9 月欧洲信用卡持有人在两天内进行的交易。共有 285,299 笔交易,只有 492 笔欺诈,这意味着数据集非常不平衡。正类(欺诈)占所有交易的 0.172%。 -数据集包含数字输入变量,这些变量是 PCA 转换的结果。遗憾的是,由于机密性问题,我们无法提供有关数据的原始特征和更多背景信息。有[28]特征,即`V1`,`V2`,... `V27`,它们是使用 PCA 获得的主要成分,除了`Time`和`Amount`特征。 `Class`特征是响应变量,在欺诈情况下取值`1`,否则取`0`。 +数据集包含数字输入变量,这些变量是 PCA 转换的结果。遗憾的是,由于机密性问题,我们无法提供有关数据的原始特征和更多背景信息。有 28 个特征,即`V1`,`V2`,... `V27`,它们是使用 PCA 获得的主要成分,除了`Time`和`Amount`特征。 `Class`特征是响应变量,在欺诈情况下取值`1`,否则取`0`。 还有两个附加特征,`Time`和`Amount`。 `Time`列表示每笔交易与第一笔交易之间的时间(以秒为单位),而`Amount`列表示此交易中转账的金额。那么,让我们看一下输入数据(仅显示`V1`,`V2`,`V26`和`V27`),如图 16 所示: @@ -946,7 +946,7 @@ $ pip3 install git+https://github.com/mwaskom/seaborn.git 现在,[我假设您已经从上述 URL 下载了数据集](https://www.kaggle.com/hunk3749/credit-card/data)。下载附带一个名为`creditcard.csv`的 CSV 文件。 -接下来,让我们阅读数据集并创建一个 pandas DataFrame: +接下来,让我们阅读数据集并创建一个 pandas `DataFrame`: ```py df = pd.read_csv('creditcard.csv') @@ -1054,12 +1054,12 @@ Total test examples: 56962, total fraud cases: 75, equal to 0.13167 % of total c ## 归一化 -为了获得更好的预测准确率,我们可以考虑两种类型的标准化:z-score 和 min-max scaling: +为了获得更好的预测准确率,我们可以考虑两种类型的标准化:z 得分和 min-max 缩放: * Z 得分:这将每列归一化为零均值并将其标准化。这特别适用于激活函数,例如 tanh,其输出零两侧的值。其次,这将留下极端的价值,因此在正常化之后会有一些极端。在这种情况下,这可能对检测异常值很有用。 * 最小 - 最大缩放:这确保所有值都在 0 和 1 之间,即正数。如果我们使用 sigmoid 作为输出激活,这是默认方法。 -我们使用验证集来决定数据标准化方法和激活函数。根据实验,我们发现当与 z-score 标准化一起使用时,tanh 的表现略好于 sigmoid。因此,我们选择了 tanh,然后是 z-score: +我们使用验证集来决定数据标准化方法和激活函数。根据实验,我们发现当与 z 得分标准化一起使用时,tanh 的表现略好于 sigmoid。因此,我们选择了 tanh,然后是 z 得分: ```py cols_mean = [] @@ -1072,7 +1072,7 @@ for c in range(train_x.shape[1]): test_x[:, c] = (test_x[:, c] - cols_mean[-1]) / cols_std[-1] ``` -## Autoencoder 作为无监督特征学习算法 +## 自编码器作为无监督特征学习算法 在本小节中,我们将看到如何使用自编码器作为无监督的特征学习算法。首先,让我们初始化网络超参数: @@ -1128,7 +1128,7 @@ def decoder(x): return layer_1 ``` -之后,我们通过传递输入数据的 TensorFlow 占位符来构建模型。权重和偏差(NN 的 Ws 和 bs)包含我们将学习优化的网络的所有参数,如下所示: +之后,我们通过传递输入数据的 TensorFlow 占位符来构建模型。权重和偏差(NN 的`W`和`b`)包含我们将学习优化的网络的所有参数,如下所示: ```py encoder_op = encoder(X) @@ -1152,7 +1152,7 @@ batch_mse = tf.reduce_mean(tf.pow(y_true - y_pred, 2), 1) 未观测值的均方误差(MSE)是[平方误差](https://en.wikipedia.org/wiki/Errors_and_residuals)或[偏差](https://en.wikipedia.org/wiki/Deviation_(statistics))的[平均值](https://en.wikipedia.org/wiki/Expected_value)。从统计学的角度来看, 它是估计量质量的度量(它总是非负的,接近于零的值更好)。 -如果`Y^`是 n 个预测的向量,并且 Y 是被预测变量的观测值的向量,则预测变量的样本内 MSE 计算如下: +如果`Y^`是 n 个预测的向量,并且`Y`是被预测变量的观测值的向量,则预测变量的样本内 MSE 计算如下: ![Autoencoder as an unsupervised feature learning algorithm](img/B09698_05_36.jpg) @@ -1309,7 +1309,7 @@ plt.show() 图 20:非欺诈案件的 MSE 欺诈评分 -前面的屏幕截图是不可理解的,所以让我们将其缩放到(0,30)范围并再次绘制图形: +前面的屏幕截图是不可理解的,所以让我们将其缩放到`(0, 30)`范围并再次绘制图形: ```py # Zoom into (0, 30) range @@ -1322,7 +1322,7 @@ plt.show() ![Evaluating the model](img/B09698_05_21.jpg) -图 21:非欺诈案件的 MSE 欺诈评分,放大到(0,30)范围 +图 21:非欺诈案件的 MSE 欺诈评分,放大到`(0, 30)`范围 现在让我们只显示欺诈类: @@ -1362,7 +1362,7 @@ Compared to the average percentage of fraud in test set: 0.132% 在本章中,我们实现了一些称为自编码器的优化网络。自编码器基本上是数据压缩网络模型。它用于将给定输入编码为较小维度的表示,然后可以使用解码器从编码版本重建输入。我们实现的所有自编码器都包含编码和解码部分。 -我们还看到了如何通过在网络训练期间引入噪声和构建去噪自编码器来提高自编码器的表现。最后,我们应用[第 4 章](../Text/ch04.html "Chapter 4. Convolutional Neural Networks")中介绍的 CNN 概念,卷积神经网络上的 TensorFlow 和卷积自编码器的实现。 +我们还看到了如何通过在网络训练期间引入噪声和构建去噪自编码器来提高自编码器的表现。最后,我们应用第 4 章中介绍的 CNN 概念,卷积神经网络上的 TensorFlow 和卷积自编码器的实现。 即使隐藏单元的数量很大,我们仍然可以通过在网络上施加其他约束来使用自编码器发现数据集的有趣和隐藏结构。换句话说,如果我们对隐藏单元施加稀疏约束,那么即使隐藏单元的数量很大,自编码器仍将在数据中发现有趣的结构。为了证明这一论点,我们看到了一个真实的例子,即信用卡欺诈分析,我们成功应用了自编码器。 diff --git a/docs/dl-tf-2e-zh/ch06.md b/docs/dl-tf-2e-zh/ch06.md index 19eea921d14e3ed3d17795b62b7a10dfe210361e..8eb7cb32d49442d252ff97b6fb8abd9402747e81 100644 --- a/docs/dl-tf-2e-zh/ch06.md +++ b/docs/dl-tf-2e-zh/ch06.md @@ -32,7 +32,7 @@ ![RNN and the gradient vanishing-exploding problem](img/B09698_06_61.jpg) -现在让 E 代表输出层的损失:`E = f(O[t])`。然后,上述三个方程告诉我们 E 取决于输出`O[t]`。输出`O[t]`相对于层的隐藏状态(`h[t]`)的变化而变化。当前时间步长(`h[t]`)的隐藏状态取决于先前时间步长(`h[t-1]`)的神经元状态。现在,下面的等式将清除这个概念。 +现在让`E`代表输出层的损失:`E = f(O[t])`。然后,上述三个方程告诉我们`E`取决于输出`O[t]`。输出`O[t]`相对于层的隐藏状态(`h[t]`)的变化而变化。当前时间步长(`h[t]`)的隐藏状态取决于先前时间步长(`h[t-1]`)的神经元状态。现在,下面的等式将清除这个概念。 相对于为隐藏层选择的参数的损失变化率`= ∂E/∂θ`,这是一个可以表述如下的链规则: @@ -62,7 +62,7 @@ ![RNN and the gradient vanishing-exploding problem](img/B09698_06_72.jpg) -在这些情况下,`θ`也随着时间步长而变化。上面的等式显示了当前状态相对于先前状态的依赖性。现在让我们解释这两个方程的解剖。假设您处于时间步长 5(t = 5),那么 k 的范围从 1 到 5(k = 1 到 5),这意味着您必须为以下内容计算 k): +在这些情况下,`θ`也随着时间步长而变化。上面的等式显示了当前状态相对于先前状态的依赖性。现在让我们解释这两个方程的解剖。假设您处于时间步长 5(`t = 5`),那么`k`的范围从 1 到 5(`k = 1`到 5),这意味着您必须为以下内容计算`k`): ![RNN and the gradient vanishing-exploding problem](img/B09698_06_75.jpg) @@ -80,7 +80,7 @@ 最近在深度学习的背景下重新发现了这种类型的神经网络,因为它没有消失梯度的问题,并且提供了出色的结果和表现。基于 LSTM 的网络是时间序列的预测和分类的理想选择,并且正在取代许多传统的深度学习方法。 -这个名称意味着短期模式不会被遗忘。 LSTM 网络由彼此链接的单元(LSTM 块)组成。每个 LSTM 块包含三种类型的门:输入门,输出门和遗忘门,它们分别实现对单元存储器的写入,读取和复位功能。这些门不是二元的,而是模拟的(通常由映射在[0,1]范围内的 Sigmoid 激活函数管理,其中 0 表示总抑制,1 表示总激活)。 +这个名称意味着短期模式不会被遗忘。 LSTM 网络由彼此链接的单元(LSTM 块)组成。每个 LSTM 块包含三种类型的门:输入门,输出门和遗忘门,它们分别实现对单元存储器的写入,读取和复位功能。这些门不是二元的,而是模拟的(通常由映射在`[0, 1]`范围内的 Sigmoid 激活函数管理,其中 0 表示总抑制,1 表示总激活)。 如果你认为 LSTM 单元是一个黑盒子,它可以像基本单元一样使用,除了它会表现得更好;训练将更快地收敛,它将检测数据中的长期依赖性。在 TensorFlow 中,您只需使用`BasicLSTMCell`代替`BasicRNNCell`: @@ -108,7 +108,7 @@ LSTM 单元管理两个状态向量,并且出于表现原因,它们默认保 由于长期`c(t)`从左到右穿过网络,你可以看到它首先通过一个遗忘门,丢弃一些内存,然后它添加一些新的存储器通过加法运算(增加了输入门选择的存储器)。结果`c(t)`直接发送,没有任何进一步的变换 -因此,在每个时间步骤,都会丢弃一些内存并添加一些内存。此外,在加法运算之后,长期状态被复制并通过 tanh 函数,该函数产生[-1,+ 1]范围内的输出。 +因此,在每个时间步骤,都会丢弃一些内存并添加一些内存。此外,在加法运算之后,长期状态被复制并通过 tanh 函数,该函数产生`[-1, +1]`范围内的输出。 然后输出门过滤结果。这会产生短期`h(t)`(等于此时间步的单元输出`y(t)`)。现在,让我们来看看新记忆的来源以及大门如何运作。首先,当前输入`x(t)`和之前的短路`h(t-1)`被馈送到四个不同的完全连接。这些门的存在允许 LSTM 单元无限期地记住信息:事实上,如果输入门低于激活阈值,单元格将保持先前的状态,如果启用当前状态,它将与输入值组合。顾名思义,遗忘门重置单元的当前状态(当其值被清除为 0 时),输出门决定是否必须执行单元的值。 @@ -604,7 +604,7 @@ y = tf.placeholder(tf.float32, [None, seq_size]) 下一个任务是构建 LSTM 网络。以下方法`LSTM_Model()`采用三个参数,如下所示: -* `x`:大小为[T,batch_size,input_size]的输入 +* `x`:大小为`[T, batch_size, input_size]`的输入 * `W`:完全连接的输出层权重矩阵 * `b`:完全连接的输出层偏置向量 @@ -1018,10 +1018,10 @@ def __load_preprocessed(self): 1. 准备正则表达式模式。 2. 清洁每个样本。 3. 恢复 HTML 字符。 -4. 删除@users 和 URL。 +4. 删除`@users`和 URL。 5. 转换为小写。 6. 删除标点符号。 -7. 用 C 替换 CC(C +)(连续出现两次以上的字符) +7. 用`C`替换`C+`(连续出现两次以上的字符) 8. 删除停用词。 现在让我们以编程方式编写上述步骤。为此,我们有以下函数: @@ -1135,7 +1135,7 @@ lstm_model = LSTM_RNN_Network(hidden_size=[hidden_size], * `max_length`:输入张量的最大长度 * `n_classes`:分类类的数量 * `learning_rate`:RMSProp 算法的学习率 -* `random_state`:dropout 的随机状态 +* `random_state`:丢弃的随机状态 构造函数的代码如下: @@ -1157,7 +1157,7 @@ def __init__(self, hidden_size, vocab_size, embedding_size, max_length, n_classe self.merged = tf.summary.merge_all() ``` -下一个函数被称为`_input()`,它采用一个名为 param `max_length`的参数,它是输入张量的最大长度。然后它返回一个输入占位符,其形状为`[batch_size, max_length]`,用于 TensorFlow 计算: +下一个函数被称为`_input()`,它采用一个名为`max_length`的参数,它是输入张量的最大长度。然后它返回一个输入占位符,其形状为`[batch_size, max_length]`,用于 TensorFlow 计算: ```py def __input(self, max_length): @@ -1171,14 +1171,14 @@ def __seq_len(self): return tf.placeholder(tf.int32, [None], name='lengths') ``` -下一个函数称为`_target()`。它需要一个名为 param `n_classes`的参数,它包含分类类的数量。最后,它返回形状为`[batch_size, n_classes]`的目标占位符: +下一个函数称为`_target()`。它需要一个名为`n_classes`的参数,它包含分类类的数量。最后,它返回形状为`[batch_size, n_classes]`的目标占位符: ```py def __target(self, n_classes): return tf.placeholder(tf.float32, [None, n_classes], name='target') ``` -`_dropout_keep_prob()`返回一个持有 dropout 的占位符保持概率以减少过拟合: +`_dropout_keep_prob()`返回一个持有丢弃的占位符保持概率以减少过拟合: ```py def __dropout_keep_prob(self): @@ -1188,10 +1188,10 @@ def __dropout_keep_prob(self): `_cell()`方法用于构建带有压差包装器的 LSTM 单元。它需要以下参数: * `hidden_size`:它是 LSTM 单元中的单元数 -* `dropout_keep_prob`:这表示持有 dropout 保持概率的张量 -* `seed`:它是一个可选值,可确保 dropout 包装器的随机状态计算的可重现性。 +* `dropout_keep_prob`:这表示持有丢弃保持概率的张量 +* `seed`:它是一个可选值,可确保丢弃包装器的随机状态计算的可重现性。 -最后,它返回一个带有 dropout 包装器的 LSTM 单元: +最后,它返回一个带有丢弃包装器的 LSTM 单元: ```py def __cell(self, hidden_size, dropout_keep_prob, seed=None): @@ -1217,9 +1217,9 @@ def __word_embeddings(self, x, vocab_size, embedding_size, seed=None): * `hidden_size`:这是 LSTM 单元中的单元数 * `x`:这是带形状的输入 * `seq_len`:这是具有形状的序列长度张量 -* `dropout_keep_prob`:这是持有 dropout 保持概率的张量 +* `dropout_keep_prob`:这是持有丢弃保持概率的张量 * `variable_scope`:这是变量范围的名称(默认层是`rnn_layer`) -* `random_state`:这是 dropout 包装器的随机状态 +* `random_state`:这是丢弃包装器的随机状态 最后,它返回形状为`[batch_size, max_seq_len, hidden_size]`的输出: @@ -1237,8 +1237,8 @@ def __rnn_layer(self, hidden_size, x, seq_len, dropout_keep_prob, variable_scope * `seq_len`:这是形状`[batch_size]`的序列长度张量 * `hidden_size`:这是一个数组,其中包含每个 RNN 层中 LSTM 单元中的单元数 * `n_classes`:这是分类的数量 -* `dropout_keep_prob`:这是持有 dropout 保持概率的张量 -* `random_state`:这是一个可选参数,但它可用于确保 dropout 包装器的随机状态 +* `dropout_keep_prob`:这是持有丢弃保持概率的张量 +* `random_state`:这是一个可选参数,但它可用于确保丢弃包装器的随机状态 最后,`_score()`方法返回具有形状`[batch_size, n_classes]`的每个类的线性激活: @@ -1643,7 +1643,7 @@ Real sentiment: [1\. 0.] # 使用 LSTM 模型识别人类活动 -人类活动识别(HAR)数据库[​​HTG0] 是通过对携带带有嵌入式惯性传感器的腰部智能手机的 30 名参加日常生活活动(ADL)的参与者进行测量而建立的。目标是将他们的活动分类为前面提到的六个类别之一。 +人类活动识别(HAR)数据库是通过对携带带有嵌入式惯性传感器的腰部智能手机的 30 名参加日常生活活动(ADL)的参与者进行测量而建立的。目标是将他们的活动分类为前面提到的六个类别之一。 ## 数据集描述 @@ -1923,7 +1923,7 @@ biases = { pred = LSTM_RNN(x, weights, biases) ``` -此外,我们还需要计算`cost` op,正则化,优化器和评估。我们使用 L2 损失进行正则化,这可以防止这种过度杀伤神经网络过度适应训练中的问题: +此外,我们还需要计算`cost`操作,正则化,优化器和评估。我们使用 L2 损失进行正则化,这可以防止这种过度杀伤神经网络过度适应训练中的问题: ```py l2 = lambda_loss_amount * sum(tf.nn.l2_loss(tf_var) for tf_var in tf.trainable_variables())