社区计算机视觉课程文档

卷积神经网络简介

Hugging Face's logo
加入 Hugging Face 社区

并获得增强文档体验

开始

卷积神经网络简介

在上一单元中,我们学习了视觉、图像和计算机视觉的基础知识。我们还探讨了视觉特征,它是借助计算机分析图像的关键部分。

我们讨论的方法今天通常被称为“经典”计算机视觉。虽然在许多小型和受限的数据集和设置中工作良好,但经典方法在处理更大规模的现实世界数据集时存在局限性。

在本单元中,我们将学习卷积神经网络,它是计算机视觉在规模和性能方面取得的重要进步。

卷积:基本概念

卷积是一种用于从数据中提取特征的操作。数据可以是 1D、2D 或 3D。我们将用一个具体的例子来解释这种操作。你现在只需要知道,这种操作只是取一个由数字组成的矩阵,在数据中移动它,并取数据和该矩阵的乘积之和。这个矩阵叫做核或过滤器。你可能会说,“这与特征提取有什么关系,我应该如何应用它?” 不要惊慌! 我们正在讲解它。

为了说明直觉,让我们看一个例子。我们有这个 1D 数据,我们将其可视化。可视化将有助于理解卷积操作的效果。

Kernel Image

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

1D Conv

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

1D Conv Multiplication

我们将重复此操作,直到核的右边元素接触到所有元素,这将产生以下结果。

1D Conv Result

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

Convolved Illustrated

卷积数据(卷积的结果)被称为特征图。这很有道理,因为它显示了我们可以提取的特征,与数据相关的特征,以及变化率。

这正是边缘检测过滤器所做的! 让我们在二维数据中看看它。这次,我们的核将有所不同。它将是一个 3x3 的核(只是让你知道它也可以是 2x2 的)。

2D Conv

这个过滤器实际上很有名,但我们现在不会告诉你它是什么:)。之前的过滤器是 [-1 1]。而这个过滤器是 [-1 0 1]。它只是形状为 3x3,没有什么不同,它显示了水平轴上的增量和减量。让我们看一个例子,并应用卷积。下面是我们的 2D 数据。

2D Conv

将其想象成一张图片,我们想提取水平变化。现在,过滤器的中心必须接触到每一个像素,所以我们填充图片。

Padding

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

2D Conv

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

2D Feature Map

它显示了水平变化(边缘)。这个过滤器实际上被称为 Prewitt 过滤器。

Prewitt and Sobel

你可以翻转 Prewitt 过滤器 以获得垂直方向的变化。 Sobel 过滤器 是另一个著名的边缘检测过滤器。

卷积神经网络

好的,但这与深度学习有什么关系? 嗯,对过滤器进行蛮力操作以提取特征对于每张图像都效果不好。想象一下,如果我们能找到最佳过滤器来提取重要信息,甚至检测图像中的物体,那该多好。这就是卷积神经网络发挥作用的地方。我们用各种过滤器对图像进行卷积,这些特征图中的像素最终将成为我们要优化的参数,最后,我们将找到最适合我们问题的过滤器。

这个想法是,我们将使用过滤器来提取信息。我们将随机初始化多个过滤器,创建我们的特征图,将它们馈送到分类器,并进行反向传播。在深入研究之前,我想向你介绍一下我们所说的“池化”。

如上所示,有许多像素显示了特征图的变化。为了知道存在边缘,我们只需要看到存在变化(边缘、角落、任何东西),仅此而已。

Pooling

在上面的例子中,我们只需要获得两个特征中的一个,这已经足够了。这样,我们可以存储更少的参数,同时仍然保留这些特征。这种从特征图中获取最重要的元素的操作称为池化。通过池化,我们失去了边缘的确切像素位置,但我们存储了更少的参数。此外,这样我们的特征提取机制对微小的变化更具鲁棒性,例如,我们只需要知道有两只眼睛、一个鼻子和一张嘴,就能知道图像中有一张脸,这些元素之间的距离和大小往往因人而异,池化使模型能够更好地应对这些变化。池化的另一个好处是它帮助我们处理不同的输入大小。我们希望您观看这段视频,以便更好地理解它。下面是最大池化操作,其中每四个像素,我们获取最大像素。池化有各种类型,例如平均池化、加权池化或 L2 池化。

让我们构建一个简单的 CNN 架构。我们将使用 Keras 示例(为了说明),并将逐步为您解释其工作原理。下面是我们的模型(再次,不要惊慌,我们将逐步为您解释其工作原理)。

如果您不知道 Keras Sequential API 在做什么,它就像乐高积木一样堆叠层并连接它们。每一层都有不同的超参数,Conv2D 层接受卷积滤波器的数量、内核大小和激活函数,而 MaxPooling2D 接受池化大小,密集层接受输出单元的数量(再次,不要惊慌)。

大多数卷积网络实现不进行填充,以便内核以图像处理的方式接触到图像中的每一个像素。用零进行填充是假设边界可能存在特征,它会增加计算复杂度。这就是为什么您看到第一个输入大小为 (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 个特征图,每个特征图的大小都与图像相同。

Network

在卷积层之后,我们添加一个最大池化层来减少存储的参数数量,并使模型对变化更加稳健,如上所述。这将减少计算的参数数量。

Network
然后,这些特征图被连接在一起并扁平化。
Network
之后,我们使用一种称为 dropout 的方法来丢弃一部分参数,以避免过度拟合。最后,权重的最终形式将经过一个密集层进行分类,并进行反向传播。

卷积神经网络中的反向传播理论

反向传播是如何在这里工作的?我们希望优化这里最佳的内核值,因此它们是我们的权重。最终,我们希望分类器能够弄清楚像素值、内核和类别之间的关系。因此,我们有一个非常长的扁平化数组,它由被池化和激活的像素与初始权重(内核元素)卷积后的元素组成。我们更新这些权重,以便回答“我应该应用哪些内核来区分猫和狗的照片?”的问题。训练 CNN 的目的是找出最佳内核,这些内核是通过反向传播来找到的。在 CNN 出现之前,人们会尝试在图像上使用许多过滤器来自己提取特征,然而,大多数通用过滤器(如上面所见,例如 Prewitt 或 Sobel)并不一定适用于所有图像,因为即使是在同一个数据集中,图像也可能非常不同。这就是为什么 CNN 比传统的图像处理技术性能更好的原因。

当我们使用卷积神经网络时,在存储方面有几个优势。

参数共享

在卷积神经网络中,我们使用相同的过滤器对所有像素、所有通道和所有图像进行卷积,这比存储参数更有效,这比使用密集神经网络遍历图像要高效得多。这被称为“权重绑定”,这些权重被称为“绑定权重”。这在自编码器中也能看到。

稀疏交互

在密集连接的神经网络中,我们一次性输入整个数据块——由于图像有数百或数千个像素,这非常繁重——而在卷积网络中,我们使用更小的内核来提取特征。这被称为稀疏交互,它有助于我们使用更少的内存。

< > 在 GitHub 上更新