一 从全连接层到卷积:

1.为什么MLP的全连接层不适用于图像分类任务?

我们之前讨论的多层感知机十分适合处理表格数据,其中行对应样本,列对应特征。
对于表格数据,我们寻找的模式可能涉及特征之间的交互,但是我们不能预先假设任何与特征交互相关的先验结构

假设我们有一个足够充分的照片数据集,数据集中是拥有标注的照片,每张照片具有百万级像素,这意味着网络的每次输入都有一百万个维度。 即使将隐藏层维度降低到1000,这个全连接层也将有$10^6×10^3$个参数。
此外,MLP在处理图像前,需要将其“展平”(flatten)成一个一维向量。这个操作完全破坏了图像固有的空间结构信息(例如,像素之间的邻近关系、物体的局部形状等),而这些信息对于理解图像内容至关重要。

如今人类和机器都能很好地区分猫和狗:这是因为图像中本就拥有丰富的结构,而这些结构可以被人类和机器学习模型使用。
卷积神经网络(convolutional neural networks,CNN)就是机器学习利用自然图像中一些已知结构的创造性方法。

2.卷积的原理——空间不变性:

以从一张图片里找到一个对象的任务为例,因为对象不管在哪里,其形态都相同,所以神经网络架构应该满足:

  1. 平移不变性(translation invariance):不管检测对象出现在图像中的哪个位置,神经网络的前面几层应该对相同的图像区域具有相似的反应,即为“平移不变性”。
  2. 局部性(locality):神经网络的前面几层应该只探索输入图像中的局部区域,而不过度在意图像中相隔较远区域的关系,这就是“局部性”原则。最终,可以聚合这些局部特征,以在整个图像级别进行预测。这样得到的便是一个卷积层,$[V]_{a,b}$被称为卷积核/滤波器,或简单地称之为该卷积层的权重,通常该权重是可学习的参数。
    如果是三维图片(加上一个维度c)且是多通道的(如RGB Channel,需要增加第四维d):

    3.卷积核计算≠数学上的卷积

    为什么上述计算被称为卷积?
    数学上的卷积定义:卷积是当把一个函数g“翻转”并移位x时,测量f和g之间的重叠区域面积。
    对离散的对象:如果输入的是二维张量,则:这与前面构造的卷积核类似,实际上,深度学习的卷积是在数学上是互相关(Cross Correlation) 计算,与卷积的区别在于,卷积使用的是差值,而卷积层使用的是和值。
    实际计算时,在几乎所有的深度学习框架(TensorFlow, PyTorch等)中,所谓的 “卷积层”实际上执行的是互相关操作 ,而不是像卷积计算那样,将卷积核先水平翻转,再垂直翻转,然后再进行滑动和元素乘积求和。

    二 卷积神经网络的核心机制

1.CNN引入了新的概念:

  • 局部感受野 (Local Receptive Fields):每个神经元不再连接到前一层的所有神经元,而只连接到一个局部的区域。这就像我们看东西时,总是一小块一小块地聚焦,而不是一眼就看到所有像素的细节。
  • 参数共享 (Parameter Sharing):在一个图像中,用于检测某个特征(例如,一个垂直边缘)的参数,在图像的不同位置上应该是相同的。因此,CNN使用一个共享的卷积核(或称为滤波器) 来“扫描”整个图像,极大地减少了参数数量。
  • 池化 (Pooling):通过对特征进行下采样(down-sampling)来降低特征图的维度,使得模型对物体在图像中的微小位移不那么敏感(即平移不变性),同时减少计算量。

2.一个经典的CNN架构流程:

