社区计算机视觉课程文档
卷积神经网络导论
并获得增强的文档体验
开始使用
卷积神经网络导论
在上一个单元中,我们学习了视觉、图像和计算机视觉的基础知识。我们还探讨了视觉特征,它是借助计算机分析图像的关键部分。
我们讨论的方法在今天通常被称为“经典”计算机视觉。虽然经典方法在许多小型和受限的数据集和设置中运行良好,但当观察更大规模的真实世界数据集时,经典方法存在局限性。
在本单元中,我们将学习卷积神经网络,这是计算机视觉在规模和性能方面向前迈出的重要一步。
卷积:基本概念
卷积是一种用于从数据中提取特征的操作。数据可以是 1D、2D 或 3D。我们将用一个具体的例子来解释这个操作。您现在只需要知道的是,该操作只是取一个由数字组成的矩阵,在数据中移动它,并取数据和该矩阵之间乘积的总和。这个矩阵称为内核或滤波器。您可能会说,“这与特征提取有什么关系,我应该如何应用它?” 别慌!我们马上就讲到。
为了说明直觉,让我们看一下这个例子。我们有这个 1D 数据,我们将其可视化。可视化将有助于理解卷积运算的效果。

我们有这个内核 [-1, 1]。我们将从最左边的元素开始,放置内核,将重叠的数字相乘,然后将它们加起来。内核有中心;它是其中一个元素。在这里,我们选择中心为 1(右边的元素)。我们在这里选择中心为 1,假设左边有一个虚构的零,这称为填充,您稍后会看到。现在,内核的中心必须接触每个元素,因此为了方便起见,我们在元素的左侧放置一个零。如果我们不填充它,我将不得不开始将 -1 与最左边的元素相乘,而 1 将不会接触最左边的元素,因此我们应用填充。让我们看看它是什么样子的。

我将最左边的元素(当前是填充)与 -1 相乘,将第一个元素(零)与 1 相乘,然后将它们加起来,得到 0,并将其记录下来。现在,我们将内核移动一个位置并执行相同的操作。再次记录下来,此移动称为步幅,这通常通过将内核移动一个像素来完成。您也可以移动更多像素。结果(卷积数据)当前是一个数组 [0, 0]。

我们将重复此操作,直到内核的右元素接触每个元素,从而产生以下结果。

注意到什么了吗?滤波器给出了数据的变化率(导数!)。这是我们可以从数据中提取的一个特征。让我们将其可视化。

卷积数据(卷积的结果)称为特征图。这很有意义,因为它显示了我们可以提取的特征、与数据相关的特征以及变化率。
这正是边缘检测滤波器所做的!让我们在二维数据中看看它。这次,我们的内核将有所不同。它将是一个 3x3 内核(只是为了让您知道它也可能是 2x2)。

这个滤波器实际上非常有名,但我们现在不会剧透 :)。之前的滤波器是 [-1 1]。同时,这个滤波器是 [-1 0 1]。它只是形状为 3x3,没有其他不同之处,它显示了水平轴上的增量和减量。让我们看一个例子并应用卷积。下面是我们的 2D 数据。

将此视为图像,我们想要提取水平变化。现在,滤波器的中心必须接触每个像素,因此我们填充图像。

特征图将与原始数据的大小相同。卷积的结果将写入内核中心在原始矩阵中接触的相同位置,这意味着,对于这个,它将接触最左边和最上面的位置。

如果我们继续应用卷积,我们将获得以下特征图。

它向我们展示了水平变化(边缘)。这个滤波器实际上被称为 Prewitt 滤波器。

您可以翻转 Prewitt 滤波器以获得垂直方向的变化。Sobel 滤波器是另一个用于边缘检测的著名滤波器。
卷积神经网络
很好,但这与深度学习有什么关系呢?好吧,强制使用滤波器来提取特征并非在每张图像上都有效。想象一下,如果我们能够以某种方式找到最佳滤波器来提取重要信息,甚至检测图像中的物体。这就是卷积神经网络发挥作用的地方。我们将图像与各种滤波器进行卷积,并且特征图中的这些像素最终将成为我们将要优化的参数,最终,我们将为我们的问题找到最佳滤波器。
我们的想法是,我们将使用滤波器来提取信息。我们将随机初始化多个滤波器,创建我们的特征图,将它们馈送到分类器,并进行反向传播。在深入研究之前,我想向您介绍一些我们称之为“池化”的东西。
如您在上面看到的,有许多像素显示了特征图中的变化。要了解是否存在边缘,我们只需要看到存在变化(边缘、角、任何东西),仅此而已。

