提交 10b71cd3 编写于 作者: X xiaotinghe 提交者: Aston Zhang

fix wrong tag

上级 cbd8baa7
......@@ -10,7 +10,7 @@
为什么需要批量归一化层呢?让我们来回顾一下训练神经网络时出现的一些实际挑战。
首先,数据预处理的方式通常会对最终结果产生巨大影响。
回想一下我们应用多层感知机来预测房价的例子(:numref:`sec_kaggle_house`)。
回想一下我们应用多层感知机来预测房价的例子( :numref:`sec_kaggle_house` )。
使用真实数据时,我们的第一步是标准化输入特征,使其平均值为0,方差为1。
直观地说,这种标准化可以很好地与我们的优化器配合使用,因为它可以将参数的量级进行统一。
......@@ -53,7 +53,7 @@ $$\begin{aligned} \hat{\boldsymbol{\mu}}_\mathcal{B} &= \frac{1}{|\mathcal{B}|}
事实证明,这是深度学习中一个反复出现的主题。
由于理论上尚未明确表述的原因,优化中的各种噪声源通常会导致更快的训练和较少的过拟合:这种变化似乎是正则化的一种形式。
在一些初步研究中,:cite:`Teye.Azizpour.Smith.2018` 和 :cite:`Luo.Wang.Shao.ea.2018` 分别将批量归一化的性质与贝叶斯先验相关联。
在一些初步研究中, :cite:`Teye.Azizpour.Smith.2018` 和 :cite:`Luo.Wang.Shao.ea.2018` 分别将批量归一化的性质与贝叶斯先验相关联。
这些理论揭示了为什么批量归一化最适应 $50 \sim 100$ 范围中的中等小批量尺寸的难题。
另外,批量归一化图层在”训练模式“(通过小批量统计数据归一化)和“预测模式”(通过数据集统计归一化)中的功能不同。
......@@ -302,7 +302,7 @@ class BatchNorm(tf.keras.layers.Layer):
## 使用批量归一化层的 LeNet
为了更好理解如何应用 `BatchNorm`,下面我们将其应用于 Lenet 模型 (:numref:`sec_lenet`)
为了更好理解如何应用 `BatchNorm`,下面我们将其应用于 LeNet 模型( :numref:`sec_lenet`
回想一下,批量归一化是在卷积层或全连接层之后、相应的激活函数之前应用的。
```{.python .input}
......@@ -363,7 +363,7 @@ def net():
```
和以前一样,我们将在 Fashion-MNIST 数据集训练我们的网络。
这个代码与我们第一次训练 Lenet(:numref:`sec_lenet`)时几乎完全相同,主要区别在于学习率大得多。
这个代码与我们第一次训练 LeNet( :numref:`sec_lenet` )时几乎完全相同,主要区别在于学习率大得多。
```{.python .input}
#@tab mxnet, pytorch
......@@ -467,7 +467,7 @@ d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr)
直观地说,批量归一化被认为可以使优化更加平滑。
然而,我们必须小心区分投机直觉和对我们观察到的现象的真实解释。
回想一下,我们甚至不知道为什么简单的神经网络(MLP 和传统的 CNN)为什么如此有效。
回想一下,我们甚至不知道为什么简单的神经网络(多层感知机和传统的卷积神经网络)为什么如此有效。
即使在 dropout 和权重衰减的情况下,它们仍然非常灵活,因此无法通过传统的学习理论泛化保证来解释它们是否能够概括到看不见的数据。
在提出批量归一化的论文中,作者除了介绍了其应用,还解释了其原理:通过减少 *内部协变量偏移*(internal covariate shift)。
......@@ -481,7 +481,7 @@ ii)这种解释只提供了一种不明确的直觉,但留下了一个有待
随着批量归一化的普及,“内部协变量偏移”的解释反复出现在技术文献的辩论,特别是关于“如何展示机器学习研究”的更广泛的讨论中。
Ali Rahimi 在接受 2017 年 NeurIPS 大会的“接受时间考验奖”(Test of Time Award)时发表了一篇令人难忘的演讲。他将“内部协变量转移”作为焦点,将现代深度学习的实践比作炼金术。
他对该示例进行了详细回顾 :cite:`Lipton.Steinhardt.2018`,概述了机器学习中令人不安的趋势。
他对该示例进行了详细回顾 :cite:`Lipton.Steinhardt.2018` ,概述了机器学习中令人不安的趋势。
此外,一些作者对批量归一化的成功提出了另一种解释:在某些方面,批量归一化的表现出与原始论文 :cite:`Santurkar.Tsipras.Ilyas.ea.2018` 中声称的行为是相反的。
然而,与技术机器学习文献中成千上万类似模糊的声明相比,内部协变量偏移没有什么更值得批评。
......
......@@ -29,7 +29,7 @@ $$\mathbf{x} \to \left[
f_1(\mathbf{x}),
f_2([\mathbf{x}, f_1(\mathbf{x})]), f_3([\mathbf{x}, f_1(\mathbf{x}), f_2([\mathbf{x}, f_1(\mathbf{x})])]), \ldots\right].$$
最后,将这些展开式结合到 MLP 中,再次减少特征的数量。
最后,将这些展开式结合到多层感知机中,再次减少特征的数量。
实现起来非常简单:我们不需要添加术语,而是将它们连接起来。
DenseNet 这个名字由变量之间的“稠密连接”而得来,最后一层与之前的所有层紧密相连。
稠密连接如 :numref:`fig_densenet` 所示。
......@@ -381,7 +381,7 @@ d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr)
1. 真的是这样吗?可以把输入形状换成 $224 \times 224$ ,来看看实际的显存消耗。
1. 你能想出另一种方法来减少显存消耗吗?你需要如何改变框架?
1. 实现 DenseNet 论文 :cite:`Huang.Liu.Van-Der-Maaten.ea.2017` 表 1 所示的不同 DenseNet 版本。
1. 应用DenseNet的思想设计一个基于多层感知机的模型。将其应用于:numref:`sec_kaggle_house`中的房价预测任务。
1. 应用DenseNet的思想设计一个基于多层感知机的模型。将其应用于 :numref:`sec_kaggle_house` 中的房价预测任务。
:begin_tab:`mxnet`
......
......@@ -344,7 +344,7 @@ d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr)
* 添加批量归一化层 :cite:`Ioffe.Szegedy.2015`(batch normalization),在 :numref:`sec_batch_norm`中将介绍)。
* 对 Inception 模块进行调整。
* 使用标签平滑(label smoothing)进行模型正则化 :cite:`Szegedy.Vanhoucke.Ioffe.ea.2016`
* 加入残差连接 :cite:`Szegedy.Ioffe.Vanhoucke.ea.2017` ,(:numref:`sec_resnet`一节将介绍)。
* 加入残差连接 :cite:`Szegedy.Ioffe.Vanhoucke.ea.2017` ,( :numref:`sec_resnet` 将介绍)。
1. 使用 GoogLeNet 的最小图像大小是多少?
1. 将 AlexNet、VGG 和 NiN 的模型参数大小与 GoogLeNet 进行比较。后两个网络结构是如何显著减少模型参数大小的?
......
# 卷积神经网络之LeNet
# 卷积神经网络(LeNet)
:label:`sec_lenet`
通过之前几节,我们学习了构建一个完整卷积神经网络的所需组件。
回想一下,之前我们将 softmax 回归模型(:numref:`sec_softmax_scratch`)和全连接层模型(:numref:`sec_mlp_scratch`)应用于 Fashion-MNIST 数据集中的服装图片上。
回想一下,之前我们将 softmax 回归模型( :numref:`sec_softmax_scratch` )和多层感知机模型( :numref:`sec_mlp_scratch` )应用于 Fashion-MNIST 数据集中的服装图片上。
为了能够应用 softmax 回归和多层感知机,我们首先将每个大小为 $28\times28$ 的图像展平为一个 784 固定长度的一维向量,然后用全连接层对其进行处理。
而现在,我们已经掌握了卷积层的处理方法,我们可以在图像中保留空间结构。
同时,用卷积层代替全连接层的另一个好处是:更简洁的模型所需的参数更少。
......@@ -95,7 +95,7 @@ def net():
我们对原始模型做了一点小改动,去掉了最后一层的高斯激活。除此之外,这个网络与最初的 LeNet-5 一致。
下面,我们将一个大小为 $28 \times 28$ 的单通道(黑白)图像通过 Lenet。 通过在每一层打印输出的形状,我们可以检查模型,以确保其操作与我们期望的 :numref:`img_lenet_vert` 一致。
下面,我们将一个大小为 $28 \times 28$ 的单通道(黑白)图像通过 LeNet。 通过在每一层打印输出的形状,我们可以检查模型,以确保其操作与我们期望的 :numref:`img_lenet_vert` 一致。
![LeNet 的简化版。](../img/lenet-vert.svg)
:label:`img_lenet_vert`
......
......@@ -13,7 +13,7 @@
## 实例化网络
首先,让我们实例化一个MLP
首先,让我们实例化一个多层感知机
```{.python .input}
from mxnet import init, np, npx
......
......@@ -3,7 +3,7 @@
除了庞大的数据集和强大的硬件,优秀的软件工具在深度学习的快速发展中发挥了不可或缺的作用。从2007年发布的开创性的Theano库开始,灵活的开源工具使研究人员能够快速开发模型原型,避免了使用标准组件时的重复工作,同时仍然保持了进行底层修改的能力。随着时间的推移,深度学习库已经演变成提供越来越粗糙的抽象。就像半导体设计师从指定晶体管到逻辑电路再到编写代码一样,神经网络研究人员已经从考虑单个人工神经元的行为转变为从层的角度构思网络,现在通常在设计结构时考虑的是更粗糙的块(block)。
到目前为止,我们已经介绍了一些基本的机器学习概念,并慢慢介绍了功能齐全的深度学习模型。在上一章中,我们从零开始实现了MLP的每个组件,然后展示了如何利用高级API轻松地实现相同的模型。为了易于学习,我们调用了深度学习库,但是跳过了它们工作的细节。在本章中,我们开始深入探索深度学习计算的关键组件,即模型构建、参数访问与初始化、设计自定义层和块、将模型读写到磁盘,以及利用GPU实现显著的加速。这些知识将使你从*基础用户*变为*高级用户*。虽然本章不介绍任何新的模型或数据集,但后面的高级模型章节在很大程度上依赖于本章的知识。
到目前为止,我们已经介绍了一些基本的机器学习概念,并慢慢介绍了功能齐全的深度学习模型。在上一章中,我们从零开始实现了多层感知机的每个组件,然后展示了如何利用高级API轻松地实现相同的模型。为了易于学习,我们调用了深度学习库,但是跳过了它们工作的细节。在本章中,我们开始深入探索深度学习计算的关键组件,即模型构建、参数访问与初始化、设计自定义层和块、将模型读写到磁盘,以及利用GPU实现显著的加速。这些知识将使你从*基础用户*变为*高级用户*。虽然本章不介绍任何新的模型或数据集,但后面的高级模型章节在很大程度上依赖于本章的知识。
```toc
:maxdepth: 2
......
# 层和块
:label:`sec_model_construction`
当我们第一次介绍神经网络时,我们关注的是具有单一输出的线性模型。在这里,整个模型只由一个神经元组成。注意,单个神经元(1)接受一些输入;(2)生成相应的标量输出;(3)具有一组相关参数,这些参数可以更新以优化某些感兴趣的目标函数。然后,当我们开始考虑具有多个输出的网络,我们就利用矢量化算法来描述整层神经元。像单个神经元一样,层(1)接受一组输入,(2)生成相应的输出,(3)由一组可调整参数描述。当我们使用softmax回归时,一个单层本身就是模型。然而,即使我们随后引入了MLP,我们仍然可以认为该模型保留了上面所说的基本结构。
当我们第一次介绍神经网络时,我们关注的是具有单一输出的线性模型。在这里,整个模型只由一个神经元组成。注意,单个神经元(1)接受一些输入;(2)生成相应的标量输出;(3)具有一组相关参数,这些参数可以更新以优化某些感兴趣的目标函数。然后,当我们开始考虑具有多个输出的网络,我们就利用矢量化算法来描述整层神经元。像单个神经元一样,层(1)接受一组输入,(2)生成相应的输出,(3)由一组可调整参数描述。当我们使用softmax回归时,一个单层本身就是模型。然而,即使我们随后引入了多层感知机,我们仍然可以认为该模型保留了上面所说的基本结构。
有趣的是,对于MLP而言,整个模型及其组成层都是这种结构。整个模型接受原始输入(特征),生成输出(预测),并包含一些参数(所有组成层的参数集合)。同样,每个单独的层接收输入(由前一层提供)生成输出(到下一层的输入),并且具有一组可调参数,这些参数根据从下一层反向传播的信号进行更新。
有趣的是,对于多层感知机而言,整个模型及其组成层都是这种结构。整个模型接受原始输入(特征),生成输出(预测),并包含一些参数(所有组成层的参数集合)。同样,每个单独的层接收输入(由前一层提供)生成输出(到下一层的输入),并且具有一组可调参数,这些参数根据从下一层反向传播的信号进行更新。
虽然你可能认为神经元、层和模型为我们的业务提供了足够的抽象,但事实证明,我们经常发现谈论比单个层大但比整个模型小的组件更方便。例如,在计算机视觉中广泛流行的ResNet-152结构就有数百层。这些层是 由*层组*的重复模式组成。一次只实现一层这样的网络会变得很乏味。这种问题不是我们幻想出来的,这种设计模式在实践中很常见。上面提到的ResNet结构赢得了2015年ImageNet和COCO计算机视觉比赛的识别和检测任务 :cite:`He.Zhang.Ren.ea.2016`,目前ResNet结构仍然是许多视觉任务的首选结构。在其他的领域,如自然语言处理和语音,层以各种重复模式排列的类似结构现在也是普遍存在。
为了实现这些复杂的网络,我们引入了神经网络*块*的概念。块可以描述单个层、由多个层组成的组件或整个模型本身。使用块进行抽象的一个好处是可以将一些块组合成更大的组件,这一过程通常是递归的。这一点在:numref:`fig_blocks`中进行了说明。通过定义代码来按需生成任意复杂度的块,我们可以通过简洁的代码实现复杂的神经网络。
为了实现这些复杂的网络,我们引入了神经网络*块*的概念。块可以描述单个层、由多个层组成的组件或整个模型本身。使用块进行抽象的一个好处是可以将一些块组合成更大的组件,这一过程通常是递归的。这一点在 :numref:`fig_blocks` 中进行了说明。通过定义代码来按需生成任意复杂度的块,我们可以通过简洁的代码实现复杂的神经网络。
![多个层被组合成块,形成更大的模型。](../img/blocks.svg)
:label:`fig_blocks`
从编程的角度来看,块由*类*(class)表示。它的任何子类都必须定义一个将其输入转换为输出的正向传播函数,并且必须存储任何必需的参数。注意,有些块不需要任何参数。最后,为了计算梯度,块必须具有反向传播函数。幸运的是,在定义我们自己的块时,由于自动微分(在:numref:`sec_autograd`中引入)提供了一些后端实现,我们只需要考虑正向传播函数和必需的参数。
从编程的角度来看,块由*类*(class)表示。它的任何子类都必须定义一个将其输入转换为输出的正向传播函数,并且必须存储任何必需的参数。注意,有些块不需要任何参数。最后,为了计算梯度,块必须具有反向传播函数。幸运的是,在定义我们自己的块时,由于自动微分(在 :numref:`sec_autograd` 中引入)提供了一些后端实现,我们只需要考虑正向传播函数和必需的参数。
首先,我们回顾一下MLP(:numref:`sec_mlp_concise`)的代码。下面的代码生成一个网络,其中包含一个具有256个单元和ReLU激活函数的全连接的隐藏层,然后是一个具有10个隐藏单元且不带激活函数的全连接的输出层。
首先,我们回顾一下多层感知机( :numref:`sec_mlp_concise` )的代码。下面的代码生成一个网络,其中包含一个具有256个单元和ReLU激活函数的全连接的隐藏层,然后是一个具有10个隐藏单元且不带激活函数的全连接的输出层。
```{.python .input}
from mxnet import np, npx
......@@ -77,7 +77,7 @@ net(X)
1. 存储和访问正向传播计算所需的参数。
1. 根据需要初始化模型参数。
在下面的代码片段中,我们从零开始编写一个块。它包含一个MLP,其具有256个隐藏单元的隐藏层和一个10维输出层。注意,下面的`MLP`类继承了表示块的类。我们的实现将严重依赖父类,只需要提供我们自己的构造函数(Python中的`__init__`函数)和正向传播函数。
在下面的代码片段中,我们从零开始编写一个块。它包含一个多层感知机,其具有256个隐藏单元的隐藏层和一个10维输出层。注意,下面的`MLP`类继承了表示块的类。我们的实现将严重依赖父类,只需要提供我们自己的构造函数(Python中的`__init__`函数)和正向传播函数。
```{.python .input}
class MLP(nn.Block):
......@@ -128,9 +128,9 @@ class MLP(tf.keras.Model):
return self.out(self.hidden((X)))
```
让我们首先关注正向传播函数。注意,它以`X`作为输入,计算带有激活函数的隐藏表示,并输出其未归一化的输出值。在这个`MLP`实现中,两个层都是实例变量。要了解这为什么是合理的,可以想象实例化两个MLP(`net1``net2`),并根据不同的数据对它们进行训练。当然,我们希望它们学到两种不同的模型。
让我们首先关注正向传播函数。注意,它以`X`作为输入,计算带有激活函数的隐藏表示,并输出其未归一化的输出值。在这个`MLP`实现中,两个层都是实例变量。要了解这为什么是合理的,可以想象实例化两个多层感知机(`net1``net2`,并根据不同的数据对它们进行训练。当然,我们希望它们学到两种不同的模型。
我们在构造函数中实例化MLP的层,然后在每次调用正向传播函数时调用这些层。注意一些关键细节。首先,我们定制的`__init__`函数通过`super().__init__()`调用父类的`__init__`函数,省去了重复编写适用于大多数块的模版代码的痛苦。然后我们实例化两个全连接层,分别为`self.hidden``self.out`。注意,除非我们实现一个新的运算符,否则我们不必担心反向传播函数或参数初始化,系统将自动生成这些。让我们试一下。
我们在构造函数中实例化多层感知机的层,然后在每次调用正向传播函数时调用这些层。注意一些关键细节。首先,我们定制的`__init__`函数通过`super().__init__()`调用父类的`__init__`函数,省去了重复编写适用于大多数块的模版代码的痛苦。然后我们实例化两个全连接层,分别为`self.hidden``self.out`。注意,除非我们实现一个新的运算符,否则我们不必担心反向传播函数或参数初始化,系统将自动生成这些。让我们试一下。
```{.python .input}
net = MLP()
......@@ -215,7 +215,7 @@ class MySequential(tf.keras.Model):
`__init__`方法中,我们将每个块逐个添加到有序字典`_modules`中。你可能会想知道为什么每个`Module`都有一个`_modules`属性,以及为什么我们使用它而不是自己定义一个Python列表。简而言之,`_modules`的主要优点是,在块的参数初始化过程中,系统知道在`_modules`字典中查找需要初始化参数的子块。
:end_tab:
`MySequential`的正向传播函数被调用时,每个添加的块都按照它们被添加的顺序执行。现在可以使用我们的`MySequential`类重新实现MLP
`MySequential`的正向传播函数被调用时,每个添加的块都按照它们被添加的顺序执行。现在可以使用我们的`MySequential`类重新实现多层感知机
```{.python .input}
net = MySequential()
......@@ -239,7 +239,7 @@ net = MySequential(
net(X)
```
注意,`MySequential`的用法与之前为`Sequential`类编写的代码相同(如:numref:`sec_mlp_concise`中所述)。
注意,`MySequential`的用法与之前为`Sequential`类编写的代码相同(如 :numref:`sec_mlp_concise` 中所述)。
## 在正向传播函数中执行代码
......@@ -389,7 +389,7 @@ chimera(X)
热心的读者可能会开始担心其中一些操作的效率。毕竟,我们在一个应该是高性能的深度学习库中进行了大量的字典查找、代码执行和许多其他的Python代码。Python的问题[全局解释器锁](https://wiki.python.org/moin/GlobalInterpreterLock)是众所周知的。在深度学习环境中,我们担心速度极快的GPU可能要等到CPU运行Python代码后才能运行另一个作业。提高Python速度的最好方法是完全避免使用Python。
Gluon这样做的一个方法是允许*混合式编程*(hybridization),这将在后面描述。
Python解释器在第一次调用块时执行它。Gluon运行时记录正在发生的事情,以及下一次它将对Python调用加速。在某些情况下,这可以大大加快速度,但当控制流(如上所述)在不同的网络通路上引导不同的分支时,需要格外小心。我们建议感兴趣的读者在读完本章后,阅读混合式编程部分(:numref:`sec_hybridize`)来了解编译。
Python解释器在第一次调用块时执行它。Gluon运行时记录正在发生的事情,以及下一次它将对Python调用加速。在某些情况下,这可以大大加快速度,但当控制流(如上所述)在不同的网络通路上引导不同的分支时,需要格外小心。我们建议感兴趣的读者在读完本章后,阅读混合式编程部分( :numref:`sec_hybridize` )来了解编译。
:end_tab:
:begin_tab:`pytorch`
......
......@@ -8,7 +8,7 @@
* 参数初始化。
* 在不同模型组件间共享参数。
我们首先关注具有一个隐藏层的MLP
我们首先关注具有单隐藏层的多层感知机
```{.python .input}
from mxnet import init, np, npx
......@@ -526,9 +526,9 @@ print(len(net.layers) == 3)
## 练习
1. 使用:numref:`sec_model_construction`中定义的`FancyMLP`模型,访问各个层的参数。
1. 使用 :numref:`sec_model_construction` 中定义的`FancyMLP`模型,访问各个层的参数。
1. 查看初始化模块文档以了解不同的初始化方法。
1. 构建包含共享参数层的MLP并对其进行训练。在训练过程中,观察模型各层的参数和梯度。
1. 构建包含共享参数层的多层感知机并对其进行训练。在训练过程中,观察模型各层的参数和梯度。
1. 为什么共享参数是个好主意?
:begin_tab:`mxnet`
......
......@@ -105,7 +105,7 @@ mydict2
## 加载和保存模型参数
保存单个权重向量(或其他张量)确实是有用的,但是如果我们想保存整个模型,并在以后加载它们。单独保存每个向量则会变得很麻烦。毕竟,我们可能有数百个参数散布在各处。因此,深度学习框架提供了内置函数来保存和加载整个网络。需要注意的一个重要细节是,这将保存模型的*参数*(parameters)而不是保存整个模型。例如,如果我们有一个3层MLP,我们需要单独指定结构。因为模型本身可以包含任意代码,所以模型本身难以序列化。因此,为了恢复模型,我们需要用代码生成结构,然后从磁盘加载参数。让我们从熟悉的MLP开始尝试一下。
保存单个权重向量(或其他张量)确实是有用的,但是如果我们想保存整个模型,并在以后加载它们。单独保存每个向量则会变得很麻烦。毕竟,我们可能有数百个参数散布在各处。因此,深度学习框架提供了内置函数来保存和加载整个网络。需要注意的一个重要细节是,这将保存模型的*参数*(parameters)而不是保存整个模型。例如,如果我们有一个3层多层感知机,我们需要单独指定结构。因为模型本身可以包含任意代码,所以模型本身难以序列化。因此,为了恢复模型,我们需要用代码生成结构,然后从磁盘加载参数。让我们从熟悉的多层感知机开始尝试一下。
```{.python .input}
class MLP(nn.Block):
......@@ -174,7 +174,7 @@ torch.save(net.state_dict(), 'mlp.params')
net.save_weights('mlp.params')
```
为了恢复模型,我们实例化了原始MLP模型的一个备份。我们没有随机初始化模型参数,而是直接读取文件中存储的参数。
为了恢复模型,我们实例化了原始多层感知机模型的一个备份。我们没有随机初始化模型参数,而是直接读取文件中存储的参数。
```{.python .input}
clone = MLP()
......
# GPU
:label:`sec_use_gpu`
:numref:`tab_intro_decade`中,我们讨论了过去20年中计算能力的快速增长。简而言之,自2000年以来,GPU性能每十年增长1000倍。这提供了巨大的机会,但也表明需要提供这样的性能。
:numref:`tab_intro_decade` 中,我们讨论了过去20年中计算能力的快速增长。简而言之,自2000年以来,GPU性能每十年增长1000倍。这提供了巨大的机会,但也表明需要提供这样的性能。
在本节中,我们开始讨论如何利用这种计算性能进行研究。首先是使用单个GPU,然后是如何使用多个GPU和多个服务器(具有多个GPU)。
......@@ -195,7 +195,7 @@ Y
### 复制
如果我们要计算`X + Y`,我们需要决定在哪里执行这个操作。例如,如:numref:`fig_copyto`所示,我们可以将`X`传输到第二个GPU并在那里执行操作。
如果我们要计算`X + Y`,我们需要决定在哪里执行这个操作。例如,如 :numref:`fig_copyto` 所示,我们可以将`X`传输到第二个GPU并在那里执行操作。
*不要*简单地`X`加上`Y`
因为这会导致异常。运行时引擎不知道该怎么做:它在同一设备上找不到数据会导致失败。由于`Y`位于第二个GPU上,所以我们需要将`X`移到那里,然后才能添加这两个GPU。
......
......@@ -295,7 +295,7 @@
与解决回归问题不同,分类问题的常见损失函数被称为*交叉熵*(cross-entropy),我们将在后面的章节中详细阐述。
请注意,最常见的类别不一定是你将用于决策的类别。
举个例子,假设你在后院发现了一个美丽的蘑菇,如:numref:`fig_death_cap`所示。
举个例子,假设你在后院发现了一个美丽的蘑菇,如 :numref:`fig_death_cap` 所示。
![死帽蕈——不能吃!!](../img/death-cap.jpg)
:width:`200px`
......@@ -309,7 +309,7 @@
因此,我们需要将“预期风险”作为损失函数。
也就是说,我们需要将结果的概率乘以与之相关的收益(或伤害)。
在这种情况下,食用蘑菇造成的损失为 $0.2 \times \infty + 0.8 \times 0 = \infty$,而丢弃蘑菇的损失为$0.2 \times 0 + 0.8 \times 1 = 0.8$。
我们的谨慎是有道理的:正如任何真菌学家都会告诉我们的那样,:numref:`fig_death_cap` 中的蘑菇实际上是一个死帽蕈。
我们的谨慎是有道理的:正如任何真菌学家都会告诉我们的那样, :numref:`fig_death_cap` 中的蘑菇实际上是一个死帽蕈。
分类可能变得比二元分类、多类分类复杂得多。
例如,有一些分类任务的变体可以用于寻找层次结构,层次结构假定在许多类之间存在某种关系。
......@@ -367,7 +367,7 @@
#### 推荐系统
:label:`subsec_recommender_systems`
另一类与搜索和排名相关的问题是*推荐系统*(recommender system),它的目标是向给特定用户进行“个性化”推荐。
另一类与搜索和排名相关的问题是*推荐系统*(recommender system),它的目标是向给特定用户进行“个性化”推荐。
例如,对于电影推荐,科幻迷和喜剧爱好者的推荐结果页面可能会有很大不同。
类似的应用也会出现在零售产品、音乐和新闻推荐等等。
......@@ -378,7 +378,7 @@
总的来说,推荐系统会为“给定用户和物品”的匹配性打分,这个“分数”可能是估计的评级或购买的概率。
由此,对于任何给定的用户,推荐系统都可以检索得分最高的对象集,然后将其推荐给用户。以上只是简单的算法,而工艺生产的推荐系统要先进得多,它会将详细的用户活动和项目特征考虑在内。
推荐系统算法经过调整,可以捕捉一个人的偏好。
比如,:numref:`fig_deeplearning_amazon`是亚马逊基于个性化算法推荐的深度学习书籍,成功的捕捉了作者的喜好。
比如, :numref:`fig_deeplearning_amazon` 是亚马逊基于个性化算法推荐的深度学习书籍,成功的捕捉了作者的喜好。
![亚马逊推荐的深度学习书籍](../img/deeplearning-amazon.jpg)
:label:`fig_deeplearning_amazon`
......@@ -425,7 +425,7 @@ Ent - - - Ent - Ent
```
**自动语音识别**。在语音识别中,输入序列是说话人的录音(如:numref:`fig_speech`所示),输出序列是说话人所说内容的文本记录。
**自动语音识别**。在语音识别中,输入序列是说话人的录音(如 :numref:`fig_speech` 所示),输出序列是说话人所说内容的文本记录。
它的挑战在于,与文本相比,音频帧多得多(声音通常以8kHz或16kHz采样)。
也就是说,音频和文本之间没有1:1的对应关系,因为数千个样本可能对应于一个单独的单词。
这也是“序列到序列”的学习问题,其中输出比输入短得多。
......@@ -625,7 +625,7 @@ agent的动作会影响后续的观察,而奖励只与所选的动作相对应
其一,随着互联网的公司的出现,为数亿在线用户提供服务,大规模数据集变得触手可及。
另外,廉价又高质量的传感器、廉价的数据存储(克里德定律)以及廉价计算(摩尔定律)的普及,特别是GPU的普及,使大规模算力唾手可得。
这一点在:numref:`tab_intro_decade`中得到了说明。
这一点在 :numref:`tab_intro_decade` 中得到了说明。
:数据集vs计算机内存和计算能力
......@@ -643,7 +643,7 @@ agent的动作会影响后续的观察,而奖励只与所选的动作相对应
与此同时,算力的增长速度已经超过了现有数据的增长速度。
这意味着统计模型需要提高内存效率(这通常是通过添加非线性来实现的),同时由于计算预算的增加,能够花费更多时间来优化这些参数。
因此,机器学习和统计的关注点从(广义的)线性模型和核方法转移到了深度神经网络。
这也是为什么许多深度学习的中流砥柱,如多层感知器:cite:`McCulloch.Pitts.1943`、卷积神经网络:cite:`LeCun.Bottou.Bengio.ea.1998`、长短期记忆网络:cite:`Watkins.Dayan.1992`和Q学习:cite:`Watkins.Dayan.1992`,在相当长一段时间处于相对休眠状态之后,在过去十年中被“重新发现”的原因之一。
这也是为什么许多深度学习的中流砥柱,如多层感知机 :cite:`McCulloch.Pitts.1943` 、卷积神经网络 :cite:`LeCun.Bottou.Bengio.ea.1998` 、长短期记忆网络 :cite:`Watkins.Dayan.1992` 和Q学习 :cite:`Watkins.Dayan.1992` ,在相当长一段时间处于相对休眠状态之后,在过去十年中被“重新发现”的原因之一。
最近十年,在统计模型、应用和算法方面的进展就像寒武纪大爆发。
事实上,最先进的技术不仅仅是应用于几十年前的算法的可用资源的结果。
......@@ -714,6 +714,6 @@ agent的动作会影响后续的观察,而奖励只与所选的动作相对应
1. 你当前正在编写的代码的哪些部分可以“学习”,即通过学习和自动确定代码中所做的设计选择来改进?你的代码是否包含启发式设计选择?
1. 您遇到的哪些问题有许多解决它们的样本,但没有具体的自动化方法?这些可能是使用深度学习的主要候选者。
1. 把人工智能的发展看作一场新的工业革命,算法和数据之间的关系是什么?它类似于蒸汽机和煤吗?根本区别是什么?
1. 你还可以在哪里应用端到端的训练方法,比如:numref:`fig_ml_loop`、物理、工程和计量经济学?
1. 你还可以在哪里应用端到端的训练方法,比如 :numref:`fig_ml_loop` 、物理、工程和计量经济学?
[Discussions](https://discuss.d2l.ai/t/22)
# softmax回归的简洁实现
:label:`sec_softmax_concise`
在 :numref:`sec_linear_concise` 中,我们可以发现通过深度学习框架的高级API能够使实现线性回归变得更加容易。同样地,通过深度学习框架的高级API也能更方便地实现分类模型。让我们继续使用Fashion-MNIST数据集,并保持批量大小为256,就像在:numref:`sec_softmax_scratch` 中一样。
在 :numref:`sec_linear_concise` 中,我们可以发现通过深度学习框架的高级API能够使实现线性回归变得更加容易。同样地,通过深度学习框架的高级API也能更方便地实现分类模型。让我们继续使用Fashion-MNIST数据集,并保持批量大小为256,就像在 :numref:`sec_softmax_scratch` 中一样。
```{.python .input}
from d2l import mxnet as d2l
......
......@@ -59,7 +59,7 @@ $$
我们希望模型的输出 $\hat{y}_j$ 可以视为属于类 $j$ 的概率。然后我们可以选择具有最大输出值的类别$\operatorname*{argmax}_j y_j$作为我们的预测。例如,如果 $\hat{y}_1$、$\hat{y}_2$ 和 $\hat{y}_3$ 分别为 0.1、0.8 和 0.1,那么我们预测的类别是2,在我们的例子中代表 “鸡”。
你可能会想是否可以将未归一化的预测 $o$ 直接视作我们感兴趣的输出。但是,将线性层的输出直接视为概率时存在一些问题:一方面,没有限制这些数字的总和为1。另一方面,根据输入的不同,它们可以为负值。这些违反了:numref:`sec_prob` 中所说的概率基本公理。
你可能会想是否可以将未归一化的预测 $o$ 直接视作我们感兴趣的输出。但是,将线性层的输出直接视为概率时存在一些问题:一方面,没有限制这些数字的总和为1。另一方面,根据输入的不同,它们可以为负值。这些违反了 :numref:`sec_prob` 中所说的概率基本公理。
要将输出视为概率,我们必须保证在任何数据上的输出都是非负的且总和为1。此外,我们需要一个训练目标,来鼓励模型估计概率。在分类器输出0.5的所有样本中,我们希望这些样本有一半实际上属于预测的类。
这个属性叫做*校准*(calibration)。
......
......@@ -5,7 +5,7 @@
梯度的自动计算(自动微分)大大简化了深度学习算法的实现。在自动微分之前,即使是对复杂模型的微小调整也需要手工重新计算复杂的导数。学术论文也不得不分配大量页面来推导更新规则。我们必须继续依赖于自动微分,这样我们就可以专注于有趣的部分,但是如果你想超过对深度学习的浅薄理解,你应当知道这些梯度是如何计算出来的。
在本节中,我们将深入探讨*反向传播*(backward propagation或backpropagation)的细节。为了传达对这些技术及其实现的一些见解,我们依赖一些基本的数学和计算图。首先,我们将重点放在带权重衰减($L_2$正则化)的单隐藏层MLP上。
在本节中,我们将深入探讨*反向传播*(backward propagation或backpropagation)的细节。为了传达对这些技术及其实现的一些见解,我们依赖一些基本的数学和计算图。首先,我们将重点放在带权重衰减($L_2$正则化)的单隐藏层多层感知机上。
## 正向传播
......
......@@ -48,9 +48,9 @@ $$
## 实践中的dropout
回想一下 :numref:`fig_mlp` 中带有一个隐藏层和5个隐藏单元的MLP。当我们将dropout应用到隐藏层,以$p$的概率将隐藏单元置为零时,结果可以看作是一个只包含原始神经元子集的网络。在 :numref:`fig_dropout2` 中,删除了$h_2$和$h_5$。因此,输出的计算不再依赖于$h_2$或$h_5$,并且它们各自的梯度在执行反向传播时也会消失。这样,输出层的计算不能过度依赖于$h_1, \ldots, h_5$的任何一个元素。
回想一下 :numref:`fig_mlp` 中带有一个隐藏层和5个隐藏单元的多层感知机。当我们将dropout应用到隐藏层,以$p$的概率将隐藏单元置为零时,结果可以看作是一个只包含原始神经元子集的网络。在 :numref:`fig_dropout2` 中,删除了$h_2$和$h_5$。因此,输出的计算不再依赖于$h_2$或$h_5$,并且它们各自的梯度在执行反向传播时也会消失。这样,输出层的计算不能过度依赖于$h_1, \ldots, h_5$的任何一个元素。
![dropout前后的MLP](../img/dropout2.svg)
![dropout前后的多层感知机](../img/dropout2.svg)
:label:`fig_dropout2`
通常,我们在测试时禁用dropout。给定一个训练好的模型和一个新的样本,我们不会丢弃任何节点,因此不需要标准化。然而,也有一些例外:一些研究人员使用测试时的dropout作为估计神经网络预测的“不确定性”的启发式方法:如果预测在许多不同的dropout掩码上都是一致的,那么我们可以说网络更有自信心。
......@@ -144,7 +144,7 @@ print(dropout_layer(X, 1.))
### 定义模型参数
同样,我们使用 :numref:`sec_fashion_mnist` 中引入的Fashion-MNIST数据集。我们定义具有两个隐藏层的MLP,每个隐藏层包含256个单元。
同样,我们使用 :numref:`sec_fashion_mnist` 中引入的Fashion-MNIST数据集。我们定义具有两个隐藏层的多层感知机,每个隐藏层包含256个单元。
```{.python .input}
num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256
......@@ -257,7 +257,7 @@ net = Net(num_outputs, num_hiddens1, num_hiddens2)
### 训练和测试
这类似于前面描述的MLP训练和测试。
这类似于前面描述的多层感知机训练和测试。
```{.python .input}
num_epochs, lr, batch_size = 10, 0.5, 256
......
# 多层感知机的简洁实现
:label:`sec_mlp_concise`
正如你所期待的,我们可以通过高级API更简洁地实现MLP
正如你所期待的,我们可以通过高级API更简洁地实现多层感知机
```{.python .input}
from d2l import mxnet as d2l
......@@ -86,8 +86,8 @@ d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
## 小结
* 我们可以使用高级API更简洁地实现MLP
* 对于相同的分类问题,MLP的实现与softmax回归的实现相同,只是MLP的实现里增加了带有激活函数的隐藏层。
* 我们可以使用高级API更简洁地实现多层感知机
* 对于相同的分类问题,多层感知机的实现与softmax回归的实现相同,只是多层感知机的实现里增加了带有激活函数的隐藏层。
## 练习
......
# 多层感知机的从零开始实现
:label:`sec_mlp_scratch`
我们已经在数学上描述了多层感知机(MLP),现在让我们尝试自己实现一个多层感知机(MLP)。为了与我们之前使用softmax回归( :numref:`sec_softmax_scratch` )获得的结果进行比较,我们将继续使用Fashion-MNIST图像分类数据集( :numref:`sec_fashion_mnist`)。
我们已经在数学上描述了多层感知机(MLP),现在让我们尝试自己实现一个多层感知机。为了与我们之前使用softmax回归( :numref:`sec_softmax_scratch` )获得的结果进行比较,我们将继续使用Fashion-MNIST图像分类数据集( :numref:`sec_fashion_mnist`)。
```{.python .input}
from d2l import mxnet as d2l
......@@ -30,7 +30,7 @@ train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
## 初始化模型参数
回想一下,Fashion-MNIST中的每个图像由$28 \times 28 = 784$个灰度像素值组成。所有图像共分为10个类别。忽略像素之间的空间结构,我们可以将每个图像视为具有784个输入特征和10个类的简单分类数据集。首先,我们将实现一个具有1个隐藏层的MLP,其中包含256个隐藏单元。注意,我们可以将这两个量都视为超参数。通常,我们选择2的幂次方作为层的宽度。因为内存在硬件中的分配和寻址方式,这么做往往可以在计算上更高效。
回想一下,Fashion-MNIST中的每个图像由$28 \times 28 = 784$个灰度像素值组成。所有图像共分为10个类别。忽略像素之间的空间结构,我们可以将每个图像视为具有784个输入特征和10个类的简单分类数据集。首先,我们将实现一个具有1个隐藏层的多层感知机,其中包含256个隐藏单元。注意,我们可以将这两个量都视为超参数。通常,我们选择2的幂次方作为层的宽度。因为内存在硬件中的分配和寻址方式,这么做往往可以在计算上更高效。
我们用几个张量来表示我们的参数。注意,对于每一层我们都要记录一个权重矩阵和一个偏差向量。跟以前一样,我们要为这些参数的损失的梯度分配内存。
......@@ -146,7 +146,7 @@ def loss(y_hat, y):
## 训练
幸运的是,MLP的训练过程实现与softmax回归的训练过程实现完全相同。可以直接调用`d2l`包的`train_ch3`函数(参见 :numref:`sec_softmax_scratch` ),将迭代周期数设置为10,并将学习率设置为0.1.
幸运的是,多层感知机的训练过程实现与softmax回归的训练过程实现完全相同。可以直接调用`d2l`包的`train_ch3`函数(参见 :numref:`sec_softmax_scratch` ),将迭代周期数设置为10,并将学习率设置为0.1.
```{.python .input}
num_epochs, lr = 10, 0.1
......@@ -177,8 +177,8 @@ d2l.predict_ch3(net, test_iter)
## 小结
* 我们看到即使手动实现一个简单的MLP也是很容易的。
* 然而,如果有大量的层,从零开始实现MLP会变得很麻烦(例如,要命名和记录模型的参数)。
* 我们看到即使手动实现一个简单的多层感知机也是很容易的。
* 然而,如果有大量的层,从零开始实现多层感知机会变得很麻烦(例如,要命名和记录模型的参数)。
## 练习
......
......@@ -19,16 +19,16 @@
### 合并隐藏层
我们可以通过合并一个或多个隐藏层来克服线性模型的限制,用来处理更一般化的函数。要做到这一点,最简单的方法是将许多全连接层堆叠在一起。每一层都输出到上面的层,直到生成最后的输出。我们可以把前$L-1$层看作表示,把最后一层看作线性预测器。这种架构通常称为*多层感知机*(multilayer perceptron),通常缩写为*MLP*。下面,我们以图的方式描述了MLP( :numref:`fig_mlp`)。
我们可以通过合并一个或多个隐藏层来克服线性模型的限制,用来处理更一般化的函数。要做到这一点,最简单的方法是将许多全连接层堆叠在一起。每一层都输出到上面的层,直到生成最后的输出。我们可以把前$L-1$层看作表示,把最后一层看作线性预测器。这种架构通常称为*多层感知机*(multilayer perceptron),通常缩写为*MLP*。下面,我们以图的方式描述了多层感知机( :numref:`fig_mlp`)。
![一个单隐藏层的MLP,具有5个隐藏单元](../img/mlp.svg)
![一个单隐藏层的多层感知机,具有5个隐藏单元](../img/mlp.svg)
:label:`fig_mlp`
这个MLP有4个输入,3个输出,其隐藏层包含5个隐藏单元。输入层不涉及任何计算,因此使用此网络产生输出只需要实现隐藏层和输出层的计算;因此,这个MLP中的层数为2。注意,这两个层都是全连接的。每次输入都会影响隐藏层中的每个神经元,而隐藏层中的每个神经元又会影响输出层中的每个神经元。
这个多层感知机有4个输入,3个输出,其隐藏层包含5个隐藏单元。输入层不涉及任何计算,因此使用此网络产生输出只需要实现隐藏层和输出层的计算;因此,这个多层感知机中的层数为2。注意,这两个层都是全连接的。每次输入都会影响隐藏层中的每个神经元,而隐藏层中的每个神经元又会影响输出层中的每个神经元。
### 从线性到非线性
跟之前的章节一样,我们通过矩阵$\mathbf{X} \in \mathbb{R}^{n \times d}$来表示$n$个样本的小批量,其中每个样本具有$d$个输入(特征)。对于具有$h$个隐藏单元的单隐藏层MLP,用$\mathbf{H} \in \mathbb{R}^{n \times h}$表示隐藏层的输出,称为*隐藏表示*(hidden representations),也可以称为*隐藏层变量*(hidden-layer variable)或*隐藏变量*(hidden variable)。因为隐藏层和输出层都是全连接的,所以我们具有隐藏层权重$\mathbf{W}^{(1)} \in \mathbb{R}^{d \times h}$和隐藏层偏差$\mathbf{b}^{(1)} \in \mathbb{R}^{1 \times h}$以及输出层权重$\mathbf{W}^{(2)} \in \mathbb{R}^{h \times q}$和输出层偏差$\mathbf{b}^{(2)} \in \mathbb{R}^{1 \times q}$。形式上,我们按如下方式计算单隐藏层MLP的输出$\mathbf{O} \in \mathbb{R}^{n \times q}$:
跟之前的章节一样,我们通过矩阵$\mathbf{X} \in \mathbb{R}^{n \times d}$来表示$n$个样本的小批量,其中每个样本具有$d$个输入(特征)。对于具有$h$个隐藏单元的单隐藏层多层感知机,用$\mathbf{H} \in \mathbb{R}^{n \times h}$表示隐藏层的输出,称为*隐藏表示*(hidden representations),也可以称为*隐藏层变量*(hidden-layer variable)或*隐藏变量*(hidden variable)。因为隐藏层和输出层都是全连接的,所以我们具有隐藏层权重$\mathbf{W}^{(1)} \in \mathbb{R}^{d \times h}$和隐藏层偏差$\mathbf{b}^{(1)} \in \mathbb{R}^{1 \times h}$以及输出层权重$\mathbf{W}^{(2)} \in \mathbb{R}^{h \times q}$和输出层偏差$\mathbf{b}^{(2)} \in \mathbb{R}^{1 \times q}$。形式上,我们按如下方式计算单隐藏层多层感知机的输出$\mathbf{O} \in \mathbb{R}^{n \times q}$:
$$
\begin{aligned}
......@@ -45,7 +45,7 @@ $$
\mathbf{O} = (\mathbf{X} \mathbf{W}^{(1)} + \mathbf{b}^{(1)})\mathbf{W}^{(2)} + \mathbf{b}^{(2)} = \mathbf{X} \mathbf{W}^{(1)}\mathbf{W}^{(2)} + \mathbf{b}^{(1)} \mathbf{W}^{(2)} + \mathbf{b}^{(2)} = \mathbf{X} \mathbf{W} + \mathbf{b}.
$$
为了发挥多层结构的潜力,我们还需要一个额外的关键要素:在仿射变换之后对每个隐藏单元应用非线性的*激活函数*(activation function)$\sigma$。激活函数的输出(例如,$\sigma(\cdot)$)被称为*激活值*(activations)。一般来说,有了激活函数,就不可能再将我们的MLP退化成线性模型:
为了发挥多层结构的潜力,我们还需要一个额外的关键要素:在仿射变换之后对每个隐藏单元应用非线性的*激活函数*(activation function)$\sigma$。激活函数的输出(例如,$\sigma(\cdot)$)被称为*激活值*(activations)。一般来说,有了激活函数,就不可能再将我们的多层感知机退化成线性模型:
$$
\begin{aligned}
......@@ -57,11 +57,11 @@ $$
由于$\mathbf{X}$中的每一行对应于小批量中的一个样本,即我们定义非线性函数$\sigma$以逐行的方式应用于其输入,即,一次计算一个样本。我们在 :numref:`subsec_softmax_vectorization` 中以相同的方式使用了softmax符号来表示逐行操作。但是在本节中,我们应用于隐藏层的激活函数通常不仅仅是逐行的,而且也是逐元素。
这意味着在计算每一层的线性部分之后,我们可以计算每个激活值,而不需要查看其他隐藏单元所取的值。对于大多数激活函数都是这样。
为了构建更通用的MLP,我们可以继续堆叠这样的隐藏层,例如,$\mathbf{H}^{(1)} = \sigma_1(\mathbf{X} \mathbf{W}^{(1)} + \mathbf{b}^{(1)})$和$\mathbf{H}^{(2)} = \sigma_2(\mathbf{H}^{(1)} \mathbf{W}^{(2)} + \mathbf{b}^{(2)})$,一层叠一层,从而产生更有表达能力的模型。
为了构建更通用的多层感知机,我们可以继续堆叠这样的隐藏层,例如,$\mathbf{H}^{(1)} = \sigma_1(\mathbf{X} \mathbf{W}^{(1)} + \mathbf{b}^{(1)})$和$\mathbf{H}^{(2)} = \sigma_2(\mathbf{H}^{(1)} \mathbf{W}^{(2)} + \mathbf{b}^{(2)})$,一层叠一层,从而产生更有表达能力的模型。
### 通用近似定理
MLP可以通过隐藏神经元捕捉到我们输入之间的复杂相互作用,这些神经元依赖于每个输入的值。我们可以很容易地设计隐藏节点来执行任意计算。例如,在一对输入上进行基本逻辑操作。MLP是通用近似器。即使是网络只有一个隐藏层,给定足够的神经元(可能非常多)和正确的权重,我们可以对任意函数建模,尽管实际中学习该函数是很困难的。你可能认为神经网络有点像C语言。C语言和任何其他现代编程语言一样,能够表达任何可计算的程序。但实际上,想出一个符合规范的程序才是最困难的部分。
多层感知机可以通过隐藏神经元捕捉到我们输入之间的复杂相互作用,这些神经元依赖于每个输入的值。我们可以很容易地设计隐藏节点来执行任意计算。例如,在一对输入上进行基本逻辑操作。多层感知机是通用近似器。即使是网络只有一个隐藏层,给定足够的神经元(可能非常多)和正确的权重,我们可以对任意函数建模,尽管实际中学习该函数是很困难的。你可能认为神经网络有点像C语言。C语言和任何其他现代编程语言一样,能够表达任何可计算的程序。但实际上,想出一个符合规范的程序才是最困难的部分。
而且,虽然一个单隐层网络能学习任何函数,但并不意味着应该尝试使用单隐藏层网络来解决所有问题。事实上,通过使用更深(而不是更广)的网络,我们可以更容易地逼近许多函数。我们将在后面的章节中进行更细致的讨论。
......@@ -261,13 +261,13 @@ d2l.plot(x.numpy(), t.gradient(y, x).numpy(), 'x', 'grad of tanh',
## 小结
* MLP在输出层和输入层之间增加一个或多个全连接的隐藏层,并通过激活函数转换隐藏层的输出。
* 多层感知机在输出层和输入层之间增加一个或多个全连接的隐藏层,并通过激活函数转换隐藏层的输出。
* 常用的激活函数包括ReLU函数、sigmoid函数和tanh函数。
## 练习
1. 计算pReLU激活函数的导数。
1. 证明一个仅使用ReLU(或pReLU)的MLP构造了一个连续的分段线性函数。
1. 证明一个仅使用ReLU(或pReLU)的多层感知机构造了一个连续的分段线性函数。
1. 证明$\operatorname{tanh}(x) + 1 = 2 \operatorname{sigmoid}(2x)$。
1. 假设我们有一个非线性单元,将它一次应用于一个小批量的数据。你认为这会导致什么样的问题?
......
......@@ -100,9 +100,9 @@ print('乘以100个矩阵后\n', M.numpy())
### 打破对称性
神经网络设计中的另一个问题是其参数化所固有的对称性。假设我们有一个简单的MLP,它有一个隐藏层和两个隐藏单元。在这种情况下,我们可以对第一层的权重$\mathbf{W}^{(1)}$进行重排列,并且同样对输出层的权重进行重排列,可以获得相同的函数。第一个隐藏单元与第二个隐藏单元没有什么特别的区别。换句话说,我们在每一层的隐藏单元之间具有排列对称性。
神经网络设计中的另一个问题是其参数化所固有的对称性。假设我们有一个简单的多层感知机,它有一个隐藏层和两个隐藏单元。在这种情况下,我们可以对第一层的权重$\mathbf{W}^{(1)}$进行重排列,并且同样对输出层的权重进行重排列,可以获得相同的函数。第一个隐藏单元与第二个隐藏单元没有什么特别的区别。换句话说,我们在每一层的隐藏单元之间具有排列对称性。
这不仅仅是理论上的麻烦。考虑前述具有两个隐藏单元的单隐藏层MLP。为便于说明,假设输出层将两个隐藏单元转换为仅一个输出单元。想象一下,如果我们将隐藏层的所有参数初始化为$\mathbf{W}^{(1)} = c$,$c$为常量,会发生什么情况。在这种情况下,在正向传播期间,两个隐藏单元采用相同的输入和参数,产生相同的激活,该激活被送到输出单元。在反向传播期间,根据参数$\mathbf{W}^{(1)}$对输出单元进行微分,得到一个梯度,其元素都取相同的值。因此,在基于梯度的迭代(例如,小批量随机梯度下降)之后,$\mathbf{W}^{(1)}$的所有元素仍然采用相同的值。这样的迭代永远不会打破对称性,我们可能永远也无法实现网络的表达能力。隐藏层的行为就好像只有一个单元。请注意,虽然小批量随机梯度下降不会打破这种对称性,但dropout正则化可以。
这不仅仅是理论上的麻烦。考虑前述具有两个隐藏单元的单隐藏层多层感知机。为便于说明,假设输出层将两个隐藏单元转换为仅一个输出单元。想象一下,如果我们将隐藏层的所有参数初始化为$\mathbf{W}^{(1)} = c$,$c$为常量,会发生什么情况。在这种情况下,在正向传播期间,两个隐藏单元采用相同的输入和参数,产生相同的激活,该激活被送到输出单元。在反向传播期间,根据参数$\mathbf{W}^{(1)}$对输出单元进行微分,得到一个梯度,其元素都取相同的值。因此,在基于梯度的迭代(例如,小批量随机梯度下降)之后,$\mathbf{W}^{(1)}$的所有元素仍然采用相同的值。这样的迭代永远不会打破对称性,我们可能永远也无法实现网络的表达能力。隐藏层的行为就好像只有一个单元。请注意,虽然小批量随机梯度下降不会打破这种对称性,但dropout正则化可以。
## 参数初始化
......@@ -163,7 +163,7 @@ $$U\left(-\sqrt{\frac{6}{n_\mathrm{in} + n_\mathrm{out}}}, \sqrt{\frac{6}{n_\mat
## 练习
1. 除了MLP层的排列对称性之外,你能设计出其他神经网络可能会表现出对称性且需要被打破的情况吗?
1. 除了多层感知机的排列对称性之外,你能设计出其他神经网络可能会表现出对称性且需要被打破的情况吗?
2. 我们是否可以将线性回归或softmax回归中的所有权重参数初始化为相同的值?
3. 在相关资料中查找两个矩阵乘积特征值的解析界。这对确保梯度条件合适有什么启示?
4. 如果我们知道某些项是发散的,我们能在事后修正吗?看看关于分层自适应速率缩放的论文 :cite:`You.Gitman.Ginsburg.2017`
......
......@@ -57,7 +57,7 @@
在机器学习中,我们通常在评估几个候选模型后选择最终的模型。这个过程叫做*模型选择*。有时,需要进行比较的模型在本质上是完全不同的(比如,决策树与线性模型)。又有时,我们需要比较不同的超参数设置下的同一类模型。
例如,我们要训练MLP模型,我们可能希望比较具有不同数量的隐藏层、不同数量的隐藏单元以及不同的的激活函数组合的模型。为了确定候选模型中的最佳模型,我们通常会使用验证集。
例如,我们要训练多层感知机模型,我们可能希望比较具有不同数量的隐藏层、不同数量的隐藏单元以及不同的的激活函数组合的模型。为了确定候选模型中的最佳模型,我们通常会使用验证集。
### 验证集
......
......@@ -68,7 +68,7 @@ print(inputs)
## 转换为张量格式
现在 `inputs``outputs` 中的所有条目都是数值类型,它们可以转换为张量格式。当数据采用张量格式后,可以通过在:numref:`sec_ndarray` 中引入的那些张量函数来进一步操作。
现在 `inputs``outputs` 中的所有条目都是数值类型,它们可以转换为张量格式。当数据采用张量格式后,可以通过在 :numref:`sec_ndarray` 中引入的那些张量函数来进一步操作。
```{.python .input}
from mxnet import np
......
此差异已折叠。
此差异已折叠。
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="363pt" height="234pt" viewBox="0 0 363 234" version="1.1">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="364pt" height="234pt" viewBox="0 0 364 234" version="1.1">
<defs>
<g>
<symbol overflow="visible" id="glyph0-0">
......@@ -18,16 +18,16 @@
<path style="stroke:none;" d="M 3.78125 -1.5 L 4.609375 -1.40625 C 4.472656 -0.925781 4.226562 -0.550781 3.875 -0.28125 C 3.53125 -0.0195312 3.085938 0.109375 2.546875 0.109375 C 1.867188 0.109375 1.328125 -0.0976562 0.921875 -0.515625 C 0.523438 -0.941406 0.328125 -1.535156 0.328125 -2.296875 C 0.328125 -3.078125 0.53125 -3.679688 0.9375 -4.109375 C 1.34375 -4.546875 1.867188 -4.765625 2.515625 -4.765625 C 3.140625 -4.765625 3.644531 -4.550781 4.03125 -4.125 C 4.425781 -3.707031 4.625 -3.113281 4.625 -2.34375 C 4.625 -2.289062 4.625 -2.21875 4.625 -2.125 L 1.140625 -2.125 C 1.171875 -1.613281 1.316406 -1.222656 1.578125 -0.953125 C 1.835938 -0.679688 2.164062 -0.546875 2.5625 -0.546875 C 2.851562 -0.546875 3.097656 -0.617188 3.296875 -0.765625 C 3.503906 -0.921875 3.664062 -1.164062 3.78125 -1.5 Z M 1.1875 -2.78125 L 3.796875 -2.78125 C 3.765625 -3.175781 3.664062 -3.472656 3.5 -3.671875 C 3.25 -3.972656 2.921875 -4.125 2.515625 -4.125 C 2.148438 -4.125 1.84375 -4 1.59375 -3.75 C 1.351562 -3.507812 1.21875 -3.1875 1.1875 -2.78125 Z M 1.1875 -2.78125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-5">
<path style="stroke:none;" d="M 0.28125 -1.390625 L 1.0625 -1.515625 C 1.101562 -1.203125 1.222656 -0.960938 1.421875 -0.796875 C 1.628906 -0.628906 1.910156 -0.546875 2.265625 -0.546875 C 2.628906 -0.546875 2.898438 -0.617188 3.078125 -0.765625 C 3.253906 -0.910156 3.34375 -1.082031 3.34375 -1.28125 C 3.34375 -1.46875 3.265625 -1.609375 3.109375 -1.703125 C 2.992188 -1.773438 2.722656 -1.867188 2.296875 -1.984375 C 1.710938 -2.128906 1.304688 -2.253906 1.078125 -2.359375 C 0.859375 -2.460938 0.691406 -2.609375 0.578125 -2.796875 C 0.460938 -2.984375 0.40625 -3.191406 0.40625 -3.421875 C 0.40625 -3.628906 0.453125 -3.820312 0.546875 -4 C 0.640625 -4.175781 0.769531 -4.328125 0.9375 -4.453125 C 1.0625 -4.535156 1.226562 -4.609375 1.4375 -4.671875 C 1.65625 -4.734375 1.882812 -4.765625 2.125 -4.765625 C 2.488281 -4.765625 2.804688 -4.710938 3.078125 -4.609375 C 3.359375 -4.503906 3.566406 -4.363281 3.703125 -4.1875 C 3.835938 -4.007812 3.929688 -3.769531 3.984375 -3.46875 L 3.203125 -3.359375 C 3.171875 -3.597656 3.066406 -3.785156 2.890625 -3.921875 C 2.722656 -4.054688 2.488281 -4.125 2.1875 -4.125 C 1.820312 -4.125 1.5625 -4.0625 1.40625 -3.9375 C 1.25 -3.820312 1.171875 -3.679688 1.171875 -3.515625 C 1.171875 -3.410156 1.203125 -3.320312 1.265625 -3.25 C 1.328125 -3.15625 1.429688 -3.082031 1.578125 -3.03125 C 1.648438 -3 1.878906 -2.929688 2.265625 -2.828125 C 2.828125 -2.679688 3.21875 -2.5625 3.4375 -2.46875 C 3.664062 -2.375 3.84375 -2.234375 3.96875 -2.046875 C 4.09375 -1.867188 4.15625 -1.644531 4.15625 -1.375 C 4.15625 -1.101562 4.078125 -0.851562 3.921875 -0.625 C 3.765625 -0.394531 3.539062 -0.210938 3.25 -0.078125 C 2.96875 0.046875 2.640625 0.109375 2.265625 0.109375 C 1.660156 0.109375 1.195312 -0.015625 0.875 -0.265625 C 0.5625 -0.523438 0.363281 -0.898438 0.28125 -1.390625 Z M 0.28125 -1.390625 "/>
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph0-6">
<path style="stroke:none;" d="M 2.328125 -0.703125 L 2.4375 -0.015625 C 2.207031 0.0351562 2.007812 0.0625 1.84375 0.0625 C 1.550781 0.0625 1.328125 0.015625 1.171875 -0.078125 C 1.015625 -0.171875 0.898438 -0.289062 0.828125 -0.4375 C 0.765625 -0.582031 0.734375 -0.890625 0.734375 -1.359375 L 0.734375 -4.046875 L 0.15625 -4.046875 L 0.15625 -4.671875 L 0.734375 -4.671875 L 0.734375 -5.828125 L 1.53125 -6.296875 L 1.53125 -4.671875 L 2.328125 -4.671875 L 2.328125 -4.046875 L 1.53125 -4.046875 L 1.53125 -1.328125 C 1.53125 -1.097656 1.539062 -0.953125 1.5625 -0.890625 C 1.59375 -0.828125 1.640625 -0.773438 1.703125 -0.734375 C 1.765625 -0.691406 1.851562 -0.671875 1.96875 -0.671875 C 2.0625 -0.671875 2.179688 -0.679688 2.328125 -0.703125 Z M 2.328125 -0.703125 "/>
<path style="stroke:none;" d="M 0.28125 -1.390625 L 1.0625 -1.515625 C 1.101562 -1.203125 1.222656 -0.960938 1.421875 -0.796875 C 1.628906 -0.628906 1.910156 -0.546875 2.265625 -0.546875 C 2.628906 -0.546875 2.898438 -0.617188 3.078125 -0.765625 C 3.253906 -0.910156 3.34375 -1.082031 3.34375 -1.28125 C 3.34375 -1.46875 3.265625 -1.609375 3.109375 -1.703125 C 2.992188 -1.773438 2.722656 -1.867188 2.296875 -1.984375 C 1.710938 -2.128906 1.304688 -2.253906 1.078125 -2.359375 C 0.859375 -2.460938 0.691406 -2.609375 0.578125 -2.796875 C 0.460938 -2.984375 0.40625 -3.191406 0.40625 -3.421875 C 0.40625 -3.628906 0.453125 -3.820312 0.546875 -4 C 0.640625 -4.175781 0.769531 -4.328125 0.9375 -4.453125 C 1.0625 -4.535156 1.226562 -4.609375 1.4375 -4.671875 C 1.65625 -4.734375 1.882812 -4.765625 2.125 -4.765625 C 2.488281 -4.765625 2.804688 -4.710938 3.078125 -4.609375 C 3.359375 -4.503906 3.566406 -4.363281 3.703125 -4.1875 C 3.835938 -4.007812 3.929688 -3.769531 3.984375 -3.46875 L 3.203125 -3.359375 C 3.171875 -3.597656 3.066406 -3.785156 2.890625 -3.921875 C 2.722656 -4.054688 2.488281 -4.125 2.1875 -4.125 C 1.820312 -4.125 1.5625 -4.0625 1.40625 -3.9375 C 1.25 -3.820312 1.171875 -3.679688 1.171875 -3.515625 C 1.171875 -3.410156 1.203125 -3.320312 1.265625 -3.25 C 1.328125 -3.15625 1.429688 -3.082031 1.578125 -3.03125 C 1.648438 -3 1.878906 -2.929688 2.265625 -2.828125 C 2.828125 -2.679688 3.21875 -2.5625 3.4375 -2.46875 C 3.664062 -2.375 3.84375 -2.234375 3.96875 -2.046875 C 4.09375 -1.867188 4.15625 -1.644531 4.15625 -1.375 C 4.15625 -1.101562 4.078125 -0.851562 3.921875 -0.625 C 3.765625 -0.394531 3.539062 -0.210938 3.25 -0.078125 C 2.96875 0.046875 2.640625 0.109375 2.265625 0.109375 C 1.660156 0.109375 1.195312 -0.015625 0.875 -0.265625 C 0.5625 -0.523438 0.363281 -0.898438 0.28125 -1.390625 Z M 0.28125 -1.390625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-7">
<path style="stroke:none;" d="M 0.59375 1.78125 L 0.59375 -4.671875 L 1.3125 -4.671875 L 1.3125 -4.0625 C 1.476562 -4.300781 1.664062 -4.476562 1.875 -4.59375 C 2.09375 -4.707031 2.359375 -4.765625 2.671875 -4.765625 C 3.066406 -4.765625 3.414062 -4.660156 3.71875 -4.453125 C 4.019531 -4.253906 4.25 -3.96875 4.40625 -3.59375 C 4.5625 -3.21875 4.640625 -2.8125 4.640625 -2.375 C 4.640625 -1.894531 4.550781 -1.460938 4.375 -1.078125 C 4.207031 -0.691406 3.960938 -0.394531 3.640625 -0.1875 C 3.316406 0.0078125 2.972656 0.109375 2.609375 0.109375 C 2.347656 0.109375 2.113281 0.0507812 1.90625 -0.0625 C 1.695312 -0.175781 1.523438 -0.316406 1.390625 -0.484375 L 1.390625 1.78125 Z M 1.3125 -2.3125 C 1.3125 -1.707031 1.429688 -1.257812 1.671875 -0.96875 C 1.921875 -0.6875 2.21875 -0.546875 2.5625 -0.546875 C 2.90625 -0.546875 3.203125 -0.691406 3.453125 -0.984375 C 3.710938 -1.285156 3.84375 -1.75 3.84375 -2.375 C 3.84375 -2.96875 3.71875 -3.410156 3.46875 -3.703125 C 3.226562 -4.003906 2.9375 -4.15625 2.59375 -4.15625 C 2.257812 -4.15625 1.960938 -3.992188 1.703125 -3.671875 C 1.441406 -3.359375 1.3125 -2.90625 1.3125 -2.3125 Z M 1.3125 -2.3125 "/>
<path style="stroke:none;" d="M 2.328125 -0.703125 L 2.4375 -0.015625 C 2.207031 0.0351562 2.007812 0.0625 1.84375 0.0625 C 1.550781 0.0625 1.328125 0.015625 1.171875 -0.078125 C 1.015625 -0.171875 0.898438 -0.289062 0.828125 -0.4375 C 0.765625 -0.582031 0.734375 -0.890625 0.734375 -1.359375 L 0.734375 -4.046875 L 0.15625 -4.046875 L 0.15625 -4.671875 L 0.734375 -4.671875 L 0.734375 -5.828125 L 1.53125 -6.296875 L 1.53125 -4.671875 L 2.328125 -4.671875 L 2.328125 -4.046875 L 1.53125 -4.046875 L 1.53125 -1.328125 C 1.53125 -1.097656 1.539062 -0.953125 1.5625 -0.890625 C 1.59375 -0.828125 1.640625 -0.773438 1.703125 -0.734375 C 1.765625 -0.691406 1.851562 -0.671875 1.96875 -0.671875 C 2.0625 -0.671875 2.179688 -0.679688 2.328125 -0.703125 Z M 2.328125 -0.703125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-8">
<path style="stroke:none;" d=""/>
<path style="stroke:none;" d="M 0.59375 1.78125 L 0.59375 -4.671875 L 1.3125 -4.671875 L 1.3125 -4.0625 C 1.476562 -4.300781 1.664062 -4.476562 1.875 -4.59375 C 2.09375 -4.707031 2.359375 -4.765625 2.671875 -4.765625 C 3.066406 -4.765625 3.414062 -4.660156 3.71875 -4.453125 C 4.019531 -4.253906 4.25 -3.96875 4.40625 -3.59375 C 4.5625 -3.21875 4.640625 -2.8125 4.640625 -2.375 C 4.640625 -1.894531 4.550781 -1.460938 4.375 -1.078125 C 4.207031 -0.691406 3.960938 -0.394531 3.640625 -0.1875 C 3.316406 0.0078125 2.972656 0.109375 2.609375 0.109375 C 2.347656 0.109375 2.113281 0.0507812 1.90625 -0.0625 C 1.695312 -0.175781 1.523438 -0.316406 1.390625 -0.484375 L 1.390625 1.78125 Z M 1.3125 -2.3125 C 1.3125 -1.707031 1.429688 -1.257812 1.671875 -0.96875 C 1.921875 -0.6875 2.21875 -0.546875 2.5625 -0.546875 C 2.90625 -0.546875 3.203125 -0.691406 3.453125 -0.984375 C 3.710938 -1.285156 3.84375 -1.75 3.84375 -2.375 C 3.84375 -2.96875 3.71875 -3.410156 3.46875 -3.703125 C 3.226562 -4.003906 2.9375 -4.15625 2.59375 -4.15625 C 2.257812 -4.15625 1.960938 -3.992188 1.703125 -3.671875 C 1.441406 -3.359375 1.3125 -2.90625 1.3125 -2.3125 Z M 1.3125 -2.3125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-9">
<path style="stroke:none;" d="M 3.359375 0 L 2.5625 0 L 2.5625 -5.046875 C 2.375 -4.859375 2.125 -4.671875 1.8125 -4.484375 C 1.5 -4.304688 1.222656 -4.175781 0.984375 -4.09375 L 0.984375 -4.859375 C 1.421875 -5.054688 1.804688 -5.300781 2.140625 -5.59375 C 2.472656 -5.894531 2.707031 -6.1875 2.84375 -6.46875 L 3.359375 -6.46875 Z M 3.359375 0 "/>
......@@ -78,30 +78,33 @@
</defs>
<g id="surface1">
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="87.9087" y="13.2056"/>
<use xlink:href="#glyph0-1" x="86.6584" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-2" x="91.8217" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-2" x="93.072" y="13.2056"/>
<use xlink:href="#glyph0-3" x="93.8215" y="13.2056"/>
<use xlink:href="#glyph0-4" x="101.3185" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-3" x="95.0718" y="13.2056"/>
<use xlink:href="#glyph0-4" x="102.5688" y="13.2056"/>
<use xlink:href="#glyph0-5" x="106.3243" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-5" x="107.5746" y="13.2056"/>
<use xlink:href="#glyph0-6" x="112.0746" y="13.2056"/>
<use xlink:href="#glyph0-6" x="108.8245" y="13.2056"/>
<use xlink:href="#glyph0-7" x="113.3245" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-4" x="114.5748" y="13.2056"/>
<use xlink:href="#glyph0-4" x="115.8247" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-7" x="119.5806" y="13.2056"/>
<use xlink:href="#glyph0-8" x="120.8305" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-8" x="124.5864" y="13.2056"/>
<use xlink:href="#glyph0-5" x="125.8363" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-9" x="127.0866" y="13.2056"/>
<use xlink:href="#glyph0-9" x="128.3365" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-10" x="87.2341" y="23.5"/>
......@@ -111,9 +114,9 @@
<use xlink:href="#glyph0-2" x="108.7513" y="23.5"/>
<use xlink:href="#glyph0-13" x="110.7511" y="23.5"/>
<use xlink:href="#glyph0-11" x="115.7569" y="23.5"/>
<use xlink:href="#glyph0-6" x="120.7627" y="23.5"/>
<use xlink:href="#glyph0-7" x="120.7627" y="23.5"/>
<use xlink:href="#glyph0-4" x="123.2665" y="23.5"/>
<use xlink:href="#glyph0-5" x="128.2723" y="23.5"/>
<use xlink:href="#glyph0-6" x="128.2723" y="23.5"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="5.9995" y="140"/>
......@@ -283,30 +286,33 @@
<path style="fill:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:4,4;stroke-miterlimit:10;" d="M 425.363281 245.550781 L 464.5 234.203125 " transform="matrix(1,0,0,1,-144,-140)"/>
<path style="fill:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:4,4;stroke-miterlimit:10;" d="M 425.417969 340.257812 L 464 330.351562 " transform="matrix(1,0,0,1,-144,-140)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="194.9087" y="13.2056"/>
<use xlink:href="#glyph0-1" x="193.6584" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-2" x="200.072" y="13.2056"/>
<use xlink:href="#glyph0-2" x="198.8217" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-3" x="202.0718" y="13.2056"/>
<use xlink:href="#glyph0-4" x="209.5688" y="13.2056"/>
<use xlink:href="#glyph0-3" x="200.8215" y="13.2056"/>
<use xlink:href="#glyph0-4" x="208.3185" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-5" x="214.5746" y="13.2056"/>
<use xlink:href="#glyph0-6" x="219.0746" y="13.2056"/>
<use xlink:href="#glyph0-5" x="213.3243" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-4" x="221.5748" y="13.2056"/>
<use xlink:href="#glyph0-6" x="215.8245" y="13.2056"/>
<use xlink:href="#glyph0-7" x="220.3245" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-7" x="226.5806" y="13.2056"/>
<use xlink:href="#glyph0-4" x="222.8247" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-8" x="231.5864" y="13.2056"/>
<use xlink:href="#glyph0-8" x="227.8305" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="234.0866" y="13.2056"/>
<use xlink:href="#glyph0-5" x="232.8363" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="235.3365" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-10" x="194.2341" y="23.5"/>
......@@ -316,35 +322,38 @@
<use xlink:href="#glyph0-2" x="215.7513" y="23.5"/>
<use xlink:href="#glyph0-13" x="217.7511" y="23.5"/>
<use xlink:href="#glyph0-11" x="222.7569" y="23.5"/>
<use xlink:href="#glyph0-6" x="227.7627" y="23.5"/>
<use xlink:href="#glyph0-7" x="227.7627" y="23.5"/>
<use xlink:href="#glyph0-4" x="230.2665" y="23.5"/>
<use xlink:href="#glyph0-5" x="235.2723" y="23.5"/>
<use xlink:href="#glyph0-6" x="235.2723" y="23.5"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="311.6584" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="312.9087" y="13.2056"/>
<use xlink:href="#glyph0-2" x="316.8217" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-2" x="318.072" y="13.2056"/>
<use xlink:href="#glyph0-3" x="318.8215" y="13.2056"/>
<use xlink:href="#glyph0-4" x="326.3185" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-3" x="320.0718" y="13.2056"/>
<use xlink:href="#glyph0-4" x="327.5688" y="13.2056"/>
<use xlink:href="#glyph0-5" x="331.3243" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-5" x="332.5746" y="13.2056"/>
<use xlink:href="#glyph0-6" x="337.0746" y="13.2056"/>
<use xlink:href="#glyph0-6" x="333.8245" y="13.2056"/>
<use xlink:href="#glyph0-7" x="338.3245" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-4" x="339.5748" y="13.2056"/>
<use xlink:href="#glyph0-4" x="340.8247" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-7" x="344.5806" y="13.2056"/>
<use xlink:href="#glyph0-8" x="345.8305" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-8" x="349.5864" y="13.2056"/>
<use xlink:href="#glyph0-5" x="350.8363" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-17" x="352.0866" y="13.2056"/>
<use xlink:href="#glyph0-17" x="353.3365" y="13.2056"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-10" x="312.2341" y="23.5"/>
......@@ -354,9 +363,9 @@
<use xlink:href="#glyph0-2" x="333.7513" y="23.5"/>
<use xlink:href="#glyph0-13" x="335.7511" y="23.5"/>
<use xlink:href="#glyph0-11" x="340.7569" y="23.5"/>
<use xlink:href="#glyph0-6" x="345.7627" y="23.5"/>
<use xlink:href="#glyph0-7" x="345.7627" y="23.5"/>
<use xlink:href="#glyph0-4" x="348.2665" y="23.5"/>
<use xlink:href="#glyph0-5" x="353.2723" y="23.5"/>
<use xlink:href="#glyph0-6" x="353.2723" y="23.5"/>
</g>
</g>
</svg>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册