《动手学深度学习》 — 动手学深度学习 2.0.0-beta0 documentation (d2l.ai)
深度卷积神经网络(AlexNet)
相较LeNet
- 使用ReLU激活函数,缓解梯度消失问题
- 使用暂退法控制全连接层模型复杂度
- 用图像增强数据(如翻转、裁切、变色)扩充训练数据集
- 网络更深更广、图像分辨率更高
- 使用更小的学习率训练
使用块的网络(VGG)
VGG块
最初的VGG块
- 带有卷积核、填充为1(保持高度和宽度)的卷积层
- 非线性激活函数(ReLU)
- 带有汇聚窗口、步幅为2(每个块后分辨率减半)的最大汇聚层
VGG块的实现
def vgg_block(num_convs, in_channels, out_channels): layers = [] for _ in range(num_conv): layers.append(nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1)) layers.append(nn.ReLU()) in_channels = out_channels layers.append(nn.MaxPool2d(kernel_size=2, stride=2)) return nn.Sequential(*layers)
VGG-11模型
- 包含5个卷积块
- 前两个卷积块各有一个卷积层
- 后三个卷积块各有两个卷积层
- 共8个卷积层,3个全连接层,故称VGG-11
# (num_convs, out_channels) conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))
网络中的网络(NiN)
NiN块
普通卷积层后接两个的卷积层。
def nin_block(in_channels, out_channels, kernel_size, strides, padding): return nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size, strides, padding), nn.ReLU(), nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU(), nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU() )
NiN模型
- 使用窗口形状为,,的卷积层
- 每个NiN块后有一个最大汇聚层,汇聚窗口形状为,步幅为2
- 相较AlexNet,取消了全连接层,以全局平均汇聚层(global average pooling layer)替代,生成一个对数几率(logits)
nn.AdaptiveAvgPool2d((1,1)), nn.Flatten()
例如最后几个块的输出形状为:
Sequential output shape: torch.Size([1, 10, 5, 5]) AdaptiveAvgPool2d output shape: torch.Size([1, 10, 1, 1]) Flatten output shape: torch.Size([1, 10])
取消全连接层的原因:
- 全连接层丢弃了表征的空间结构
- 全连接层易造成过拟合
- 全连接层模型所需参数量较大
含并行连结的网络(GoogLeNet)
Inception块
- 卷积层用来改变通道数,降低模型复杂性
- 四条路径均使用合适填充来使输入与输出的高和宽一致
- 不同大小的滤波器可以有效识别不同范围的图像细节
GoogLeNet模型
批量规范化(batch normalization)
只有使用足够大的小批量,批量规范化这种方法才是有效、稳定的。
其中和也是待学习的拉伸(scale)和偏移(shift)参数。每个通道都有各自的和。
的添加是为了防止除以0的情况。
优化中的各种噪声是有益的,通常会导致更快的训练和较少的过拟合。
通过移动平均估算整个训练数据集的样本均值和方差,并在预测时使用他们得到确定的输出。
# 每次前向传播时,更新移动平均的均值和方差 momentum=0.9 moving_mean = momentum * moving_mean + (1 - momentum) * batch_mean moving_var = momentum * moving_var + (1 - momentum) * batch_var
残差网络(ResNet)
基本思想
当更换框架时,只有当更换后较复杂的函数类包含原本较小的函数类(嵌套函数类)时,才能确保挺高性能。
残差网络的核心思想是:每个附加层都应该更容易地包含原始函数作为其元素之一。
残差块(residual block)
上图右边为一个残差块。如果想要改变通道数,需引入一个卷积层。
ResNet-18
- 4个由残差块组成的模块
- 每个模块有4个卷积层
- 再加上开始的卷积层和最后的全连接层
- 共18层
稠密连接网络(DenseNet)
ResNet和DenseNet的关键区别在于:DenseNet输出是连接([,]表示),而不是如ResNet的简单相加。
稠密网络的组成部分:
- 稠密块(dense block):定义如何连接输入和输出
- 过渡层(transition layer):控制通道数量,降低复杂性
稠密块
卷积块的通道数控制了输出通道数相对于输入通道数的增长,因此被称为增长率(growth rate)。
过渡层
- 通过卷积层减小通道数
- 使用步幅为2的平均汇聚层减半高和宽
DenseNet模型
略