INPUT -> [CONV -> ReLU -> POOL] * N -> [FC -> ReLU] * M -> OUTPUT

  • 输入层 (INPUT):接收原始图像数据,例如 $32\times32\times3$ 的张量。
  • 卷积-激活-池化层 (CONV-ReLU-POOL):这个组合是CNN的核心特征提取器。
    • 网络的前几层通常学习到一些低级特征,如边缘、角点、颜色块。
    • 随着网络加深,后续层会组合这些低级特征,形成更高级、更抽象的特征,如眼睛、鼻子、轮廓,或者是物体的部件。
  • 全连接层 (FC):在经过多次特征提取后,最终得到的抽象特征图会被展平成一个向量,然后送入一个或多个全连接层。这部分的作用与MLP类似,它根据提取到的高级特征进行“推理”,并完成最终的分类任务。
  • 输出层 (OUTPUT):使用Softmax等函数输出最终的类别概率。

    为什么ReLU可以引入非线性?

    Relu拟合任意函数的机制:add+stack后变成复杂分段线性函数,可以拟合非线性函数,

    三 卷积层

    1.工作流程

  1. 输入特征图 (Input Feature Map):待处理的数据,例如原始图像。
  2. 卷积核 (Kernel / Filter):一个小的权重矩阵(例如 $3\times3 或 5\times5$),这个权重是需要通过训练学习的。每个卷积核都像一个“特征探测器”,专门用于探测某种特定的局部特征(如垂直边缘、红色块等)。
  3. 卷积操作:卷积核在输入特征图上从左到右、从上到下滑动。在每一个位置,计算卷积核与输入特征图上对应小块的元素乘积之和
  4. 输出特征图 (Output Feature Map / Activation Map):将所有位置的计算结果组合起来,形成一个新的二维矩阵,即输出特征图。这个图上的每个像素值,代表了该位置对卷积核所探测特征的响应强度。

    2.卷积核:

    1x1卷积核:实现跨通道的线性组合
    一个卷积层的输入特征图尺寸为 $H\times W\times C{in}$($C{in}$输入通道数)。
    一个 1x1 的卷积核,其完整的尺寸实际上是 1x1x$C{in}$。当它进行“卷积”操作时,在输入图的每一个像素位置 (h, w) 上,它所做的是: **将该位置上所有$C{in}$个通道的值,与卷积核自身的 $C_{in}$个权重进行加权求和。
    这本质上是在
    不改变图像宽高的情况下,对每一个像素位置的通道信息做了一次全连接操作。
    (此外,1x1卷积层还可以在网络学习中引入
    非线性,因为卷积层是卷积+激活函数**,可以在不改变图像宽高的情况下,对特征进行一次非线性变换,增强了网络的表达能力)

    3.超参数

    (1)滤波器数量 (Number of Filters)

    决定了输出特征图的深度。如果有64个滤波器,输出的深度就是64。每个滤波器学习探测一种不同的特征。
    滤波器数量(也即卷积核数量)决定输出通道的数量,从而实现升降维。
    例如,如果你的输入是 56x56x192(192个通道),但你希望减少计算量,你可以使用32个 1x1 的卷积核。输出的特征图尺寸将变为 56x56x32。通道数从192锐减到32,极大地减少了后续卷积层的参数量和计算量。

    (2) 填充 (Padding)

    一个240x240像素的图像,经过10层5x5的卷积后,将减少到200x200像素。如此一来,原始图像的边界丢失了许多有用信息。
    我们可以在输入特征图的边缘填充0。这主要有两个目的:
    1. 保持边界信息:让卷积核能够处理到图像边缘的像素。
    2. 控制输出尺寸:通过适当的填充,可以使输出特征图的宽高与输入保持一致。
      如果我们添加$p_h$行填充(大约一半在顶部,一半在底部)和$p_w$列填充(左侧大约一半,右侧一半),则输出形状将为在许多情况下,我们需要设置$p_h=k_h-1$和$p_w=k_w-1$,使输入和输出具有相同的高度和宽度$n_h$和$n_k$。也就是每次用卷积核处理时都在图像外围增加$(k_h-1)/2$行和$(k_w-1)/2$列。

      (3)步幅 (Stride)

      卷积核每次滑动的像素距离。步幅为1表示逐像素滑动,步幅为2则会使输出特征图的尺寸减半。
      当垂直步幅为$s_h$、水平步幅为$s_w$时,输出形状为:由于一般我们设置$p_h=k_h-1$和$p_w=k_w-1$,这样输出形状即为如果$n_h$和$n_k$分别能被$s_h$和$s_k$整除,那么输出形状为$[n_h/s_h]\times[n_w/s_w]$因为$s_h-1/s_h<1$