在上面的示例中,我们可以只获得两个中的一个,这已经足够了。这样,我们将存储更少的参数,并且仍然具有特征。这种获取特征图中最重要的元素的操作称为池化。通过池化,我们失去了边缘的确切像素位置,但我们存储了更少的参数。此外,通过这种方式,我们的特征提取机制将对微小的变化更加鲁棒,例如,我们只需要知道图像中有两个眼睛、一个鼻子和一张嘴就知道图像中有一张脸,这些元素之间的距离和这些元素的大小往往会因人而异,而池化使模型能够更鲁棒地应对这些变化。关于池化的另一个好处是,它有助于我们处理不同的输入大小。下面是最大池化操作,其中每四个像素,我们得到最大像素。池化有多种类型,例如,平均池化、加权池化或 L2 池化。
让我们构建一个简单的 CNN 架构。我们将使用 Keras 示例(为了说明),我们将引导您了解正在发生的事情。下面是我们的模型(同样,不要惊慌,我们将引导您了解正在发生的事情)。
如果您不知道 Keras Sequential API 在做什么,它会像乐高积木一样堆叠层并将它们连接起来。每个层都有不同的超参数,Conv2D 层采用卷积滤波器的数量、内核大小和激活函数,而 MaxPooling2D 采用池化大小,密集层采用输出单元的数量(同样,不要惊慌)。
大多数 convnet 实现不进行填充,以使内核接触图像处理方式中的每个像素。用零填充会带来一个假设,即我们可能在边界处有特征,并且它增加了顶层计算的复杂性。这就是您看到第一个输入大小为 (26,26) 的原因,我们沿着边界丢失了信息。
model = keras.Sequential(
[
keras.Input(shape=input_shape),
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Flatten(),
layers.Dropout(0.5),
layers.Dense(num_classes, activation="softmax"),
]
)
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 13, 13, 32) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 11, 11, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64) 0
_________________________________________________________________
flatten (Flatten) (None, 1600) 0
_________________________________________________________________
dropout (Dropout) (None, 1600) 0
_________________________________________________________________
dense (Dense) (None, 10) 16010
=================================================================
Total params: 34,826
Trainable params: 34,826
Non-trainable params: 0
_________________________________________________________________
卷积神经网络以输入层和卷积层开始。Keras Conv2D 层采用内核数量和内核大小作为参数。下面说明了正在发生的事情。在这里,我们将图像与 32 个内核卷积,最终得到 32 个特征图,每个特征图的大小与图像相同。

在卷积层之后,我们放置一个最大池化层,以减少存储的参数数量,并使模型对变化具有鲁棒性,如上所述。这将减少计算的参数数量。


卷积神经网络中的反向传播理论
反向传播在这里是如何工作的?我们想要优化这里的最佳内核值,因此它们是我们的权重。最后,我们期望分类器找出像素值、内核和类之间的关系。因此,我们有一个非常长的展平数组,其中包含与初始权重(内核元素)卷积的像素的池化和激活版本。我们更新这些权重,以便我们回答问题“我应该应用哪些内核来区分猫和狗的照片?”。训练 CNN 的目的是提出最佳内核,这些内核是通过反向传播找到的。在 CNN 之前,人们会尝试在图像上尝试大量滤波器来自己提取特征,同时大多数通用滤波器(正如我们在上面看到的,例如 Prewitt 或 Sobel)不一定适用于所有图像,因为即使在同一数据集中,图像也可能非常不同。这就是为什么 CNN 的性能优于传统的图像处理技术。
当我们使用卷积神经网络时,在存储方面有几个优势。
参数共享
在卷积神经网络中,我们使用相同的滤波器在所有像素、所有通道和所有图像上进行卷积,这提供了优于存储参数的优势,这比使用密集神经网络遍历图像效率更高。这称为“权重绑定”,这些权重称为“绑定权重”。这也在自编码器中看到。
稀疏交互
在密集连接的神经网络中,我们一次性输入整个数据片段 - 由于图像具有数百或数千个像素,这非常令人难以承受 - 同时在 convnet 中,我们使用较小的内核来提取特征。这称为稀疏交互,它有助于我们使用更少的内存。
< > 在 GitHub 上更新