Skip to content

Commit

Permalink
[slides] modern cnn (d2l-ai#815)
Browse files Browse the repository at this point in the history
* modern cnn slides

* batch norm polish

* resnet polish

* polish

* polish

* polish

* polish

* channel polish
  • Loading branch information
goldmermaid authored May 12, 2021
1 parent 47c53bd commit ed448d5
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 39 deletions.
8 changes: 4 additions & 4 deletions chapter_convolutional-modern/alexnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def net():
])
```

我们构造了一个高度和宽度都为224的单通道数据,来观察每一层输出的形状。
[**我们构造一个**]高度和宽度都为224的(**单通道数据,来观察每一层输出的形状**)
它与 :numref:`fig_alexnet` 中的AlexNet架构相匹配。

```{.python .input}
Expand Down Expand Up @@ -238,8 +238,8 @@ for layer in net().layers:
## 读取数据集

尽管本文中AlexNet是在ImageNet上进行训练的,但我们在这里使用的是Fashion-MNIST数据集。因为即使在现代GPU上,训练ImageNet模型,同时使其收敛可能需要数小时或数天的时间。
将AlexNet直接应用于Fashion-MNIST的一个问题是,Fashion-MNIST的图像分辨率($28 \times 28$像素)低于ImageNet图像。
为了解决这个问题,我们将它们增加到 $224 \times 224$(通常来讲这不是一个明智的做法,但我们在这里这样做是为了有效使用AlexNet结构)。
将AlexNet直接应用于Fashion-MNIST的一个问题是,[**Fashion-MNIST图像的分辨率**]($28 \times 28$像素)(**低于ImageNet图像。**)
为了解决这个问题,(**我们将它们增加到 $224 \times 224$**)(通常来讲这不是一个明智的做法,但我们在这里这样做是为了有效使用AlexNet结构)。
我们使用 `d2l.load_data_fashion_mnist` 函数中的 `resize` 参数执行此调整。

```{.python .input}
Expand All @@ -248,7 +248,7 @@ batch_size = 128
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)
```

## 训练AlexNet
## [**训练AlexNet**]

现在,我们可以开始训练AlexNet了。与 :numref:`sec_lenet` 中的LeNet相比,这里的主要变化是使用更小的学习速率训练,这是因为网络更深更广、图像分辨率更高,训练卷积神经网络就更昂贵。

Expand Down
14 changes: 7 additions & 7 deletions chapter_convolutional-modern/batch-norm.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ $$\mathbf{h} = \phi(\mathrm{BN}(\mathbf{W}\mathbf{x} + \mathbf{b}) ).$$



## 从零实现
## (**从零实现**)

下面,我们从头开始实现一个具有张量的批量归一化层。

Expand Down Expand Up @@ -179,7 +179,7 @@ def batch_norm(X, gamma, beta, moving_mean, moving_var, eps):
return Y
```

我们现在可以创建一个正确的 `BatchNorm` 图层。
我们现在可以[**创建一个正确的 `BatchNorm` 图层**]
这个层将保持适当的参数:拉伸 `gamma` 和偏移 `beta`, 这两个参数将在训练过程中更新。
此外,我们的图层将保存均值和方差的移动平均值,以便在模型预测期间随后使用。

Expand Down Expand Up @@ -302,7 +302,7 @@ class BatchNorm(tf.keras.layers.Layer):

## 使用批量归一化层的 LeNet

为了更好理解如何应用 `BatchNorm`,下面我们将其应用于 LeNet 模型( :numref:`sec_lenet` )。
为了更好理解如何[**应用`BatchNorm`**],下面我们将其应用(**于LeNet模型**)( :numref:`sec_lenet` )。
回想一下,批量归一化是在卷积层或全连接层之后、相应的激活函数之前应用的。

```{.python .input}
Expand Down Expand Up @@ -362,7 +362,7 @@ def net():
)
```

和以前一样,我们将在 Fashion-MNIST 数据集训练我们的网络
和以前一样,我们将[**在Fashion-MNIST数据集上训练网络**]
这个代码与我们第一次训练 LeNet( :numref:`sec_lenet` )时几乎完全相同,主要区别在于学习率大得多。

```{.python .input}
Expand All @@ -379,7 +379,7 @@ train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
net = d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
```

让我们来看看从第一个批量归一化层中学到的拉伸参数 `gamma` 和偏移参数 `beta`
让我们来看看从第一个批量归一化层中学到的[**拉伸参数 `gamma` 和偏移参数 `beta`**]

```{.python .input}
net[1].gamma.data().reshape(-1,), net[1].beta.data().reshape(-1,)
Expand All @@ -395,7 +395,7 @@ net[1].gamma.reshape((-1,)), net[1].beta.reshape((-1,))
tf.reshape(net.layers[1].gamma, (-1,)), tf.reshape(net.layers[1].beta, (-1,))
```

## 简明实现
## [**简明实现**]

除了使用我们刚刚定义的 `BatchNorm` ,我们也可以直接使用深度学习框架中定义的 `BatchNorm`
该代码看起来几乎与我们上面的代码相同。
Expand Down Expand Up @@ -455,7 +455,7 @@ def net():
])
```

