提交 2bb61637 编写于 作者: X xiaotinghe 提交者: Aston Zhang

chapter_deep-learning-computation/Deferred Initialization (#594)

* chapter_deep-learning-computation/Deferred Initialization

* Deferred Initialization
上级 eec64646
# 延初始化
# 延初始化
:label:`sec_deferred_init`
到目前为止,似乎我们在建立我们的网络方面被草率地逃脱了。具体来说,我们做了以下不直观的事情,这可能看起来不应该工作
到目前为止,似乎我们在建立网络时表现得很简单。具体来说,我们忘记了做以下这些事情,似乎无法成功建立网络
* 我们在没有指定输入维度的情况下定义了网络架构
* 我们添加了图层,而不指定前一图层的输出维度。
* 我们甚至 “初始化” 这些参数,然后提供足够的信息来确定我们的模型应该包含多少个参数。
* 我们定义了网络架构,但没有指定输入维度
* 我们添加层时没有指定前一层的输出维度。
* 我们在初始化参数时,甚至没有足够的信息来确定模型应该包含多少参数。
您可能会惊讶我们的代码运行。毕竟,深度学习框架无法判断网络的输入维度。这里的诀窍是框架 * 推迟初始化 *,等到我们第一次通过模型传递数据,以便动态推断每个层的大小。
你可能会对我们的代码能运行感到惊讶。毕竟,深度学习框架无法判断网络的输入维度是什么。这里的诀窍是框架的*延后初始化*(defers initialization),即等到我们第一次将数据通过模型传递时,才会动态地推断出每个层的大小。
后来,当使用卷积神经网络时,这种技术将变得更加方便,因为输入维度(即图像的分辨率)将影响每个后续图层的维度。因此,无需在编写代码时知道维度是什么的情况下设置参数的能力可以极大地简化指定和随后修改我们的模型的任务。接下来,我们深入了解初始化的机制。
在以后,当使用卷积神经网络时,由于输入维度(即图像的分辨率)将影响每个后续层的维数,因此该技术将变得更加方便。现在我们在编写代码时无需知道维度是什么就可以设置参数,这种能力可以大大简化定义和修改模型的任务。接下来,我们将更深入地研究初始化机制。
## 实例化网络
首先,让我们实例化 MLP。
首先,让我们实例化一个MLP。
```{.python .input}
from mxnet import init, np, npx
......@@ -39,7 +39,7 @@ net = tf.keras.models.Sequential([
])
```
此时,网络不可能知道输入图层权重的尺寸,因为输入维度仍未知。因此,框架尚未初始化任何参数。我们通过尝试访问以下参数来确认。
此时,因为输入维数是未知的,所以网络不可能知道输入层权重的维数。因此,框架尚未初始化任何参数。我们通过尝试访问以下参数进行确认。
```{.python .input}
print(net.collect_params)
......@@ -52,11 +52,11 @@ print(net.collect_params())
```
:begin_tab:`mxnet`
请注意,当参数对象存在时,每个图层的输入维度将列为-1。MxNet 使用特殊值-1 表示参数维度仍未知。此时,尝试访问 `net[0].weight.data()` 将触发运行时错误,指出必须先初始化网络才能访问参数。现在让我们看看当我们尝试通过 `initialize` 函数初始化参数时会发生什么。
注意,当参数对象存在时,每个层的输入维度为-1。MXNet使用特殊值-1表示参数维度仍然未知。此时,尝试访问`net[0].weight.data()`将触发运行时错误,提示必须先初始化网络,然后才能访问参数。现在让我们看看当我们试图通过`initialize`函数初始化参数时会发生什么。
:end_tab:
:begin_tab:`tensorflow`
请注意,每个图层对象都存在,但权重为空。使用 `net.get_weights()` 会抛出错误,因为权重尚未初始化。
请注意,每个层对象都存在,但权重为空。使用`net.get_weights()`将抛出一个错误,因为权重尚未初始化。
:end_tab:
```{.python .input}
......@@ -65,10 +65,10 @@ net.collect_params()
```
:begin_tab:`mxnet`
正如我们所看到的,什么都没有改变。当输入维度未知时,初始化调用不会真正初始化参数。相反,这个调用注册到 MxNet,我们希望(也可以根据哪个分布)初始化参数
如我们所见,一切都没有改变。当输入维度未知时,调用`initialize`不会真正初始化参数。而是会在MXNet内部声明希望初始化参数,并且可以选择初始化分布
:end_tab:
接下来让我们通过网络传递数据,使框架最终初始化参数。
接下来让我们将数据通过网络,最终使框架初始化参数。
```{.python .input}
X = np.random.uniform(size=(2, 20))
......@@ -84,18 +84,18 @@ net(X)
[w.shape for w in net.get_weights()]
```
只要我们知道输入维度 20,框架就可以通过插入值 20 来识别第一层权重矩阵的形状。在识别第一层的形状之后,框架将继续进入第二层,依此类推通过计算图形,直到所有形状都已知。请注意,在这种情况下,只有第一层需要延迟初始化,但框架按顺序初始化。一旦所有参数形状都知道,框架最终可以初始化参数。
一旦我们知道输入维数是20,框架可以通过代入值20来识别第一层权重矩阵的形状。识别出第一层的形状后,框架处理第二层,依此类推,直到所有形状都已知为止。注意,在这种情况下,只有第一层需要延迟初始化,但是框架仍是按顺序初始化的。等到知道了所有的参数形状,框架就可以初始化参数。
## 摘要
## 小结
*迟初始化可以很方便,允许框架自动推断参数形状,使得修改体系结构并消除一个常见的错误来源
*后初始化可以很方便地通过框架自动推断参数形状,使修改模型结构变得容易,避免了一类常见的错误
* 我们可以通过模型传递数据,使框架最终初始化参数。
## 练习
1. 如果您将输入维度指定给第一个图层而不是后续图层,会发生什么情况?您是否立即进行初始化?
1. 如果指定不匹配的维度,会发生什么情况
1. 如果你有不同维度的输入,你需要做什么?提示:看看参数绑定
1. 如果您指定了第一层的输入尺寸,但没有指定后续层的尺寸,会发生什么?是否立即进行初始化?
1. 如果指定了不匹配的维度会发生什么
1. 如果输入具有不同的维度,你需要做什么?提示:查看参数绑定的相关内容
:begin_tab:`mxnet`
[Discussions](https://discuss.d2l.ai/t/280)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册