四 池化层 (Pooling,也称汇聚层)

(1)目的:

a.降低卷积层对位置的敏感性:

假设一个 2x2 的最大池化窗口正在处理一个探测“眼睛”的特征图。如果这只“眼睛”在输入图像中向右平移了一个像素,它在特征图上的强烈响应位置也会平移一个像素。但只要这个强烈响应仍然落在这个 2x2 的池化窗口内,池化后的输出值将完全相同

b.降低对空间降采样表示的敏感性:

池化操作将一个局部区域内的特征图信息,用一个单一的值(如该区域的最大值)来概括。 这可以被看作是一种特征选择信息提炼
一方面使得特征图的尺寸变小,后续层的计算量和参数量都随之减少。
另一方面,通过保留最关键的信息并丢弃部分细节,有助于提升模型的泛化能力。

(2)两种pooling:

pooling是使用类似的卷积的滑动窗口(常用2x2大小),但它没有参数,只是做如下两种操作的一种:

  • 最大池化 (Max Pooling)最常用。在窗口内取最大值作为输出。它能有效地保留最显著的特征(如最亮的像素点)。
  • 平均池化 (Average Pooling):在窗口内取平均值作为输出。它能平滑特征,保留更多的背景信息。
    我们当然也可以指定汇聚层的填充和步幅。使用最大汇聚层以及大于1的步幅,可减少空间维度(高度和宽度)。

    五 现代CNN网络:从LeNet到ResNet

    1.LeNet:


    Yann LeCun的LeNet
    LeNet(LeNet-5)由两个部分组成:
  • 卷积编码器:由两个卷积层组成;
  • 全连接层密集块:由三个全连接层组成。
    每个卷积块中的基本单元是一个卷积核、一个sigmoid激活函数和平均汇聚层。(虽然ReLU和最大汇聚层更有效,但它们在20世纪90年代还没有出现)
    第一卷积层有6个输出通道(得到6@28x28,即六个输出通道,每个通道和之前输入的大小相等),池操作通过空间下采样将维数减少4倍(得到6@14x14)
    而第二个卷积层有16个输出通道(6@10x10)。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    net = nn.Sequential(
    nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Flatten(),
    nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
    nn.Linear(120, 84), nn.Sigmoid(),
    nn.Linear(84, 10))

2.AlexNet

在2012年前,图像特征都是机械地计算出来的。事实上,设计一套新的特征函数、改进结果,并撰写论文是盛极一时的潮流。SIFT (Lowe, 2004)、SURF (Bay et al., 2006)、HOG(定向梯度直方图) (Dalal and Triggs, 2005)、bags of visual words和类似的特征提取方法占据了主导地位。

另一组研究人员认为特征本身应该被学习。在合理地复杂性前提下,特征应该由多个共同学习的神经网络层组成,每个层都有可学习的参数。在机器视觉中,最底层可能检测边缘、颜色和纹理。这个便是AlexNet的思想。

包含许多特征的深度模型需要大量的有标签数据,才能显著优于基于凸优化的传统方法(如线性方法和核方法)。2009年,ImageNet数据集发布,并发起ImageNet挑战赛:要求研究人员从100万个样本中训练模型,以区分1000个不同类别的对象。这一开源数据集解决了训练模型数据不足的问题。