下面,我们使用相同的超参数来训练我们的模型
下面,我们[**使用相同超参数来训练模型**]
请注意,通常高级 API 变体运行速度快得多,因为它的代码已编译为 C++ 或 CUDA,而我们的自定义代码由 Python 实现。

```{.python .input}
Expand Down
12 changes: 6 additions & 6 deletions chapter_convolutional-modern/densenet.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ DenseNet 这个名字由变量之间的“稠密连接”而得来,最后一
前者定义如何连接输入和输出,而后者则控制通道数量,使其不会太复杂。


## 稠密块体
## (**稠密块体**)

DenseNet 使用了 ResNet 改良版的“批量归一化、激活和卷积”结构(参见 :numref:`sec_resnet` 中的练习)。
我们首先实现一下这个结构。
Expand Down Expand Up @@ -148,7 +148,7 @@ class DenseBlock(tf.keras.layers.Layer):
return x
```

在下面的例子中,我们定义一个有 2 个输出通道数为 10 的 `DenseBlock`
在下面的例子中,我们[**定义一个**] 2 个输出通道数为 10 的 (**`DenseBlock`**)
使用通道数为 3 的输入时,我们会得到通道数为 $3+2\times 10=23$ 的输出。
卷积块的通道数控制了输出通道数相对于输入通道数的增长,因此也被称为*增长率*(growth rate)。

Expand Down Expand Up @@ -176,7 +176,7 @@ Y = blk(X)
Y.shape
```

## 过渡层
## [**过渡层**]

由于每个稠密块都会带来通道数的增加,使用过多则会过于复杂化模型。
而过渡层可以用来控制模型复杂度。
Expand Down Expand Up @@ -217,7 +217,7 @@ class TransitionBlock(tf.keras.layers.Layer):
return self.avg_pool(x)
```

对上一个例子中稠密块的输出使用通道数为 10 的过渡层
对上一个例子中稠密块的输出[**使用**]通道数为 10 [**过渡层**]
此时输出的通道数减为 10,高和宽均减半。

```{.python .input}
Expand All @@ -238,7 +238,7 @@ blk = TransitionBlock(10)
blk(Y).shape
```

## DenseNet模型
## [**DenseNet模型**]

我们来构造 DenseNet 模型。DenseNet 首先使用同 ResNet 一样的单卷积层和最大池化层。

Expand Down Expand Up @@ -355,7 +355,7 @@ def net():
return net
```

## 训练模型
## [**训练模型**]

由于这里使用了比较深的网络,本节里我们将输入高和宽从 224 降到 96 来简化计算。

Expand Down
9 changes: 4 additions & 5 deletions chapter_convolutional-modern/googlenet.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ GoogLeNet吸收了NiN中串联网络的思想,并在此基础上做了改进
在本节中,我们将介绍一个稍微简化的GoogLeNet版本:我们省略了一些为稳定训练而添加的特殊特性,但是现在有了更好的训练算法,这些特性不是必要的。


## Inception块
## (**Inception块**)

在GoogLeNet中,基本的卷积块被称为*Inception块*(Inception block)。这很可能得名于电影《盗梦空间》(Inception),因为电影中的一句话“我们需要走得更深”(“We need to go deeper”)。

Expand Down Expand Up @@ -125,7 +125,7 @@ class Inception(tf.keras.Model):
同时,我们可以为不同的滤波器分配不同数量的参数。


## GoogLeNet 模型
## [**GoogLeNet模型**]

如 :numref:`fig_inception_full` 所示,GoogLeNet 一共使用 9 个Inception块和全局平均池化层的堆叠来生成其估计值。Inception块之间的最大池化层可降低维度。
第一个模块类似于 AlexNet 和 LeNet,Inception块的栈从VGG继承,全局平均池化层避免了在最后使用全连接层。
Expand Down Expand Up @@ -293,7 +293,7 @@ def net():
```

