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

ch7

上级 68697cb9
......@@ -31,15 +31,15 @@
:width:`400px`
:label:`fig_filters`
AlexNet的更高层建立在这些表示的基础上,以表示更大的特征,如眼睛、鼻子、草叶等等。而更高的层可以检测整个物体,如人、飞机、狗或飞盘。最终的隐藏神经元可以学习图像的综合表示,从而使属于不同类别的数据易于区分。尽管一直有一群执着的研究者不断钻研,试图学习视觉数据的逐级表征,然而很长一段时间里这些尝试都未有突破。深度卷积神经网络的巨大突破出现在2012年,该突破可归因于两个关键因素。
AlexNet的更高层建立在这些表示的基础上,以表示更大的特征,如眼睛、鼻子、草叶等等。而更高的层可以检测整个物体,如人、飞机、狗或飞盘。最终的隐藏神经元可以学习图像的综合表示,从而使属于不同类别的数据易于区分。尽管一直有一群执着的研究者不断钻研,试图学习视觉数据的逐级表征,然而很长一段时间里这些尝试都未有突破。深度卷积神经网络的突破出现在2012年,可归因于两个关键因素。
### 缺少的分:数据
### 缺少的分:数据
包含许多特征的深度模型需要大量的有标签数据,才能显著优于基于凸优化的传统方法(如线性方法和核方法)。
然而,限于早期计算机有限的存储和90年代有限的研究预算,大部分研究只基于小的公开数据集。例如,不少研究论文基于加州大学欧文分校(UCI)提供的若干个公开数据集,其中许多数据集只有几百至几千张在非自然环境下以低分辨率拍摄的图像。这一状况在2010年前后兴起的大数据浪潮中得到改善。2009年,ImageNet数据集发布,并发起ImageNet挑战赛:要求研究人员从100万个样本中训练模型,以区分1000个不同类别的对象。ImageNet数据集由斯坦福教授李飞飞(Fei-Fei-Li)小组的研究人员开发,利用谷歌图像搜索(Google Image Search)对每一类图像进行预筛选,并利用亚马逊众包(Amazon-Mechanical-Turk)来标注每张图片的相关类别。这种规模是前所未有的。这项被称为ImageNet的挑战赛推动了计算机视觉和机器学习研究的发展,同时推动计算机视觉和机器学习的研究进入新的阶段,而此前的传统方法不再有优势。
### 缺少的分:硬件
### 缺少的分:硬件
深度学习对计算资源要求很高,训练可能需要数百个迭代周期,每次迭代都需要通过代价高昂的许多线性代数层传递数据。这也是为什么在20世纪90年代至21世纪初,优化凸目标的简单算法是研究人员的首选。然而,用GPU训练神经网络改变了这一格局。*图形处理器* (Graphics Processing Unit,GPU)早年用来加速图形处理,使电脑游戏玩家受益。GPU可优化高吞吐量的 $4 \times 4$ 矩阵和向量乘法,从而服务于基本的图形任务。幸运的是,这些数学运算与计算卷积层惊人地相似。由此,英伟达(NVIDIA)和ATI会把它们作为 *通用GPU* 来销售。
......@@ -243,7 +243,7 @@ for layer in net().layers:
## 读取数据集
尽管本文中AlexNet是在ImageNet上进行训练的,但我们在这里使用的是Fashion-MNIST数据集,因为即使在现代GPU上,训练ImageNet模型其收敛可能需要数小时或数天的时间。
尽管本文中AlexNet是在ImageNet上进行训练的,但我们在这里使用的是Fashion-MNIST数据集,因为即使在现代GPU上,训练ImageNet模型以使其收敛可能需要数小时或数天的时间。
将AlexNet直接应用于Fashion MNIST的一个问题是,它的图像分辨率($28 \times 28$像素)低于ImageNet图像。
为了解决这个问题,我们将它们增加到 $224 \times 224$(通常来讲这不是一个明智的做法,但我们在这里这样做是为了有效使用AlexNet架构)。
我们使用 `d2l.load_data_fashion_mnist` 函数中的 `resize` 参数执行此调整。
......@@ -268,7 +268,7 @@ d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr)
* AlexNet的结构与LeNet相似,但使用了更多的卷积层和更多的参数来拟合大规模的ImageNet数据集。
* 今天,AlexNet已经被更有效的体系结构所超越,但它是从浅层网络到深层网络的关键一步。
* 尽管AlexNet的代码只比LeNet多出几行,但学术界花了很多年才拥抱深度学习这一概念上的变化,并利用其出色的实验结果。这个漫长过程的出现也是由于缺乏有效的计算工具。
* 尽管AlexNet的代码只比LeNet多出几行,但学术界花了很多年才接受深度学习这一概念,并应用其出色的实验结果。这也是由于缺乏有效的计算工具。
* Dropout、ReLU和预处理是提升计算机视觉任务性能的其他关键步骤。
## 练习
......
# 批量归一化
:label:`sec_batch_norm`
训练深层神经网络是十分困难的,特别是在较短的时间内使他们收敛是更加棘手的事情
训练深层神经网络是十分困难的,特别是在较短的时间内使他们收敛更加棘手
在本节中,我们将介绍 *批量归一化*(batch normalization) :cite:`Ioffe.Szegedy.2015` ,这是一种流行且有效的技术,可持续加速深层网络的收敛速度。
再结合在 :numref:`sec_resnet` 中将介绍的残差块,批量归一化使得研究人员能够训练 100 多层的网络。
......@@ -16,7 +16,7 @@
第二,对于典型的多层感知机或卷积神经网络。当我们训练时,中间层中的变量(例如,多层感知机中的仿射变换输出)可能具有更广的变化范围:不论是沿着从输入到输出的层,跨同一层中的单元,或是随着时间的推移,模型参数的随着训练更新变幻莫测。
批量归一化的发明者非正式地假设,这些变量分布中的这种偏移可能会阻碍网络的收敛。
直观地说,我们可能会猜想,如果一个层的变量值是另一层的 100 倍,这可能需要对学习率进行补偿调整。
直观地说,我们可能会猜想,如果一个层的可变值是另一层的 100 倍,这可能需要对学习率进行补偿调整。
第三,更深层的网络很复杂,容易过拟合。
这意味着正则化变得更加重要。
......@@ -25,9 +25,9 @@
接下来,我们应用比例系数和比例偏移。
正是由于这个基于*批量*统计的*标准化*,才有了*批量归一化*的名称。。
请注意,如果我们尝试使用大小为 1 的小批量大小来进行批量归一化,我们将无法学到任何东西。
这是因为在减去均值之后,每个隐藏单元的值将为 0。
所以,只有使用足够大的小批量大小,批量归一化这种方法才是有效且稳定的。
请注意,如果我们尝试使用大小为 1 的小批量应用批量归一化,我们将无法学到任何东西。
这是因为在减去均值之后,每个隐藏单元将为 0。
所以,只有使用足够大的小批量,批量归一化这种方法才是有效且稳定的。
请注意,在应用批量归一化时,批量大小的选择可能比没有批量归一化时更重要。
从形式上来说,用 $\mathbf{x} \in \mathcal{B}$ 表示一个来自小批量 $\mathcal{B}$ 的输入,批量归一化$\mathrm{BN}$ 根据以下表达式转换 $\mathbf{x}$:
......
......@@ -2,25 +2,25 @@
:label:`sec_googlenet`
在2014年的ImageNet图像识别挑战赛中,一个名叫GoogLeNet :cite:`Szegedy.Liu.Jia.ea.2015` 的网络结构大放异彩。
GoogLeNet吸收了NiN中串联网络的思想,并在此基础上做了很大改进。
这篇论文的一个重点是解决了“什么样大小的卷积核最合适”的问题。
毕竟,以前流行的网络使用小到 $1 \times 1$ 大到 $11 \times 11$ 的卷积核。
GoogLeNet吸收了NiN中网络串联网络的思想,并在此基础上做了很大改进。
这篇论文的一个重点是解决了什么样大小的卷积核最合适的问题。
毕竟,以前流行的网络使用小到 $1 \times 1$ 大到 $11 \times 11$ 的卷积核。
本文的一个观点是,有时使用不同大小的卷积核组合是有利的。
在本节中,我们将介绍一个稍微简化的GoogLeNet版本:我们省略了一些为稳定训练而添加的特殊特性,但是现在有了更好的训练算法,这些特性是不必要的。
在本节中,我们将介绍个稍微简化的GoogLeNet版本:我们省略了一些为稳定训练而添加的特殊特性,但是现在有了更好的训练算法,这些特性不是必要的。
## Inception块
在GoogLeNet中,基本的卷积块被称为*Inception块*“Inception block”),得名于同名电影《盗梦空间》(Inception)。
在GoogLeNet中,基本的卷积块被称为*Inception块*Inception block),很可能得名于电影《盗梦空间》(Inception)。
![Inception块的结构。](../img/inception.svg)
:label:`fig_inception`
如 :numref:`fig_inception` 所示,Inception块由四条并行线路组成。
前三条线路使用窗口大小为 $1\times 1$、$3\times 3$ 和 $5\times 5$ 的卷积层,从不同空间大小的卷积层中提取信息。
中间的两条线路在输入上执行 $1\times 1$ 卷积,以减少通道数,从而降低模型的复杂性。
第四条线路使用 $3\times 3$ 最大池化层,其次是 $1\times 1$ 卷积层来改变通道数。
这四条线路都使用合适的填充来使输入与输出的高和宽一致,最后我们将每条线路的输出在通道维度上连结,并输入接下来的层中去
如 :numref:`fig_inception` 所示,Inception块由四条并行路径组成。
前三条路径使用窗口大小为 $1\times 1$、$3\times 3$ 和 $5\times 5$ 的卷积层,从不同空间大小中提取信息。
中间的两条路径在输入上执行 $1\times 1$ 卷积,以减少通道数,从而降低模型的复杂性。
第四条路径使用 $3\times 3$ 最大池化层,然后是 $1\times 1$ 卷积层来改变通道数。
这四条路径都使用合适的填充来使输入与输出的高和宽一致,最后我们将每条线路的输出在通道维度上连结,并构成Inception块的输出。初始块的通常调整的超参数是每层输出通道的数量
在Inception块中,通常调整的超参数是每层输出通道的数量。
```{.python .input}
......@@ -30,7 +30,7 @@ from mxnet.gluon import nn
npx.set_np()
class Inception(nn.Block):
# `c1`--`c4` 是每条线路的输出通道数
# `c1`--`c4` 是每条路径的输出通道数
def __init__(self, c1, c2, c3, c4, **kwargs):
super(Inception, self).__init__(**kwargs)
# 线路1,单1 x 1卷积层
......@@ -64,7 +64,7 @@ from torch import nn
from torch.nn import functional as F
class Inception(nn.Module):
# `c1`--`c4` 是每条线路的输出通道数
# `c1`--`c4` 是每条路径的输出通道数
def __init__(self, in_channels, c1, c2, c3, c4, **kwargs):
super(Inception, self).__init__(**kwargs)
# 线路1,单1 x 1卷积层
......@@ -94,7 +94,7 @@ from d2l import tensorflow as d2l
import tensorflow as tf
class Inception(tf.keras.Model):
# `c1`--`c4` 是每条线路的输出通道数
# `c1`--`c4` 是每条路径的输出通道数
def __init__(self, c1, c2, c3, c4):
super().__init__()
# 线路1,单1 x 1卷积层
......@@ -121,20 +121,20 @@ class Inception(tf.keras.Model):
return tf.keras.layers.Concatenate()([p1, p2, p3, p4])
```
那么为什么GoogLeNet这个网络如此卓有成效呢?
首先我们考虑一下滤波器的组合,他们可以探索各种滤镜尺寸的图像,这意味着不同大小的滤波器可以有效地识别不同范围的图像细节。
那么为什么GoogLeNet这个网络如此效呢?
首先我们考虑一下滤波器(filter)的组合,他们可以探索各种滤波器尺寸的图像,这意味着不同大小的滤波器可以有效地识别不同范围的细节。
同时,我们可以为不同的滤波器分配不同数量的参数。
## GoogLeNet 模型
如 :numref:`fig_inception_full` 所示,GoogLeNet 一共使用 9 个启动块和全局平均池化层来生成其估计值。启动模块之间的最大池化层可降低维度。
第一个模块类似于 AlexNet 和 LeNet,堆栈的使用继承了 VGG 的优势,而全局平均池化层最终避免使用全连接层。
如 :numref:`fig_inception_full` 所示,GoogLeNet 一共使用 9 个Inception块和全局平均池化层的堆叠来生成其估计值。Inception块之间的最大池化层可降低维度。
第一个模块类似于 AlexNet 和 LeNet,Inception块的栈从VGG继承,全局平均池化层避免在最后使用全连接层。
![GoogLeNet结构。](../img/inception-full.svg)
:label:`fig_inception_full`
现在,我们逐一实现GoogLeNet的每个模块。第一个模块使用 64 个通道、 $7\times 7$ 卷积层。
我们现在可以一块一块地实现GoogLeNet的模块。第一个模块使用 64 个通道、 $7\times 7$ 卷积层。
```{.python .input}
b1 = nn.Sequential()
......@@ -158,7 +158,8 @@ def b1():
tf.keras.layers.MaxPool2D(pool_size=3, strides=2, padding='same')])
```
第二个模块使用两个卷积层:第一个卷积层是 64 通道、 $1\times 1$ 卷积层;第二个卷积层使用将通道数量增加三倍的 $3\times 3$ 卷积层。
第二个模块使用两个卷积层:第一个卷积层是 64个通道、 $1\times 1$ 卷积层;第二个卷积层使用将通道数量增加三倍的 $3\times 3$ 卷积层。
这对应于 Inception 块中的第二条路径。
```{.python .input}
b2 = nn.Sequential()
......@@ -185,8 +186,8 @@ def b2():
```
第三个模块串联两个完整的Inception块。
第一个Inception块的输出通道数为 $64+128+32+32=256$,四个路径之间的输出通道数量比为 $64:128:32:32=2:4:1:1$。
第二个和第三个路径首先将输入通道的数量分别减少到 $96/192=1/2$ 和 $16/192=1/12$,然后连接第二个卷积层。第二个Inception块的输出通道数增加到 $128+192+96+64=480$,四个路径之间的输出通道数量比为 $128:192:96:64 = 4:6:3:2$。
第一个 Inception 块的输出通道数为 $64+128+32+32=256$,四个路径之间的输出通道数量比为 $64:128:32:32=2:4:1:1$。
第二个和第三个路径首先将输入通道的数量分别减少到 $96/192=1/2$ 和 $16/192=1/12$,然后连接第二个卷积层。第二个 Inception 块的输出通道数增加到 $128+192+96+64=480$,四个路径之间的输出通道数量比为 $128:192:96:64 = 4:6:3:2$。
第二条和第三条路径首先将输入通道的数量分别减少到 $128/256=1/2$ 和 $32/256=1/8$。
```{.python .input}
......@@ -214,9 +215,9 @@ def b3():
第四模块更加复杂,
它串联了5个Inception块,其输出通道数分别是 $192+208+48+64=512$ 、 $160+224+64+64=512$ 、 $128+256+64+64=512$ 、 $112+288+64+64=528$ 和 $256+320+128+128=832$ 。
这些线路的通道数分配和第三模块中的类似,首先是含 $3×3$ 卷积层的第二条线路输出最多通道,其次是仅含 $1×1$ 卷积层的第一条线路,之后是含 $5×5$ 卷积层的第三条线路和含 $3×3$ 最大池化层的第四条线路
其中第二、第三条线路都会先按比例减小通道数。
这些比例在各个Inception块中都略有不同。
这些路径的通道数分配和第三模块中的类似,首先是含 $3×3$ 卷积层的第二条路径输出最多通道,其次是仅含 $1×1$ 卷积层的第一条路径,之后是含 $5×5$ 卷积层的第三条路径和含 $3×3$ 最大池化层的第四条路径
其中第二、第三条路径都会先按比例减小通道数。
这些比例在各个 Inception 块中都略有不同。
```{.python .input}
b4 = nn.Sequential()
......@@ -251,7 +252,7 @@ def b4():
```
第五模块包含输出通道数为 $256+320+128+128=832$ 和 $384+384+128+128=1024$ 的两个Inception块。
其中每条线路的通道数的分配思路和第三、第四模块中的一致,只是在具体数值上有所不同。
其中每条路径的通道数的分配思路和第三、第四模块中的一致,只是在具体数值上有所不同。
需要注意的是,第五模块的后面紧跟输出层,该模块同 NiN 一样使用全局平均池化层,将每个通道的高和宽变成1。
最后我们将输出变成二维数组,再接上一个输出个数为标签类别数的全连接层。
......@@ -322,7 +323,7 @@ for layer in net().layers:
## 训练模型
和以前一样,我们使用 Fashion-MNIST 数据集来训练我们的模型。在训练过程之前,我们将其图片转换为 $96 \times 96$ 像素分辨率。
和以前一样,我们使用 Fashion-MNIST 数据集来训练我们的模型。在训练过程之前,我们将其图片转换为 $96 \times 96$ 分辨率。
```{.python .input}
#@tab all
......@@ -334,22 +335,18 @@ d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr)
## 小结
* Inception块相当于一个有4条线路的子网络。它通过不同窗口形状的卷积层和最大池化层来并行抽取信息,并使用 $1×1$ 卷积层减少通道数从而降低模型复杂度。
* GoogLeNet将多个设计精细的Inception块与其他层(卷积层、全连接层)串联起来。其中Inception块的通道数分配之比是在 ImageNet 数据集上通过大量的实验得来的。
* GoogLeNet 和它的后继者们一度是 ImageNet 上最高效的模型之一:在类似的测试精度下,它们的计算复杂度往往更低
* Inception 块相当于一个有4条路径的子网络。它通过不同窗口形状的卷积层和最大池化层来并行抽取信息,并使用 $1×1$ 卷积层减少每像素级别上的通道维数从而降低模型复杂度。
* GoogLeNet将多个设计精细的 Inception 块和其他层连接起来。其中 Inception 块的通道数分配之比是在ImageNet 数据集上通过大量的实验得来的。
* GoogLeNet 和它的后继者们一度是 ImageNet 上最有效的模型之一:它以较低的计算复杂度提供了类似的测试精度
## 练习
GoogLeNet有数个后续版本。尝试实现并运行它们,然后观察实验结果。这些后续版本包括加入批量归一化层(下一节将介绍)、对Inception块做调整和加入残差连接(“残差网络(ResNet)”一节将介绍)。
对比AlexNet、VGG和NiN、GoogLeNet的模型参数尺寸。为什么后两个网络可以显著减小模型参数尺寸?
1. GoogLeNet 有数个后续版本。尝试实现并运行它们,然后观察实验结果。这些后续版本包括:
* 添加批量归一化层 :cite:`Ioffe.Szegedy.2015`,(下一节将介绍)。
*Inception块进行调整。
* 使用标签平滑(label smoothing)进行模型正则化 :cite:`Szegedy.Vanhoucke.Ioffe.ea.2016`
* 加入残差连接 :cite:`Szegedy.Ioffe.Vanhoucke.ea.2017`(“残差网络(ResNet)”一节将介绍)
* 添加批量归一化层 :cite:`Ioffe.Szegedy.2015`,(下一节将介绍)。
* Inception 模块进行调整。
* 使用标签平滑(label smoothing)进行模型正则化 :cite:`Szegedy.Vanhoucke.Ioffe.ea.2016`
* 加入残差连接 :cite:`Szegedy.Ioffe.Vanhoucke.ea.2017`(:numref:`sec_resnet`一节将介绍)
1. 使用 GoogLeNet 的最小图像大小是多少?
1. 将 AlexNet、VGG 和 NiN 的模型参数大小与 GoogLeNet 进行比较。后两个网络架构是如何显著减少模型参数大小的?
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册