Skip to content

Commit

Permalink
cnn polish (#1066)
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaotinghe authored Dec 31, 2021
1 parent 472d12a commit ec6e7ae
Show file tree
Hide file tree
Showing 20 changed files with 91 additions and 90 deletions.
2 changes: 1 addition & 1 deletion chapter_computer-vision/fine-tuning.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
然而,我们平常接触到的数据集的规模通常在这两者之间。

假如我们想识别图片中不同类型的椅子,然后向用户推荐购买链接。
一种可能的方法是首先识别100把普通椅子,为每把椅子拍摄1000张不同角度的图像,然后在收集的影像数据集上训练一个分类模型
一种可能的方法是首先识别100把普通椅子,为每把椅子拍摄1000张不同角度的图像,然后在收集的图像数据集上训练一个分类模型
尽管这个椅子数据集可能大于Fashion-MNIST数据集,但实例数量仍然不到ImageNet中的十分之一。
适合ImageNet的复杂模型可能会在这个椅子数据集上过拟合。
此外,由于训练样本数量有限,训练模型的准确性可能无法满足实际要求。
Expand Down
2 changes: 1 addition & 1 deletion chapter_computer-vision/image-augmentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ train_with_data_aug(train_augs, test_augs, net)

## 练习

1. 在不使用图像增广的情况下训练模型:`train_with_data_aug(no_aug, no_aug)`比较使用与不使用图像增广的训练结果和测试精度。这个对比实验能支持图像增广可以减轻过拟合的论点吗?为什么?
1. 在不使用图像增广的情况下训练模型:`train_with_data_aug(no_aug, no_aug)`比较使用和不使用图像增广的训练结果和测试精度。这个对比实验能支持图像增广可以减轻过拟合的论点吗?为什么?
2. 在基于CIFAR-10数据集的模型训练中结合多种不同的图像增广方法。它能提高测试准确性吗?
3. 参阅深度学习框架的在线文档。它还提供了哪些其他的图像增广方法?

Expand Down
6 changes: 3 additions & 3 deletions chapter_computer-vision/ssd.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ forward(torch.zeros((2, 3, 256, 256)), base_net()).shape

### 完整的模型

[**完整的单发多框检测模型由五个模块组成**]每个块生成的特征图既用于(i)生成锚框,又用于(ii)预测这些锚框的类别和偏移量。在这五个模块中,第一个是基本网络块,第二个到第四个是高和宽减半块,最后一个模块使用全局最大池将高度和宽度都降到1。从技术上讲,第二到第五个区块都是 :numref:`fig_ssd`中的多尺度特征块。
[**完整的单发多框检测模型由五个模块组成**]每个块生成的特征图既用于生成锚框,又用于预测这些锚框的类别和偏移量。在这五个模块中,第一个是基本网络块,第二个到第四个是高和宽减半块,最后一个模块使用全局最大池将高度和宽度都降到1。从技术上讲,第二到第五个区块都是 :numref:`fig_ssd`中的多尺度特征块。

```{.python .input}
def get_blk(i):
Expand All @@ -246,7 +246,7 @@ def get_blk(i):
return blk
```

现在我们[**为每个块定义前向传播**]。与图像分类任务不同,此处的输出包括:(i)CNN特征图`Y`,(ii)在当前尺度下根据`Y`生成的锚框,以及(iii)预测的这些锚框的类别和偏移量(基于`Y`)。
现在我们[**为每个块定义前向传播**]。与图像分类任务不同,此处的输出包括:CNN特征图`Y`在当前尺度下根据`Y`生成的锚框预测的这些锚框的类别和偏移量(基于`Y`)。

```{.python .input}
def blk_forward(X, blk, size, ratio, cls_predictor, bbox_predictor):
Expand Down Expand Up @@ -401,7 +401,7 @@ trainer = torch.optim.SGD(net.parameters(), lr=0.2, weight_decay=5e-4)
### [**定义损失函数和评价函数**]

目标检测有两种类型的损失。
第一种有关锚框类别的损失:我们可以简单地重用之前图像分类问题里一直使用的交叉熵损失函数来计算
第一种有关锚框类别的损失:我们可以简单地复用之前图像分类问题里一直使用的交叉熵损失函数来计算
第二种有关正类锚框偏移量的损失:预测偏移量是一个回归问题。
但是,对于这个回归问题,我们在这里不使用 :numref:`subsec_normal_distribution_and_squared_loss`中描述的平方损失,而是使用$L_1$范数损失,即预测值和真实值之差的绝对值。
掩码变量`bbox_masks`令负类锚框和填充锚框不参与损失的计算。
Expand Down
4 changes: 2 additions & 2 deletions chapter_convolutional-modern/alexnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,10 @@ AlexNet由八层组成:五个卷积层、两个全连接隐藏层和一个全

### 容量控制和预处理

AlexNet通过dropout( :numref:`sec_dropout`)控制全连接层的模型复杂度,而LeNet只使用了权重衰减。
AlexNet通过暂退法( :numref:`sec_dropout`)控制全连接层的模型复杂度,而LeNet只使用了权重衰减。
为了进一步扩充数据,AlexNet在训练时增加了大量的图像增强数据,如翻转、裁切和变色。
这使得模型更健壮,更大的样本量有效地减少了过拟合。
我们将在 :numref:`sec_image_augmentation`中更详细地讨论数据扩充
我们将在 :numref:`sec_image_augmentation`中更详细地讨论数据扩增

```{.python .input}
from d2l import mxnet as d2l
Expand Down
36 changes: 18 additions & 18 deletions chapter_convolutional-modern/batch-norm.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@
$$\mathrm{BN}(\mathbf{x}) = \boldsymbol{\gamma} \odot \frac{\mathbf{x} - \hat{\boldsymbol{\mu}}_\mathcal{B}}{\hat{\boldsymbol{\sigma}}_\mathcal{B}} + \boldsymbol{\beta}.$$
:eqlabel:`eq_batchnorm`

在 :eqref:`eq_batchnorm`中,$\hat{\boldsymbol{\mu}}_\mathcal{B}$是样本均值,$\hat{\boldsymbol{\sigma}}_\mathcal{B}$是小批量$\mathcal{B}$的样本标准差。
在 :eqref:`eq_batchnorm`中,$\hat{\boldsymbol{\mu}}_\mathcal{B}$是小批量$\mathcal{B}$的样本均值,$\hat{\boldsymbol{\sigma}}_\mathcal{B}$是小批量$\mathcal{B}$的样本标准差。
应用标准化后,生成的小批量的平均值为0和单位方差为1。
由于单位方差(与其他一些魔法数)是一个任意的选择,因此我们通常包含
由于单位方差(与其他一些魔法数)是一个主观的选择,因此我们通常包含
*拉伸参数*(scale)$\boldsymbol{\gamma}$和*偏移参数*(shift)$\boldsymbol{\beta}$,它们的形状与$\mathbf{x}$相同。
请注意,$\boldsymbol{\gamma}$和$\boldsymbol{\beta}$是需要与其他模型参数一起学习的参数。

Expand All @@ -48,23 +48,23 @@ $$\mathrm{BN}(\mathbf{x}) = \boldsymbol{\gamma} \odot \frac{\mathbf{x} - \hat{\b
$$\begin{aligned} \hat{\boldsymbol{\mu}}_\mathcal{B} &= \frac{1}{|\mathcal{B}|} \sum_{\mathbf{x} \in \mathcal{B}} \mathbf{x},\\
\hat{\boldsymbol{\sigma}}_\mathcal{B}^2 &= \frac{1}{|\mathcal{B}|} \sum_{\mathbf{x} \in \mathcal{B}} (\mathbf{x} - \hat{\boldsymbol{\mu}}_{\mathcal{B}})^2 + \epsilon.\end{aligned}$$

请注意,我们在方差估计值中添加一个小常量$\epsilon > 0$,以确保我们永远不会尝试除以零,即使在经验方差估计值可能消失的情况下也是如此。估计值$\hat{\boldsymbol{\mu}}_\mathcal{B}$和${\hat{\boldsymbol{\sigma}}_\mathcal{B}}$通过使用平均值和方差的噪声(noise)估计来抵消缩放问题。
请注意,我们在方差估计值中添加一个小的常量$\epsilon > 0$,以确保我们永远不会尝试除以零,即使在经验方差估计值可能消失的情况下也是如此。估计值$\hat{\boldsymbol{\mu}}_\mathcal{B}$和${\hat{\boldsymbol{\sigma}}_\mathcal{B}}$通过使用平均值和方差的噪声(noise)估计来抵消缩放问题。
你可能会认为这种噪声是一个问题,而事实上它是有益的。

事实证明,这是深度学习中一个反复出现的主题。
由于理论上尚未明确表述的原因,优化中的各种噪声源通常会导致更快的训练和较少的过拟合:这种变化似乎是正则化的一种形式。
由于尚未在理论上明确的原因,优化中的各种噪声源通常会导致更快的训练和较少的过拟合:这种变化似乎是正则化的一种形式。
在一些初步研究中, :cite:`Teye.Azizpour.Smith.2018`和 :cite:`Luo.Wang.Shao.ea.2018`分别将批量规范化的性质与贝叶斯先验相关联。
这些理论揭示了为什么批量规范化最适应$50 \sim 100$范围中的中等小批量尺寸的难题
这些理论揭示了为什么批量规范化最适应$50 \sim 100$范围中的中等批量大小的难题

另外,批量规范化图层在”训练模式“(通过小批量统计数据规范化)和“预测模式”(通过数据集统计规范化)中的功能不同。
另外,批量规范化层在”训练模式“(通过小批量统计数据规范化)和“预测模式”(通过数据集统计规范化)中的功能不同。
在训练过程中,我们无法得知使用整个数据集来估计平均值和方差,所以只能根据每个小批次的平均值和方差不断训练模型。
而在预测模式下,可以根据整个数据集精确计算批量规范化所需的平均值和方差。

现在,我们了解一下批量规范化在实践中是如何工作的。

## 批量规范化层

回想一下,批量规范化和其他图层之间的一个关键区别是,由于批量规范化在完整的小批次上运行,因此我们不能像以前在引入其他图层时那样忽略批处理的尺寸大小
回想一下,批量规范化和其他层之间的一个关键区别是,由于批量规范化在完整的小批量上运行,因此我们不能像以前在引入其他层时那样忽略批量大小
我们在下面讨论这两种情况:全连接层和卷积层,他们的批量规范化实现略有不同。

### 全连接层
Expand All @@ -81,7 +81,7 @@ $$\mathbf{h} = \phi(\mathrm{BN}(\mathbf{W}\mathbf{x} + \mathbf{b}) ).$$

同样,对于卷积层,我们可以在卷积层之后和非线性激活函数之前应用批量规范化。
当卷积有多个输出通道时,我们需要对这些通道的“每个”输出执行批量规范化,每个通道都有自己的拉伸(scale)和偏移(shift)参数,这两个参数都是标量。
假设我们的微批次包含$m$个示例,并且对于每个通道,卷积的输出具有高度$p$和宽度$q$。
假设我们的小批量包含$m$个样本,并且对于每个通道,卷积的输出具有高度$p$和宽度$q$。
那么对于卷积层,我们在每个输出通道的$m \cdot p \cdot q$个元素上同时执行每个批量规范化。
因此,在计算平均值和方差时,我们会收集所有空间位置的值,然后在给定通道内应用相同的均值和方差,以便在每个空间位置对值进行规范化。

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

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

撇开算法细节,注意我们实现图层的基础设计模式
撇开算法细节,注意我们实现层的基础设计模式
通常情况下,我们用一个单独的函数定义其数学原理,比如说`batch_norm`
然后,我们将此功能集成到一个自定义层中,其代码主要处理簿记问题,例如将数据移动到训练设备(如GPU)、分配和初始化任何必需的变量、跟踪移动平均线(此处为均值和方差)
然后,我们将此功能集成到一个自定义层中,其代码主要处理数据移动到训练设备(如GPU)、分配和初始化任何必需的变量、跟踪移动平均线(此处为均值和方差)等问题
为了方便起见,我们并不担心在这里自动推断输入形状,因此我们需要指定整个特征的数量。
不用担心,深度学习框架中的批量规范化API将为我们解决上述问题,我们稍后将展示这一点。

Expand Down Expand Up @@ -467,8 +467,8 @@ d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
在提出批量规范化的论文中,作者除了介绍了其应用,还解释了其原理:通过减少*内部协变量偏移*(internal covariate shift)。
据推测,作者所说的“内部协变量转移”类似于上述的投机直觉,即变量值的分布在训练过程中会发生变化。
然而,这种解释有两个问题:
i)这种偏移与严格定义的*协变量偏移*(covariate shift)非常不同,所以这个名字用词不当。
ii)这种解释只提供了一种不明确的直觉,但留下了一个有待后续挖掘的问题:为什么这项技术如此有效?
1、这种偏移与严格定义的*协变量偏移*(covariate shift)非常不同,所以这个名字用词不当。
2、这种解释只提供了一种不明确的直觉,但留下了一个有待后续挖掘的问题:为什么这项技术如此有效?
本书旨在传达实践者用来发展深层神经网络的直觉。
然而,重要的是将这些指导性直觉与既定的科学事实区分开来。
最终,当你掌握了这些方法,并开始撰写自己的研究论文时,你会希望清楚地区分技术和直觉。
Expand All @@ -478,8 +478,8 @@ Ali Rahimi在接受2017年NeurIPS大会的“接受时间考验奖”(Test of
他对该示例进行了详细回顾 :cite:`Lipton.Steinhardt.2018`,概述了机器学习中令人不安的趋势。
此外,一些作者对批量规范化的成功提出了另一种解释:在某些方面,批量规范化的表现出与原始论文 :cite:`Santurkar.Tsipras.Ilyas.ea.2018`中声称的行为是相反的。

然而,与技术机器学习文献中成千上万类似模糊的声明相比,内部协变量偏移没有什么更值得批评
很可能,它作为这些辩论的焦点而产生共鸣,要归功于它对目标受众的广泛认可
然而,与机器学习文献中成千上万类似模糊的说法相比,内部协变量偏移没有更值得批评
很可能,它作为这些辩论的焦点而产生共鸣,要归功于目标受众对它的广泛认可
批量规范化已经被证明是一种不可或缺的方法。它适用于几乎所有图像分类器,并在学术界获得了数万引用。

## 小结
Expand All @@ -496,10 +496,10 @@ Ali Rahimi在接受2017年NeurIPS大会的“接受时间考验奖”(Test of
1. 绘制训练和测试准确度的提高。
1. 你的学习率有多高?
1. 我们是否需要在每个层中进行批量规范化?尝试一下?
1. 你可以通过批量规范化来替换暂退法吗?行为如何改变
1. 你可以通过批量规范化来替换暂退法吗?行为会如何改变
1. 确定参数`beta``gamma`,并观察和分析结果。
1. 查看高级API中有关`BatchNorm`的在线文档,以查看其他批量规范化的应用。
1. 研究思路:想想你可以应用的其他“规范化”转换?你可以应用概率积分变换吗?全秩协方差估计如何
1. 研究思路:想想你可以应用的其他“规范化”转换?你可以应用概率积分变换吗?全秩协方差估计可以么

:begin_tab:`mxnet`
[Discussions](https://discuss.d2l.ai/t/1876)
Expand Down
4 changes: 2 additions & 2 deletions chapter_convolutional-modern/googlenet.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ GoogLeNet吸收了NiN中串联网络的思想,并在此基础上做了改进
这篇论文的一个重点是解决了什么样大小的卷积核最合适的问题。
毕竟,以前流行的网络使用小到$1 \times 1$,大到$11 \times 11$的卷积核。
本文的一个观点是,有时使用不同大小的卷积核组合是有利的。
在本节中,我们将介绍一个稍微简化的GoogLeNet版本:我们省略了一些为稳定训练而添加的特殊特性,但是现在有了更好的训练算法,这些特性不是必要的。
在本节中,我们将介绍一个稍微简化的GoogLeNet版本:我们省略了一些为稳定训练而添加的特殊特性,现在有了更好的训练方法,这些特性不是必要的。

## (**Inception块**)

Expand Down Expand Up @@ -338,7 +338,7 @@ d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
## 练习

1. GoogLeNet有一些后续版本。尝试实现并运行它们,然后观察实验结果。这些后续版本包括:
* 添加批量规范化层 :cite:`Ioffe.Szegedy.2015`(batch normalization),在 :numref:`sec_batch_norm`中将介绍
* 添加批量规范化层 :cite:`Ioffe.Szegedy.2015`(batch normalization),在 :numref:`sec_batch_norm`中将介绍。
* 对Inception模块进行调整 :cite:`Szegedy.Vanhoucke.Ioffe.ea.2016`
* 使用标签平滑(label smoothing)进行模型正则化 :cite:`Szegedy.Vanhoucke.Ioffe.ea.2016`
* 加入残差连接 :cite:`Szegedy.Ioffe.Vanhoucke.ea.2017`。( :numref:`sec_resnet`将介绍)。
Expand Down
2 changes: 1 addition & 1 deletion chapter_convolutional-modern/nin.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ NiN使用窗口形状为$11\times 11$、$5\times 5$和$3\times 3$的卷积层,
每个NiN块后有一个最大汇聚层,汇聚窗口形状为$3\times 3$,步幅为2。

NiN和AlexNet之间的一个显著区别是NiN完全取消了全连接层。
相反,NiN使用一个NiN块,其输出通道数等于标签类别的数量。最后放一个*全局平均汇聚层*(global average pooling layer),生成一个多元逻辑向量(logits)。NiN设计的一个优点是,它显著减少了模型所需参数的数量。然而,在实践中,这种设计有时会增加训练模型的时间。
相反,NiN使用一个NiN块,其输出通道数等于标签类别的数量。最后放一个*全局平均汇聚层*(global average pooling layer),生成一个对数几率 (logits)。NiN设计的一个优点是,它显著减少了模型所需参数的数量。然而,在实践中,这种设计有时会增加训练模型的时间。

```{.python .input}
net = nn.Sequential()
Expand Down
6 changes: 3 additions & 3 deletions chapter_convolutional-modern/resnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ class Residual(tf.keras.Model): #@save
return tf.keras.activations.relu(Y)
```

如图 :numref:`fig_resnet_block`所示,此代码生成两种类型的网络:
一种是在`use_1x1conv=False`应用ReLU非线性函数之前,将输入添加到输出。
另一种是在`use_1x1conv=True`时,添加通过$1 \times 1$卷积调整通道和分辨率。
:numref:`fig_resnet_block`所示,此代码生成两种类型的网络:
一种是当`use_1x1conv=False`时,应用ReLU非线性函数之前,将输入添加到输出。
另一种是当`use_1x1conv=True`时,添加通过$1 \times 1$卷积调整通道和分辨率。

![包含以及不包含 $1 \times 1$ 卷积层的残差块。](../img/resnet-block.svg)
:label:`fig_resnet_block`
Expand Down
Loading

0 comments on commit ec6e7ae

Please sign in to comment.