GoogLeNet 模型的计算复杂,而且不如 VGG 那样便于修改通道数。
为了在Fashion-MNIST上有一个合理的训练时间,我们将输入的高和宽从 224 降到 96,这简化了计算。下面演示各个模块输出的形状变化。
[**为了使Fashion-MNIST上的训练短小精悍,我们将输入的高和宽从224降到96**],这简化了计算。下面演示各个模块输出的形状变化。

```{.python .input}
X = np.random.uniform(size=(1, 1, 96, 96))
Expand All @@ -319,7 +319,7 @@ for layer in net().layers:
print(layer.__class__.__name__, 'output shape:\t', X.shape)
```

## 训练
## [**训练模型**]

和以前一样,我们使用 Fashion-MNIST 数据集来训练我们的模型。在训练之前,我们将图片转换为 $96 \times 96$ 分辨率。

Expand All @@ -332,7 +332,6 @@ d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

## 小结


* Inception 块相当于一个有4条路径的子网络。它通过不同窗口形状的卷积层和最大池化层来并行抽取信息,并使用 $1×1$ 卷积层减少每像素级别上的通道维数从而降低模型复杂度。
* GoogLeNet将多个设计精细的Inception块与其他层(卷积层、全连接层)串联起来。其中Inception块的通道数分配之比是在 ImageNet 数据集上通过大量的实验得来的。
* GoogLeNet 和它的后继者们一度是 ImageNet 上最有效的模型之一:它以较低的计算复杂度提供了类似的测试精度。
Expand Down
8 changes: 4 additions & 4 deletions chapter_convolutional-modern/nin.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ AlexNet 和 VGG 对 LeNet 的改进主要在于如何扩大和加深这两个模
然而,如果使用稠密层了,可能会完全放弃表征的空间结构。
*网络中的网络* (*NiN*) 提供了一个非常简单的解决方案:在每个像素的通道上分别使用多层感知机 :cite:`Lin.Chen.Yan.2013`

## NiN 块
## (**NiN块**)

回想一下,卷积层的输入和输出由四维张量组成,张量的每个轴分别对应样本、通道、高度和宽度。
另外,全连接层的输入和输出通常是分别对应于样本和特征的二维张量。
Expand Down Expand Up @@ -68,7 +68,7 @@ def nin_block(num_channels, kernel_size, strides, padding):
activation='relu')])
```

## NiN 模型
## [**NiN模型**]

最初的 NiN 网络是在 AlexNet 后不久提出的,显然从中得到了一些启示。
NiN使用窗口形状为 $11\times 11$、$5\times 5$ 和 $3\times 3$的卷积层,输出通道数量与 AlexNet 中的相同。
Expand Down Expand Up @@ -131,7 +131,7 @@ def net():
])
```

我们创建一个数据样本来查看每个块的输出形状
我们创建一个数据样本来[**查看每个块的输出形状**]

```{.python .input}
X = np.random.uniform(size=(1, 1, 224, 224))
Expand All @@ -157,7 +157,7 @@ for layer in net().layers:
print(layer.__class__.__name__,'output shape:\t', X.shape)
```

## 训练
## [**训练模型**]

和以前一样,我们使用 Fashion-MNIST 来训练模型。训练 NiN 与训练 AlexNet、VGG时相似。

Expand Down
12 changes: 6 additions & 6 deletions chapter_convolutional-modern/resnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ $$f^*_\mathcal{F} := \mathop{\mathrm{argmin}}_f L(\mathbf{X}, \mathbf{y}, f) \te
凭借它,ResNet 赢得了 2015 年 ImageNet 大规模视觉识别挑战赛。


## 残差块
## (**残差块**)

让我们聚焦于神经网络局部:如图 :numref:`fig_residual_block` 所示,假设我们的原始输入为 $x$ ,而希望学出的理想映射为 $f(\mathbf{x})$ (作为 :numref:`fig_residual_block` 上方激活函数的输入)。
:numref:`fig_residual_block` 左图虚线框中的部分需要直接拟合出该映射 $f(\mathbf{x})$ ,而右图虚线框中的部分则需要拟合出残差映射 $f(\mathbf{x}) - \mathbf{x}$ 。
Expand Down Expand Up @@ -155,7 +155,7 @@ class Residual(tf.keras.Model): #@save
![包含以及不包含 $1 \times 1$ 卷积层的残差块。](../img/resnet-block.svg)
:label:`fig_resnet_block`

下面我们来查看输入和输出形状一致的情况
下面我们来查看[**输入和输出形状一致**]的情况

```{.python .input}
blk = Residual(3)
Expand All @@ -180,7 +180,7 @@ Y = blk(X)
Y.shape
```