另一方面,深度学习对计算资源要求很高,训练可能需要数百个迭代轮数,每次迭代都需要通过代价高昂的许多线性代数层传递数据。这也是为什么在20世纪90年代至21世纪初,优化凸目标的简单算法是研究人员的首选。然而,用GPU训练神经网络改变了这一格局。

在此背景下,AlexNet应运而生,它用强大的硬件(GPU)和更深的网络结构,以碾压性的优势告诉全世界:深度学习这条路,走得通!

LeNet与AlexNet的对比,如上图
1.由于图片像素量不同,所以第一层卷积层更大。此外AlexNet的卷积通道数目是LeNet的10倍。
2.Sigmoid被换成了更简易并且梯度更新更稳定的ReLU
3.AlexNet使用了Dropout,而LeNet只使用了权重衰减。
4.为了进一步扩充数据,AlexNet在训练时增加了大量的图像增强数据,如翻转、裁切和变色。 这使得模型更健壮,更大的样本量有效地减少了过拟合。

3.VGG


VGG的作者们发现AlexNet的结构有点“杂乱”(用了大小不一的卷积核)。他们想,我们能不能只用一种最标准、最好用的“乐高积木”来搭建网络?他们选择了 3×3 的小卷积核。然后,他们就像一个强迫症艺术家一样,用这种积木整齐划一地、一层又一层地堆叠。
VGG的整个网络就是不断重复 [卷积 -> 卷积 -> 池化] 的过程。VGG证明了,只要结构设计得足够简洁优美,一味地加深网络也能带来性能的持续提升。

4.NiN

NiN的想法是在每个像素位置(针对每个高度和宽度)应用一个全连接层。 如果我们将权重连接到每个空间位置,我们可以将其视为 1x1 卷积层 ,或作为在每个像素位置上独立作用的全连接层。 从另一个角度看,即将空间维度中的每个像素视为单个样本,将通道维度视为不同特征(feature)。

VGG vs NiN
NiN块以一个普通卷积层开始,后面是两个的卷积层。这两个卷积层充当带有ReLU激活函数的逐像素全层。NiN完全取消了全连接层。 相反,NiN使用一个NiN块,其输出通道数等于标签类别的数量。
最后放一个全局平均汇聚层(global average pooling layer),它不再粗暴地将特征图展平,而是将每个特征图(代表一种高级特征)取一个平均值,这极大地减少了参数数量,降低了过拟合风险。

5.GoogLeNet

使用Inception块,结构如下,是四个并行的子路径。
前三条路径使用窗口大小为1x1、3x3和5x5的卷积层,从不同空间大小中提取信息。 中间的两条路径在输入上执行1x1卷积,以减少通道数,从而降低模型的复杂性。 第四条路径使用3x3最大汇聚层,然后使用卷积层来改变通道数。
它们可以用各种滤波器尺寸探索图像,这意味着不同大小的滤波器可以有效地识别不同范围的图像细节。 同时,我们可以为不同的滤波器分配不同数量的参数。

在网络的最后,也使用了借鉴自NiN的全局平均池化

6.ResNet

假设神经网络架构为F,对于所有f ∈ F,我们可以训练调整参数得到最优f
通常我们无法直接找到最优的,但是可以优化损失函数:
$f
=\text{argmin}_f L(X,y,f)$
下图反映,对非嵌套函数类,更复杂的函数(下图F6比F1更复杂)不一定比简单的更近似真函数。

因此,只有当较复杂的函数类包含较小的函数类时,我们才能确保提高它们的性能。
对于深度神经网络,如果我们能将新添加的层训练成 恒等映射(identity function),新模型和原模型将同样有效。同时,由于新模型可能得出更优的解来拟合训练数据集,因此添加层似乎更容易降低训练误差。
残差网络的核心思想是:每个附加层都应该更容易地包含原始函数作为其元素之一。 于是,残差块(residual blocks)便诞生了。允许原始信息(和梯度)直接跳过几个复杂的层,快速传递到网络的深处。


正常块vs残差块