From 46ccc0d68e013caac74cc7765c14cf80ae640b58 Mon Sep 17 00:00:00 2001 From: wizardforcel <562826179@qq.com> Date: Wed, 5 Aug 2020 22:12:20 +0800 Subject: [PATCH] 2020-08-05 22:12:20 --- docs/hands-on-dl-tf-zh/ch01.md | 2 +- docs/hands-on-dl-tf-zh/ch02.md | 16 ++++++------ docs/hands-on-dl-tf-zh/ch03.md | 48 +++++++++++++++++----------------- docs/hands-on-dl-tf-zh/ch04.md | 2 +- docs/hands-on-dl-tf-zh/ch05.md | 6 ++--- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/docs/hands-on-dl-tf-zh/ch01.md b/docs/hands-on-dl-tf-zh/ch01.md index b5fd8b8d..9e891ee8 100644 --- a/docs/hands-on-dl-tf-zh/ch01.md +++ b/docs/hands-on-dl-tf-zh/ch01.md @@ -576,7 +576,7 @@ plt.plot(test_acc,'rx') ![Evaluating the model accuracy](img/00021.jpg) -验证精度似乎在经过约 400-500 次迭代后趋于平稳; 除此之外,我们的模型可能过拟合或没有学到更多。 同样,即使最终精度大约是 40%,看起来也很差,但请记住,对于五个类别,完全随机的猜测将仅具有 20%的精度。 有了这个有限的数据集,简单的模型就可以做到。 +验证精度似乎在经过约 400-500 次迭代后趋于平稳; 除此之外,我们的模型可能过拟合或没有学到更多。 同样,即使最终精度大约是 40%,看起来也很差,但请记住,对于五个类别,完全随机的猜测将仅具有 20% 的精度。 有了这个有限的数据集,简单的模型就可以做到。 查看计算出的权重通常也很有帮助。 这些可以为您提供有关模型认为重要的线索。 让我们按给定类的像素位置绘制它们: diff --git a/docs/hands-on-dl-tf-zh/ch02.md b/docs/hands-on-dl-tf-zh/ch02.md index c4e3ecb9..5a9b4ac6 100644 --- a/docs/hands-on-dl-tf-zh/ch02.md +++ b/docs/hands-on-dl-tf-zh/ch02.md @@ -67,7 +67,7 @@ print(logx1.eval()) ![Log function](img/00024.jpg) -但是,对数不能处理负输入,并且您越接近零,小输入就变得越负。 因此,请注意对数。 最后,是 S 形变换。 +但是,对数不能处理负输入,并且您越接近零,小输入就变得越负。 因此,请注意对数。 最后,是 Sigmoid 变换。 ## sigmoid 函数 @@ -103,7 +103,7 @@ sess.run(tf.global_variables_initializer()) ![Sigmoid function](img/00027.jpg) -在上图中,我们有一个简单的网络,其中有两个输入`X0`和`X1`,两个输出`Y0`和`Y1`,中间有三个神经元。 `X0`中的值被发送到每个`N`神经元,但是权重不同,该权重乘以与每个相关的`X0`。 `X1`也发送到每个神经元,并具有自己的一组权重。 对于每个神经元,我们计算输入的加权总和,将其通过激活函数,然后产生中间输出。 现在,我们做同样的事情,但是将神经元的输出视为 Ys 的输入。 注意,通过对输入加权和进行非线性激活,我们实际上只是为最终模型计算了一组新的特征。 +在上图中,我们有一个简单的网络,其中有两个输入`X0`和`X1`,两个输出`Y0`和`Y1`,中间有三个神经元。 `X0`中的值被发送到每个`N`神经元,但是权重不同,该权重乘以与每个相关的`X0`。 `X1`也发送到每个神经元,并具有自己的一组权重。 对于每个神经元,我们计算输入的加权总和,将其通过激活函数,然后产生中间输出。 现在,我们做同样的事情,但是将神经元的输出视为`Y`的输入。 注意,通过对输入加权和进行非线性激活,我们实际上只是为最终模型计算了一组新的特征。 现在您已经了解了 TensorFlow 中非线性转换的基础以及什么是神经网络。 好吧,它们可能不会让您读懂思想,它们对于深度学习至关重要。 在下一节中,我们将使用简单的神经网络来改进分类算法。 @@ -164,7 +164,7 @@ except ImportError: 在所有这些权重中,我们使用此奇怪的截断普通调用对其进行初始化。 借助神经网络,我们希望获得良好的初始值分布,以便我们的权重可以攀升至有意义的值,而不是仅仅归零。 -5. 截断正态具有给定标准偏差的正态分布中的随机值,该研究标准按输入数量进行缩放,但抛出的值太极端,因此被截断了。 定义好权重和神经元后,我们将像以前一样设置最终的`softmax`模型,除了需要注意使用 128 个神经元作为输入`h1`以及相关的权重和偏差`W2` ]和`b2`: +5. 截断正态具有给定标准偏差的正态分布中的随机值,该研究标准按输入数量进行缩放,但抛出的值太极端,因此被截断了。 定义好权重和神经元后,我们将像以前一样设置最终的`softmax`模型,除了需要注意使用 128 个神经元作为输入`h1`以及相关的权重和偏差`W2`和`b2`: ```py y = tf.nn.softmax(tf.matmul(h1,W2) + b2) @@ -222,9 +222,9 @@ plt.plot(test_acc,'rx') ![Single hidden layer explained](img/00031.jpg) -同样,如果您没有 Matplotlib,那就没关系。 您可以只查看数组值本身。 请注意,训练精度(蓝色)通常比测试精度(红色)好一点。 这并不奇怪,因为测试图像对于模型来说是全新的,并且可能包含以前看不见的特征。 另外,观察精度通常会攀升到更多的周期,然后逐渐上升,然后逐渐上升。 我们的模型在这里达到约 60%的准确率; 并非完美,但对简单逻辑回归进行了改进。 +同样,如果您没有 Matplotlib,那就没关系。 您可以只查看数组值本身。 请注意,训练精度(蓝色)通常比测试精度(红色)好一点。 这并不奇怪,因为测试图像对于模型来说是全新的,并且可能包含以前看不见的特征。 另外,观察精度通常会攀升到更多的周期,然后逐渐上升,然后逐渐上升。 我们的模型在这里达到约 60% 的准确率; 并非完美,但对简单逻辑回归进行了改进。 -要查看我们的模型在哪里混淆,创建混淆矩阵会很有帮助。 也就是说,我们将寻找一个可以说的实际绘图类别。 该模型将其分类为什么? 形式上是 5x5 矩阵。 对于每个测试图像,如果图像实际上是类别`i`和模型预测类别`j`,则我们增加值和位置`i j`。 请注意,当模型正确时,则为`i = j`。 +要查看我们的模型在哪里混淆,创建混淆矩阵会很有帮助。 也就是说,我们将寻找一个可以说的实际绘图类别。 该模型将其分类为什么? 形式上是`5x5`矩阵。 对于每个测试图像,如果图像实际上是类别`i`和模型预测类别`j`,则我们增加值和位置`i j`。 请注意,当模型正确时,则为`i = j`。 一个好的模型在对角线上将具有很大的值,而在其他地方则没有很多。 通过这种类型的分析,很容易看出两个类是否经常彼此混淆,或者模型很少选择某些类。 @@ -258,7 +258,7 @@ for i in range(32): plts[i//8, i%8].pcolormesh(W1.eval()[:,i].reshape([36,36])) ``` -但是,现在我们有 128 个神经元,每个神经元的权重都来自输入像素,权重为 36x36。 让我们看看其中的一些,以了解他们的发现。 同样,如果您没有 Matplotlib,则可以简单地打印出数组以查看相同的行为。 在这里,我们将研究 128 个神经元中的 32 个。 因此,让我们将子图的格式设置为四行八列。 现在,我们逐步求值每个神经元的权重,并将其重塑为图像大小。 双斜杠(`//`)使用整数除法将图像放入适当的行,而百分号(`%`)使用余数(实际上是模块化算术)来选择列。 +但是,现在我们有 128 个神经元,每个神经元的权重都来自输入像素,权重为`36x36`。 让我们看看其中的一些,以了解他们的发现。 同样,如果您没有 Matplotlib,则可以简单地打印出数组以查看相同的行为。 在这里,我们将研究 128 个神经元中的 32 个。 因此,让我们将子图的格式设置为四行八列。 现在,我们逐步求值每个神经元的权重,并将其重塑为图像大小。 双斜杠(`//`)使用整数除法将图像放入适当的行,而百分号(`%`)使用余数(实际上是模块化算术)来选择列。 ![Understanding weights of the model](img/00033.jpg) @@ -312,7 +312,7 @@ W3 = tf.Variable(tf.truncated_normal([num_hidden2, 5], b3 = tf.Variable(tf.constant(0.1,shape=[5])) ``` -现在这是第三组权重,当然,此形状必须与前面的隐藏层的输出匹配,因此 32 x 5: +现在这是第三组权重,当然,此形状必须与前面的隐藏层的输出匹配,因此`32 x 5`: ![Exploring the multiple hidden layer model](img/00035.jpg) @@ -398,7 +398,7 @@ plt.plot(test_acc,'rx') ![Understanding the multiple hidden layers graph](img/00037.jpg) -从前面的输出图中,我们可以达到约 68%的训练精度,也许还有 63%的验证精度。 这还不错,但是确实留出了一些改进的空间。 +从前面的输出图中,我们可以达到约 68% 的训练精度,也许还有 63% 的验证精度。 这还不错,但是确实留出了一些改进的空间。 让我们花点时间看一下准确率在许多周期如何增长。 当然,它起步非常糟糕,并且存在一些最初的麻烦,但是权重是随机的,并且在那个时候仍在学习,并且在最初的数千个周期中它很快得到了改善。 虽然可能会暂时卡在局部最大值中,但通常会爬出并最终减慢其重音。 请注意,它仍然可以很好地进入训练阶段。 只是到了尽头,模型才可能达到其最大容量。 根据随机初始化,您的曲线可能看起来有些不同,但这没关系; 这是您的模型,非常好。 diff --git a/docs/hands-on-dl-tf-zh/ch03.md b/docs/hands-on-dl-tf-zh/ch03.md index 7d05c8c1..db1ee001 100644 --- a/docs/hands-on-dl-tf-zh/ch03.md +++ b/docs/hands-on-dl-tf-zh/ch03.md @@ -28,7 +28,7 @@ 对于诸如图像分类(尤其是字体分类)之类的任务,图像中出现小比例尺特征通常并不重要。 我们可以通过在整个图像中滑动较小的窗口来在较大的图像中查找小比例尺特征,这对于使用相同的权重矩阵至关重要,无论该窗口在图像中的位置如何。 这样,我们可以随时随地寻找相同的特征。 -假设我们有一个 10x10 的图像,并且想在其中滑动 3x3 的窗口。 通常,机器学习工程师每次只能将此窗口滑动一个像素。 这称为跨步,因此从一个窗口到下一个窗口会有一些重叠。 然后逐个元素地将我们小的 3x3 权重矩阵`W1`乘到我们的窗口`H1[00]`中,对结果求和,并通过称为`F`的激活函数进行处理。 +假设我们有一个`10x10`的图像,并且想在其中滑动`3x3`的窗口。 通常,机器学习工程师每次只能将此窗口滑动一个像素。 这称为跨步,因此从一个窗口到下一个窗口会有一些重叠。 然后逐个元素地将我们小的`3x3`权重矩阵`W1`乘到我们的窗口`H1[00]`中,对结果求和,并通过称为`F`的激活函数进行处理。 ![Convolutional layer motivation](img/00042.jpg) @@ -56,7 +56,7 @@ ![Multiple features extracted](img/00047.jpg) -现在,观察上图中所示的矩阵。 您确实有一个红色值的矩阵,一个绿色值的矩阵和一个蓝色值的矩阵。 现在,您的权重矩阵实际上是大小为 3x3x3 的权重张量,并且在所有颜色上的窗口大小均相同。 当然,您可以组合所有这些方法,并且通常在计算完窗口上的 32 个特征后,尤其是在第一个卷积层之后进行; 现在,您有许多用于下一层的输入通道。 +现在,观察上图中所示的矩阵。 您确实有一个红色值的矩阵,一个绿色值的矩阵和一个蓝色值的矩阵。 现在,您的权重矩阵实际上是大小为`3x3x3`的权重张量,并且在所有颜色上的窗口大小均相同。 当然,您可以组合所有这些方法,并且通常在计算完窗口上的 32 个特征后,尤其是在第一个卷积层之后进行; 现在,您有许多用于下一层的输入通道。 # 卷积层应用 @@ -70,7 +70,7 @@ 这只是一个小例子,可以帮助我们熟悉将 TensorFlow 用于卷积层。 -导入必要的工具后,让我们制作一个假的 10x10 图像,但对角线的值较大: +导入必要的工具后,让我们制作一个假的`10x10`图像,但对角线的值较大: ```py # Make some fake data, 1 data points @@ -79,7 +79,7 @@ image = np.random.randint(10,size=[1,10,10]) + np.eye(10)*10 请注意前面代码中指定的异常大小。 `10, 10`只是图像尺寸,但是`1`是指输入通道的数量。 在这种情况下,我们使用一个输入通道,就像一个灰度图像。 如果您有彩色图像,则这可能是代表红色,绿色和蓝色的三个通道。 -尽管此处的示例和研究问题只有一个通道(灰度级),但我们将在 Deep CNN 部分中看到如何从卷积层产生多个输入,从而在下一个卷积层中产生多通道输入。 因此,您仍然会感觉如何处理。 +尽管此处的示例和研究问题只有一个通道(灰度级),但我们将在深度 CNN 部分中看到如何从卷积层产生多个输入,从而在下一个卷积层中产生多通道输入。 因此,您仍然会感觉如何处理。 向下移动到 TensorFlow 占位符,我们还做了一些看似不寻常的事情。 @@ -214,9 +214,9 @@ plt.colorbar() ![Max pooling layers](img/00053.jpg) -通常,研究人员在一个或多个卷积层之后添加一个池化层。 您最常看到的窗口大小是 2x2。 您要做的只是提取四个相邻的值,此处指的是`H[00]`,通常不会对其施加任何权重。 现在,我们希望以某种方式组合这四个值,以提取此窗口最有趣的特征。 通常,我们要提取最引人注目的特征,因此我们选择最大值(`max(H[00])`)的像素,然后丢弃其余像素。 但是,您也可以平均结果或做一些更奇特的事情。 同样,尽管我们的卷积窗口有很多重叠,但对于合并窗口,我们通常不希望有任何重叠,因此此步长将等于窗口大小 2。 +通常,研究人员在一个或多个卷积层之后添加一个池化层。 您最常看到的窗口大小是`2x2`。 您要做的只是提取四个相邻的值,此处指的是`H[00]`,通常不会对其施加任何权重。 现在,我们希望以某种方式组合这四个值,以提取此窗口最有趣的特征。 通常,我们要提取最引人注目的特征,因此我们选择最大值(`max(H[00])`)的像素,然后丢弃其余像素。 但是,您也可以平均结果或做一些更奇特的事情。 同样,尽管我们的卷积窗口有很多重叠,但对于合并窗口,我们通常不希望有任何重叠,因此此步长将等于窗口大小 2。 -在前面的 10x10 示例输出中,由于步幅的变化,我们的池化输出仅为 5x5。 +在前面的`10x10`示例输出中,由于步幅的变化,我们的池化输出仅为`5x5`。 ![Max pooling layers](img/00054.jpg) @@ -228,15 +228,15 @@ plt.colorbar() ### 注意 -请注意,此示例对池化层使用 9x9 输入,但由于有效的填充和跨度为 2,因此输出仅为 4x4。 8x8 输入也将具有 4x4 输出。 +请注意,此示例对池化层使用`9x9`输入,但由于有效的填充和跨度为 2,因此输出仅为`4x4`。 `8x8`输入也将具有`4x4`输出。 -当您将卷积层和池化层组合在一起时,它们的真正优势就体现出来了。 通常,您会在模型的顶部输入端看到一个卷积层,也许带有 3x3 窗口。 +当您将卷积层和池化层组合在一起时,它们的真正优势就体现出来了。 通常,您会在模型的顶部输入端看到一个卷积层,也许带有`3x3`窗口。 ![Max pooling layers](img/00056.jpg) 这会在图像中的任何位置寻找相同的特征集。 -然后立即出现一个 2x2 的最大池化层,仅池出最具特征的区域并缩小尺寸。 您也可以重复此过程。 +然后立即出现一个`2x2`的最大池化层,仅池出最具特征的区域并缩小尺寸。 您也可以重复此过程。 合并后,您现在实际上具有较小的图像`P1`,但是具有像素强度,而不是像素颜色强度。 因此,您可以创建另一个卷积层以读取第一个池的输出,即底部出现的`P1`,然后可以对此应用另一个最大池化层。 请注意,由于池化,图像大小是如何逐渐缩小的。 直观地,您可以将其视为建立跨越图像较大区域的较大比例的特征。 @@ -248,16 +248,16 @@ plt.colorbar() 让我们从上一节中停下来的示例开始。 在开始本练习之前,请确保您已执行所有操作直到英镑池化层。 -回想一下,我们通过 3x3 卷积和校正的线性激活来放置 10x10 图像。 现在,让我们在卷积层之后添加一个最大 2x2 的池化层。 +回想一下,我们通过`3x3`卷积和校正的线性激活来放置`10x10`图像。 现在,让我们在卷积层之后添加一个最大`2x2`的池化层。 ```py p1 = tf.nn.max_pool(h1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID') ``` -关键是`tf.nn.max_pool`。 第一个参数只是我们先前的卷积层`h1`的输出。 接下来,我们有一个奇怪的`ksize`。 这实际上只是定义了池的窗口大小。 在这种情况下,为 2x2。 第一个`1`指的是一次或批量多少个数据点。 通常,我们将其保留为`1`。 最后的`1`指的是一次包含在合并中的通道数。 请注意,这里有两个通道,因为卷积产生了两个输出滤波器。 但是我们只有`1`在这个位置; 这是一次最多只有一个特征的唯一故障。 步幅的工作方式与卷积层相同。 此处的区别在于我们使用 2x2(即合并窗口的大小),因为我们不希望有任何重叠。 `1`之前和之后的值与卷积层中的值完全相同。 +关键是`tf.nn.max_pool`。 第一个参数只是我们先前的卷积层`h1`的输出。 接下来,我们有一个奇怪的`ksize`。 这实际上只是定义了池的窗口大小。 在这种情况下,为`2x2`。 第一个`1`指的是一次或批量多少个数据点。 通常,我们将其保留为`1`。 最后的`1`指的是一次包含在合并中的通道数。 请注意,这里有两个通道,因为卷积产生了两个输出滤波器。 但是我们只有`1`在这个位置; 这是一次最多只有一个特征的唯一故障。 步幅的工作方式与卷积层相同。 此处的区别在于我们使用`2x2`(即合并窗口的大小),因为我们不希望有任何重叠。 `1`之前和之后的值与卷积层中的值完全相同。 -因此,我们的输出将是每个尺寸的一半,这里是 5x5。 最后,我们将`padding`设置为`VALID`。 这意味着,如果一个窗口超出了图像的边缘(实际上是卷积输出),我们将把它扔掉而不使用它。 如果我们的池化层进入另一个卷积层,则可以在以下代码行中添加它: +因此,我们的输出将是每个尺寸的一半,这里是`5x5`。 最后,我们将`padding`设置为`VALID`。 这意味着,如果一个窗口超出了图像的边缘(实际上是卷积输出),我们将把它扔掉而不使用它。 如果我们的池化层进入另一个卷积层,则可以在以下代码行中添加它: ```py # We automatically determine the size @@ -266,7 +266,7 @@ p1_size = np.product([s.value for s in p1.get_shape()[1:]]) 但是,如果您已经完成了卷积层的工作,并且想要像上一节中的模型那样馈入经典的完全连接层,该怎么办? 这很容易做到; 我们只需要将具有许多输出通道的 2D 矩阵的输出展平到长的一维向量即可。 -该行是自动计算展平池输出长度的一种方法。 它所做的就是乘以所有尺寸的大小。 因此,具有两个通道的 5x5 矩阵将产生`5x5x2`,即`50`输出。 下一行`tf.reshape`使用此值实际展平数组: +该行是自动计算展平池输出长度的一种方法。 它所做的就是乘以所有尺寸的大小。 因此,具有两个通道的`5x5`矩阵将产生`5x5x2`,即`50`输出。 下一行`tf.reshape`使用此值实际展平数组: ```py p1f = tf.reshape(p1, [-1, p1_size ]) @@ -284,9 +284,9 @@ P = p1.eval(feed_dict = {x: image}) ![Pooling layer application](img/00057.jpg) -仅查看前面的第一个过滤器输出,您会注意到它是 5x5。 +仅查看前面的第一个过滤器输出,您会注意到它是`5x5`。 -还要注意,存在的值全部在卷积输出的某些单元中。 由于我们在池化层上的唯一激活是最大值,因此在每个 2x2 窗口中会丢弃三个值,并且一个值会前进到下一层。 +还要注意,存在的值全部在卷积输出的某些单元中。 由于我们在池化层上的唯一激活是最大值,因此在每个`2x2`窗口中会丢弃三个值,并且一个值会前进到下一层。 # 深度 CNN @@ -294,9 +294,9 @@ P = p1.eval(feed_dict = {x: image}) ## 添加卷积和池化层组合 -对于卷积层,我们将使用 5x5 窗口,其中提取了四个特征。 这比示例要大一些。 +对于卷积层,我们将使用`5x5`窗口,其中提取了四个特征。 这比示例要大一些。 -我们真的希望模型现在学习一些东西。 首先,我们应该使用`tf.reshape`将 36x36 的图像放入大小为 36x36x1 的张量中。 +我们真的希望模型现在学习一些东西。 首先,我们应该使用`tf.reshape`将`36x36`的图像放入大小为`36x36x1`的张量中。 ```py x_im = tf.reshape(x, [-1,36,36,1]) @@ -354,7 +354,7 @@ p1 = tf.nn.max_pool(h1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID') ``` -只是为了回顾一下,我们在每次跨步时将 2x2 窗口`ksize`在卷积输出上滑动两个。 当我们超出数据范围时,`padding='VALID'`告诉我们停止。 现在我们有了卷积池和池化层的组合,让我们附加一个典型的密集连接层: +只是为了回顾一下,我们在每次跨步时将`2x2`窗口`ksize`在卷积输出上滑动两个。 当我们超出数据范围时,`padding='VALID'`告诉我们停止。 现在我们有了卷积池和池化层的组合,让我们附加一个典型的密集连接层: ```py p1_size = np.product( @@ -451,7 +451,7 @@ for i in tqdm(range(epochs), ascii=True): ![CNN to classify our fonts](img/00058.jpg) -我们可以看到,该模型优于旧的紧密连接模型,现在达到了 76%的训练准确率和约 68%的验证。 +我们可以看到,该模型优于旧的紧密连接模型,现在达到了 76% 的训练准确率和约 68% 的验证。 这可能是因为字体即使创建许多不同的字母也以相同的方式使用了许多小范围的特征。 让我们也看看混淆矩阵。 @@ -501,9 +501,9 @@ load_all() 与往常一样,在启动新模型时,进行一个新的 IPython 会话并执行直到`num_filters1`的代码。 太好了,现在您都可以开始学习了。 让我们跳入卷积模型。 -我们为何不抱有雄心,将第一个卷积层设置为具有`16`过滤器,远远超过旧模型中的`4`。 但是,这次我们将使用较小的窗口大小。 只有 3x3。 另请注意,我们将某些变量名称(例如`num_filters`更改为`num_filters1`)。 这是因为我们将在短时间内拥有另一个卷积层,并且我们可能希望在每个卷积层上使用不同数量的过滤器。 该层的其余部分与以前完全一样,我们可以进行卷积并进行 2x2 max 池化,并使用整流的线性激活单元。 +我们为何不抱有雄心,将第一个卷积层设置为具有`16`过滤器,远远超过旧模型中的`4`。 但是,这次我们将使用较小的窗口大小。 只有`3x3`。 另请注意,我们将某些变量名称(例如`num_filters`更改为`num_filters1`)。 这是因为我们将在短时间内拥有另一个卷积层,并且我们可能希望在每个卷积层上使用不同数量的过滤器。 该层的其余部分与以前完全一样,我们可以进行卷积并进行`2x2`最大池化,并使用整流的线性激活单元。 -现在,我们添加另一个卷积层。 一些模型先进行几次卷积,然后再进行池化,另一些模型先进行一次卷积,再进行一次池化,再进行一次卷积,依此类推。 我们在这里做后者。 假设您需要四个滤镜和一个 3x3 的窗口。 这很容易产生权重; 与上一层的唯一大不同是我们现在有许多输入通道,请参见`num_filters1`: +现在,我们添加另一个卷积层。 一些模型先进行几次卷积,然后再进行池化,另一些模型先进行一次卷积,再进行一次池化,再进行一次卷积,依此类推。 我们在这里做后者。 假设您需要四个滤镜和一个`3x3`的窗口。 这很容易产生权重; 与上一层的唯一大不同是我们现在有许多输入通道,请参见`num_filters1`: ```py # Conv layer 2 @@ -519,7 +519,7 @@ b2 = tf.Variable(tf.constant(0.1, 这是因为我们有`16`输入通道来自上一层。 如果我们使用`num_filters1 = 8`,则只有`8`输入通道。 将此视为我们将要建立的低级特征。 请记住,通道的数量和输入就像颜色的数量一样,因此,如果您要这样考虑,可能会有所帮助。 -当我们进行实际的第二个卷积层时,请确保传入第一个池化层`p1`的输出。 现在,这可以进入新的`relu`激活函数,然后是另一个池化层。 像往常一样,我们使用有效填充进行最大 2x2 的池化: +当我们进行实际的第二个卷积层时,请确保传入第一个池化层`p1`的输出。 现在,这可以进入新的`relu`激活函数,然后是另一个池化层。 像往常一样,我们使用有效填充进行最大`2x2`的池化: ```py # 3x3 convolution, pad with zeros on edges @@ -679,7 +679,7 @@ for i in range(16): cmap = plt.cm.gray_r) ``` -因为窗口大小是 3x3,所以每个都是 3x3 矩阵。 嗯! 我们可以看到,权重肯定是缩小了小范围的特征。 +因为窗口大小是`3x3`,所以每个都是`3x3`矩阵。 嗯! 我们可以看到,权重肯定是缩小了小范围的特征。 ![Wrapping up deep CNN](img/00062.jpg) @@ -697,7 +697,7 @@ for i in range(16): # 总结 -在本章中,我们遍历了示例图像上的卷积层。 我们解决了理解卷积的实际问题。 它们可以令人费解,但希望不再造成混淆。 我们最终将此概念应用于 TensorFlow 中的一个简单示例。 我们探索了卷积,池化层的共同伙伴。 我们解释了常见的卷积伙伴 max pooling 层的工作原理。 然后,随着我们的进步,我们通过在示例中添加一个池化层将其付诸实践。 我们还练习了在 TensorFlow 中创建最大池化层。 我们开始将卷积神经网络添加到字体分类问题中。 +在本章中,我们遍历了示例图像上的卷积层。 我们解决了理解卷积的实际问题。 它们可以令人费解,但希望不再造成混淆。 我们最终将此概念应用于 TensorFlow 中的一个简单示例。 我们探索了卷积,池化层的共同伙伴。 我们解释了常见的卷积伙伴最大池化层的工作原理。 然后,随着我们的进步,我们通过在示例中添加一个池化层将其付诸实践。 我们还练习了在 TensorFlow 中创建最大池化层。 我们开始将卷积神经网络添加到字体分类问题中。 在下一章中,我们将研究具有时间成分的模型,即循环神经网络(RNN)。 diff --git a/docs/hands-on-dl-tf-zh/ch04.md b/docs/hands-on-dl-tf-zh/ch04.md index 26c20da0..84bb12bf 100644 --- a/docs/hands-on-dl-tf-zh/ch04.md +++ b/docs/hands-on-dl-tf-zh/ch04.md @@ -203,7 +203,7 @@ for i in tqdm(range(epochs), ascii=True): ![Understanding RNNs](img/00065.jpg) -如果您确实看过准确率,您会发现它做得很好。 比 25%的随机猜测要好得多,但仍有很多东西需要学习。 +如果您确实看过准确率,您会发现它做得很好。 比 25% 的随机猜测要好得多,但仍有很多东西需要学习。 # TensorFlowLearn diff --git a/docs/hands-on-dl-tf-zh/ch05.md b/docs/hands-on-dl-tf-zh/ch05.md index 0c160652..8b6f1255 100644 --- a/docs/hands-on-dl-tf-zh/ch05.md +++ b/docs/hands-on-dl-tf-zh/ch05.md @@ -83,7 +83,7 @@ y = tf.nn.softmax(tf.matmul(x,W) + b) ![The single hidden layer neural network model](img/00069.jpg) -该模型具有 36x36 像素,外加 1 个偏移乘以 128 个节点,再加上 128 个隐藏节点加上 1 个偏移乘以 5 个类的总权重,即 166,661 个参数。 隐藏层使用`sigmoid`激活函数来实现非线性。 在经过 5,000 个周期后,参数的纠缠达到了约 60%的验证准确率,这是一个很大的改进。 但是,此改进的代价是大量增加了计算复杂性中的参数数量,您可以从代码中大致了解一下: +该模型具有 36x36 像素,外加 1 个偏移乘以 128 个节点,再加上 128 个隐藏节点加上 1 个偏移乘以 5 个类的总权重,即 166,661 个参数。 隐藏层使用`sigmoid`激活函数来实现非线性。 在经过 5,000 个周期后,参数的纠缠达到了约 60% 的验证准确率,这是一个很大的改进。 但是,此改进的代价是大量增加了计算复杂性中的参数数量,您可以从代码中大致了解一下: ```py # These will be inputs @@ -209,7 +209,7 @@ keep_prob = tf.placeholder("float") h2_drop = tf.nn.dropout(h2, keep_prob) ``` -仅训练了 5000 个周期后,我们就清除了 68%的准确率。 我们确实必须对卷积进行编码,但这并不是那么困难。 通过对问题的结构应用一些知识,我们同时减小了模型大小,但提高了准确率。 干得好! +仅训练了 5000 个周期后,我们就清除了 68% 的准确率。 我们确实必须对卷积进行编码,但这并不是那么困难。 通过对问题的结构应用一些知识,我们同时减小了模型大小,但提高了准确率。 干得好! ## 深度卷积神经网络 @@ -217,7 +217,7 @@ h2_drop = tf.nn.dropout(h2, keep_prob) ![Deep convolutional neural network](img/00072.jpg) -尽管我们使用了较小的 3x3 窗口,但我们在第一个卷积层上计算了 16 个滤镜。 在进行最大 2x2 的池化之后,我们再次使用另一个 3x3 窗口和 4 个过滤器对池化值进行了处理。 另一个合并层再次馈入 32 个紧密连接的神经元和 Softmax 输出。 因为在馈入密集神经网络之前我们在池中有更多的卷积,所以在此模型中实际上我们具有较少的参数(准确地说是 10,765 个),几乎与逻辑回归模型一样少。 但是,该模型以 6,000 个周期的速度达到了 80%的验证准确率,证明了您的新深度学习和 TensorFlow 技能。 +尽管我们使用了较小的 3x3 窗口,但我们在第一个卷积层上计算了 16 个滤镜。 在进行最大 2x2 的池化之后,我们再次使用另一个 3x3 窗口和 4 个过滤器对池化值进行了处理。 另一个合并层再次馈入 32 个紧密连接的神经元和 Softmax 输出。 因为在馈入密集神经网络之前我们在池中有更多的卷积,所以在此模型中实际上我们具有较少的参数(准确地说是 10,765 个),几乎与逻辑回归模型一样少。 但是,该模型以 6,000 个周期的速度达到了 80% 的验证准确率,证明了您的新深度学习和 TensorFlow 技能。 ```py # Conv layer 1 -- GitLab