我们也可以在增加输出通道数的同时减半输出的高和宽
我们也可以在[**增加输出通道数的同时,减半输出的高和宽**]

```{.python .input}
blk = Residual(6, use_1x1conv=True, strides=2)
Expand All @@ -200,7 +200,7 @@ blk = Residual(6, use_1x1conv=True, strides=2)
blk(X).shape
```

## ResNet模型
## [**ResNet模型**]

ResNet 的前两层跟之前介绍的 GoogLeNet 中的一样:
在输出通道数为 64、步幅为 2 的 $7 \times 7$ 卷积层后,接步幅为 2 的 $3 \times 3$ 的最大池化层。
Expand Down Expand Up @@ -352,7 +352,7 @@ def net():
![ResNet-18 架构](../img/resnet18.svg)
:label:`fig_resnet18`

在训练 ResNet 之前,让我们观察一下 ResNet 中不同模块的输入形状是如何变化的
在训练 ResNet 之前,让我们[**观察一下ResNet中不同模块的输入形状是如何变化的**]
在之前所有架构中,分辨率降低,通道数量增加,直到全局平均池化层聚集所有特征。

```{.python .input}
Expand All @@ -379,7 +379,7 @@ for layer in net().layers:
print(layer.__class__.__name__,'output shape:\t', X.shape)
```

## 训练 ResNet
## [**训练模型**]

同之前一样,我们在 Fashion-MNIST 数据集上训练 ResNet。

Expand Down
12 changes: 6 additions & 6 deletions chapter_convolutional-modern/vgg.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

使用块的想法首先出现在牛津大学的 [视觉几何组(visualgeometry Group)](http://www.robots.ox.ac.uk/~vgg/) (VGG)的 *VGG网络* 中。通过使用循环和子程序,可以很容易地在任何现代深度学习框架的代码中实现这些重复的结构。

## VGG 块
## (**VGG块**)

经典卷积神经网络的基本组成部分是下面的这个序列:
1. 带填充以保持分辨率的卷积层;
Expand Down Expand Up @@ -73,7 +73,7 @@ def vgg_block(num_convs, num_channels):
return blk
```

## VGG 网络
## [**VGG网络**]

与 AlexNet、LeNet 一样,VGG 网络可以分为两部分:第一部分主要由卷积层和池化层组成,第二部分由全连接层组成。如 :numref:`fig_vgg` 中所示。

Expand Down Expand Up @@ -149,7 +149,7 @@ def vgg(conv_arch):
net = vgg(conv_arch)
```

接下来,我们将构建一个高度和宽度为 224 的单通道数据样本,以观察每个层输出的形状
接下来,我们将构建一个高度和宽度为 224 的单通道数据样本,[**观察每个层输出的形状**]

```{.python .input}
net.initialize()
Expand Down Expand Up @@ -177,9 +177,9 @@ for blk in net.layers:

正如你所看到的,我们在每个块的高度和宽度减半,最终高度和宽度都为7。最后再展平表示,送入全连接层处理。

## 训练
## 训练模型

由于 VGG-11 比 AlexNet 计算量更大,因此我们构建了一个通道数较少的网络,足够用于训练Fashion-MNIST数据集。
[**由于VGG-11比AlexNet计算量更大,因此我们构建了一个通道数较少的网络**],足够用于训练Fashion-MNIST数据集。

```{.python .input}
#@tab mxnet, pytorch
Expand All @@ -196,7 +196,7 @@ small_conv_arch = [(pair[0], pair[1] // ratio) for pair in conv_arch]
net = lambda: vgg(small_conv_arch)
```

除了使用略高的学习率外,模型训练过程与 :numref:`sec_alexnet` 中的 AlexNet 类似。
除了使用略高的学习率外,[**模型训练**]过程与 :numref:`sec_alexnet` 中的 AlexNet 类似。

```{.python .input}
#@tab all
Expand Down
2 changes: 1 addition & 1 deletion chapter_convolutional-neural-networks/channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def corr2d_multi_in(X, K):
return tf.reduce_sum([d2l.corr2d(x, k) for x, k in zip(X, K)], axis=0)
```

我们可以构造与 :numref:`fig_conv_multi_in` 中的值相对应的输入张量 `X` 和核张量 `K`,以[**验证互相关运算的输出**]
我们可以构造与 :numref:`fig_conv_multi_in` 中的值相对应的输入张量 `X` 和核张量 `K`,以(**验证互相关运算的输出**)

```{.python .input}
#@tab all
Expand Down

0 comments on commit ed448d5

Please sign in to comment.