一、卷积神经网络简介
卷积神经网络(Convolutional Neural Network, CNN)是一种深度学习模型,尤其擅长处理图像和视频等高维度的数据。CNN 通过模仿人类视觉系统的工作方式,自动学习数据中的空间层次结构,使得它在计算机视觉任务中表现出色,如图像分类、目标检测等。
与传统的神经网络不同,CNN 通过引入卷积层和池化层,有效地减少了参数数量并提升了计算效率。卷积层使用可学习的过滤器(Filter)扫描输入数据,提取特征,而池化层则通过下采样减少数据维度,进一步压缩信息。这种层次化的特征提取方式,使得 CNN 能够从低层次的边缘和纹理,一直到高层次的复杂对象,逐步构建对图像的理解。
自从 LeCun 等人在 1998 年提出的 LeNet-5 被用于手写数字识别以来,CNN 已经在多个领域取得了突破性进展。在医学图像诊断到自动驾驶,都有不错的表现力和泛化能力。
上图分解说明了一个图片分类模型的模块功能,一张猫猫图片从被丢给模型,到模型判别出这是一张猫猫的图片,中间有多少个环节?并非输入照片后,模型就能输出“这一一只猫咪”。
二、训练大致环节
2.1 训练前的数据处理
输入层是 CNN 的起点,接收原始数据并准备进行处理。对于图像数据,输入层通常是一个三维的矩阵,包含高度、宽度和通道数(如 RGB 图像有三个通道:彩色图像的每个像素都可以描述为红色(red)、绿色(green)、蓝色(blue)的组合,这 3 种颜色就称为图像的 3 个色彩通道。这种颜色描述方式称为 RGB 色彩模型,常用于在屏幕上显示颜色。)
将代表图像的三维张量输入到网络里之前,需要先将它“拉平”,对于一张尺寸为100*100像素的图像,张量有 100 × 100 × 3 个数字,所以一张图像是由100×100×3 个数字所组成的,每个数值是某一个像素在某一个通道下的颜色强度。把这些数字排成一排就是一个巨大的向量。这个很长的向量就是特征向量,我们是把它丢给模型去处理。(在输入之前记得要把所有图像都调成一样的尺寸)。
2.2 模型训练
按神经网络最原始的定义,特征向量输入进神经网络模型,每一个神经元需要对输入向量的每一个值计算权重,当输入的向量长度是 100 × 100 × 3,且第 1 层有 1000 个神经元时,第 1 层的权重就需要 1000 × 100 × 100 × 3 1000×100×100×3 1000×100×100×3 = 3 × 1 0 7 3 ×10^7 3×107个权重,这是一个非常大的数目。
更多的参数为模型带来了更好的弹性和更强的能力,但也增加了过拟合的风险。为了避免过拟合,在做图像识别的时候,并不一定需要全连接,即不需要每个神经元跟输入的每个维度的数值都有一个权重。
2.3 模型输出
模型的目标是分类,因此可将不同的分类结果表示成不同的独热向量 y ′ y′ y′。在这个独热向量里面,类别对应的值为 1,其余类别对应的值为 0。例如,我们规定向量中的某些维度代表狗、猫、树等分类结果,那么若分类结果为猫,则猫所对应的维度的数值就是 1,其他东西所对应的维度的数值就是 0。
独热向量 y′ 的长度决定了模型可以识别出多少不同种类的东西。如果向量的长度是 5,代表模型可以识别出 5 种不同的东西。如果希望图像识别系统可以识别上万种目标,标签就会是维度上万的独热向量。
输出层是 CNN 的最后一层,输出预测结果。在训练过程中,输出层会计算损失函数(如交叉熵损失),用以评估模型的预测结果与真实标签之间的差距,并指导模型参数的更新。
三、神经网络优化策略——卷积层(convolutional layer)
全连接神经网络的神经元和参数往往很多,更多的参数为模型带来了更好的弹性和更强的能力,但也增加了过拟合的风险。为了避免过拟合,我们可以用一些方法来简化全连接网络,即不需要每个神经元跟输入的每个维度的数值都有一个权重,减少参数数量,这样就能降低弹性。这个策略就是卷积层,卷积层主要基于两种思想方法:
(1)引入感受野,让神经元只关注一个区域而不是整张图片,这减少了参数的数量;
(2)让多个神经元共享参数。参数共享意味着在同一张图的所有感受野上使用相同的滤波器参数。这与全连接层不同,在全连接层中每个输入和每个输出都有独立的权重。
而感受野加上参数共享就是卷积层(convolutional layer),用到卷积层的网络就叫卷积神经网络。
3.1 用感受野(Receptive field)识别关键特征
检测目标也许并不需要整张图象,人在判断一个物体的时候,往往也是抓最重要的特征。看到这些特征以后,就会直觉地看到了某种物体比如我们识别一只鸟,只要看到鸟嘴、鸟的眼睛、鸟的翅膀、鸟脚,这些局部就能判断检测对象是一只鸟了;人脸识别也是这样,通过五官这几个重要特征就可以把不同的人区别开来了。对一个图像识别的类神经网络里面的神经元而言,它要做的就是检测图像里面有没有出现一些特别重要的模式(pattern),这些模式是代表了某种物体的。
由此想法得到一个简化神经网络的思路:使用感受野
在全连接神经网络里,神经元要关注的内容覆盖整张图像,而使用感受野之后,相当于给神经元规定了它关注的范围,每个神经元都只关心自己的感受野里面发生的事情就好了。而感受野指的是网络中某个神经元在输入图像上所覆盖的区域。可以理解为这个神经元能感知到多少输入信息。感受野大小的变化通常由卷积核的尺寸、步长、填充方式、以及网络层数决定。
上图中蓝色的神经元的关注范围就是红色正方体框的感受野。这个感受野里面有3 × 3 × 3 个数值。对蓝色的神经元,它只需要关心这个小范围,不需要在意整张图像里面有什么东西。这个神经元会把 3 × 3 × 3 的数值“拉直”变成一个长度是 3 × 3 × 3=27 维的向量,再把这 27 维的向量作为神经元的输入,这个神经元会给 27 维的向量的每个维度一个权重,所以这个神经元有 3 × 3 × 3 = 27 3 × 3 × 3 = 27 3×3×3=27个权重,再加上偏置(bias)得到输出。这个输出再送给下一层的神经元当作输入。
一般同一个感受野会有一组神经元去守备这个范围,比如 64 个或者是 128 个神经元去守备一个感受野的范围。下图中左上角的感受野由两个蓝色的神经元守备。
感受野彼此之间可以是重叠的,比如绿色的神经元的感受野跟蓝色的、黄色的神经元都有一些重叠的空间。
3.1.2 感受野的设计
感受野完全可以根据对问题的理解来设计,它的大小尺寸、形状、通道、移动步幅都可以人为设计。模式有的比较小,有的比较大。有的模式也许在 3 × 3 的范围内就可以被检测出来,有的模式也许要 11 × 11 的范围才能被检测出来;感受野不仅可以是正方形的,也可以是长方形的;感受野可以是 RGB 三个通道都考虑,还有些模式只在红色或蓝色的通道会出现,所以有些神经元的感受野只设计在一个通道上。
-
卷积核大小
一个感受野的高度、宽度和深度,我们不用看它的深度,因为它的深度就等于通道数,而高跟宽合起来叫做核大小。在图像识别里面,一般核大小不会设太大,3 × 3 的核大小就足够了,7 × 7、9 × 9算是蛮大的核大小。常见的感受野设定方式就是核大小为 3 × 3 -
步幅(stride)
把左上角的感受野往右移一个步幅,就制造出一个新的守备范围,即新的感受野。移动的量称为步幅(stride),上图中步幅就等于 2。步幅是一个超参数,需要人为调整。因为希望感受野跟感受野之间是有重叠的,步幅往往不会设太大,一般设为 1 或 2。
如果感受野完全没有重叠,如果有一个模式正好出现在两个感受野的交界上面,就没有任何神经元去检测它,这个模式可能会丢失,所以希望感受野彼此之间有高度的重叠。
- 补充(padding)
当感受野超出了图像的范围时,就做填充(padding),填充就是补值,一般使用零填充(zero padding),超出范围就补 0,如果感受野有一部分超出图像的范围之外,就当做那个里面的值都是 0。也有别的补值的方法,比如补整张图像里面所有值的平均值或者把边界的这些数字拿出来补没有值的地方。
3.2 滤波器(Filters/Kernels)
滤波器(也叫卷积核)基于的是参数共享的思想降低神经网络弹性:对神经元的权重做限制,本来在学习的时候,每个神经元可以各自有不同的参数,它们可以学出相同的参数,也可以有不一样的参数。但是加入参数共享以后,某一些神经元无论如何参数都要一模一样的,这又增加了对神经元参数的限制。
3.2.1 参数共享(parameter sharing)
所谓参数共享就是两个神经元的权重完全是一样的。下面这幅图中,上面的神经元跟下面神经元守备的感受野是不一样的,但是它们的参数是相同的。而它们的输出不会永远都是一样的,因为它们的输入是不一样的。上面神经元的输入是 x1, x2, · · · · · · ,下面神经元的输入是 x′1, x′2, · · · · · ·
上面神经元输出为: σ ( w 1 x 1 + w 2 x 2 + ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ + 1 ) σ (w_1x_1 + w_2x_2 + · · · · · · + 1) σ(w1x1+w2x2+⋅⋅⋅⋅⋅⋅+1)
下面神经元的输出为: σ ( w 1 x 1 ′ + w 2 x 2 ′ + ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ + 1 ) σ (w_1x^′_1 + w_2x^′_2 + · · · · · · + 1) σ(w1x1′+w2x2′+⋅⋅⋅⋅⋅⋅+1)
上文提到每个感受野都有一组神经元在负责守备,比如 64 个神经元,它们彼此之间可以共享参数。使用一样的颜色代表这两个神经元共享一样的参数,所以每个感受野都只有一组参数,就是上面感受野的第 1 个神经元会跟下面感受野的第 1 个神经元共用参数,上面感受野的第 2 个神经元跟下面感受野的第 2 个神经元共用参数 · · · · · · 所以每个感受野都只有一组参数而已,这些参数称为滤波器(filter)。而神经元共享权重其实就是用滤波器扫过一张图像,这个过程就是卷积。
3.2.2 滤波器的卷积操作
滤波器是一组小的、可学习的权重矩阵,用于扫描图像并提取特征。每个滤波器都专注于检测某种特定的模式,如边缘、纹理或更复杂的结构。滤波器在输入数据上进行卷积操作,即逐点乘积并累加,形成一个特征图。这个过程帮助神经网络在不同位置上提取相同类型的特征。
卷积层里面有很多滤波器,这些滤波器的大小是 3 × 3 × 通道。如果图像是彩色的,它有 RGB 三个通道。如果是黑白的图像,它的通道就等于 1。一个卷积层里面就是有一排的滤波器,每个滤波器都是一个 3 × 3 × 通道,其作用是要去图像里面检测某个模式。这些模式要在 3 × 3 × 通道,这个小的范围内,它才能够被这些滤波器检测出来。举个例子,假设通道为 1,也就是图像是黑白的。
滤波器里面的数值其实是未知的,它是可以通过学习找出来的。假设这些滤波器里面的数值已经找出来了,如图 4.19 所示。如图 4.20 所示,这是一个 6 × 6 的大小的图像。先把滤波器放在图像的左上角,接着把滤波器里面所有的 9 个值跟左上角这个范围内的 9 个值对应相乘再相加,也就是做内积,结果是 3。接下来设置好步幅,然后把滤波器往右移或往下移,重复几次,可得到模式检测的结果,图 4.20 中的步幅为 1。这是第 1 个滤波器。
接下来到第 2 个滤波器,它用来检测图像 3 × 3 范围内中间一列都为 1 的模式。把第 2 个滤波器先从左上角开始扫起,得到一个数值,往右移一个步幅,再得到一个数值再往右移一个步幅,再得到一个数值。重复同样的操作,直到把整张图像都扫完,就得到另外一组数值。每个滤波器都会给我们一组数字,红色的滤波器给我们一组数字,蓝色的滤波器给我们另外一组数字。如果有 64 个滤波器,就可以得到 64 组的数字。这组数字称为特征映射(feature map)。每个滤波器都做这样重复的过程。当一张图像通过一个滤波器的时候,就会产生一个特征映射,假设卷积层里面有 64 个滤波器,产生的特征映射就有 64 组数字。在上述例子中每一组是 4 × 4,即第 1 个滤波器产生 4 × 4 个数字,第2 个滤波器也产生 4 × 4 个数字,第 3 个也产生 4 × 4 个数字,64 个滤波器都产生 4 × 4 个数字。特征映射可以看成是另外一张新的图像,只是这个图像的通道不是 RGB 3 个通道,有64 个通道,每个通道就对应到一个滤波器。本来一张图像有 3 个通道,通过一个卷积变成一张新的有 64 个通道图像。
3.3 汇聚(Pooling)
3. 激活函数层(Activation Layer)
- 激活函数层通常紧跟在卷积层之后,增加网络的非线性能力。常用的激活函数包括 ReLU(Rectified Linear Unit)、Sigmoid 和 Tanh 等。
- ReLU (Rectified Linear Unit):
- ReLU 是最常用的激活函数,它将所有负值变为零,保持正值不变。这样可以加快模型的收敛速度,并减少梯度消失问题。
- Leaky ReLU:
- 类似于 ReLU,但在负值区域有一个很小的斜率,以保留一些负值信息,从而改善训练效果。
4. 池化层(Pooling Layer)
- 池化层用于减少特征图的尺寸,同时保留重要的特征,降低计算量和模型的复杂性。池化层通过下采样操作缩小特征图。
- 最大池化(Max Pooling):
- 选择池化窗口内的最大值作为输出,保留最强的特征响应,通常用于捕捉显著的特征。
- 平均池化(Average Pooling):
- 计算池化窗口内所有值的平均值,更多用于特征的平滑处理。
- 步长和池化窗口:
- 池化窗口的大小和步长决定了输出特征图的尺寸。较大的池化窗口或步长会进一步减少输出尺寸。
5. 平铺层(Flattening Layer)
- 平铺层将卷积和池化后的多维特征图展开为一维向量,以便传递给全连接层。
- 这个过程不会对数据进行任何计算,只是将多维数组转换为一维数组,以连接卷积部分和全连接部分。
6. 全连接层(Fully Connected Layer)
- 全连接层将前面提取到的特征综合起来,进行分类或回归等任务。每一个神经元都与上一层的所有输出连接,类似于传统神经网络中的连接方式。
- 权重矩阵:
- 全连接层包含大量参数(权重和偏置),它们用于将输入特征映射到输出类别。
- 输出层:
- 通常,输出层会使用 Softmax 函数来进行多分类,将网络输出转换为概率分布;或使用 Sigmoid 函数进行二分类。
7. 输出层(Output Layer)
- 输出层是 CNN 的最后一层,输出预测结果。对于分类问题,输出层的神经元数量等于类别数量。
- 损失函数:
- 在训练过程中,输出层会计算损失函数(如交叉熵损失),用以评估模型的预测结果与真实标签之间的差距,并指导模型参数的更新。
- 在训练过程中,输出层会计算损失函数(如交叉熵损失),用以评估模型的预测结果与真实标签之间的差距,并指导模型参数的更新。
总结
卷积神经网络的各个构建模块相互协作,形成了一个高效的特征提取和学习框架。卷积层负责初步的特征提取,激活函数增加非线性,池化层减少数据维度,全连接层进行特征整合并最终输出结果。通过这些模块的堆叠和组合,CNN 可以逐层构建从低级到高级的特征表示,最终实现对数据的高效分类或其他任务。