d2l自学笔记 – 7.现代卷积神经网络

《动手学深度学习》 — 动手学深度学习 2.0.0-beta0 documentation (d2l.ai)

深度卷积神经网络(AlexNet)


相较LeNet

  • 使用ReLU激活函数,缓解梯度消失问题
  • 使用暂退法控制全连接层模型复杂度
  • 用图像增强数据(如翻转、裁切、变色)扩充训练数据集
  • 网络更深更广、图像分辨率更高
  • 使用更小的学习率训练

使用块的网络(VGG)

VGG块

最初的VGG块

  • 带有3×33\times 3卷积核、填充为1(保持高度和宽度)的卷积层
  • 非线性激活函数(ReLU)
  • 带有2×22\times 2汇聚窗口、步幅为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块

普通卷积层后接两个1×11\times 1的卷积层。

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模型

  • 使用窗口形状为11×1111\times 115×55\times 53×33\times 3的卷积层
  • 每个NiN块后有一个最大汇聚层,汇聚窗口形状为3×33\times 3,步幅为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块

  • 1×11\times 1卷积层用来改变通道数,降低模型复杂性
  • 四条路径均使用合适填充来使输入与输出的高和宽一致
  • 不同大小的滤波器可以有效识别不同范围的图像细节

GoogLeNet模型

批量规范化(batch normalization)

只有使用足够大的小批量,批量规范化这种方法才是有效、稳定的。
BN(x)=γxμ^Bσ^B+β\mathrm{BN}(\mathbf{x})=\gamma \odot \frac{\mathbf{x}-\hat{\mu}_{B}}{\hat{\sigma}_{B}}+\beta

其中γ\gammaβ\beta也是待学习的拉伸(scale)和偏移(shift)参数。每个通道都有各自的γ\gammaβ\beta

μ^B=1BxBxσ^E2=1BxB(xμ^B)2+ϵ\begin{aligned} &\hat{\mu}_{B}=\frac{1}{|\mathcal{B}|} \sum_{\mathbf{x} \in B} \mathbf{x} \\ &\hat{\sigma}_{E}^{2}=\frac{1}{|\mathcal{B}|} \sum_{\mathbf{x} \in B}\left(\mathbf{x}-\hat{\mu}_{B}\right)^{2}+\epsilon \end{aligned}

ϵ>0\epsilon >0的添加是为了防止除以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)

上图右边为一个残差块。如果想要改变通道数,需引入一个1×11\times 1卷积层。

ResNet-18

  • 4个由残差块组成的模块
  • 每个模块有4个卷积层
  • 再加上开始的7×77\times 7卷积层和最后的全连接层
  • 共18层

稠密连接网络(DenseNet)

ResNet和DenseNet的关键区别在于:DenseNet输出是连接([,]表示),而不是如ResNet的简单相加。

x[x,f1(x),f2([x,f1(x)]),f3([x,f1(x),f2([x,f1(x)])]),]\mathbf{x} \rightarrow\left[\mathbf{x}, f_{1}(\mathbf{x}), f_{2}\left(\left[\mathbf{x}, f_{1}(\mathbf{x})\right]\right), f_{3}\left(\left[\mathbf{x}, f_{1}(\mathbf{x}), f_{2}\left(\left[\mathbf{x}, f_{1}(\mathbf{x})\right]\right)\right]\right), \ldots \right]

稠密网络的组成部分:

  • 稠密块(dense block):定义如何连接输入和输出
  • 过渡层(transition layer):控制通道数量,降低复杂性

稠密块

卷积块的通道数控制了输出通道数相对于输入通道数的增长,因此被称为增长率(growth rate)。

过渡层

  • 通过1×11\times 1卷积层减小通道数
  • 使用步幅为2的平均汇聚层减半高和宽

DenseNet模型

发表评论

%d 博主赞过: