YOLO入门教程(番外):卷积神经网络—从全连接层到卷积
在前面的章节中,我们遇到过图像数据。 这种数据的每个样本都由一个二维像素网格组成, 每个像素可能是一个或者多个数值,取决于是黑白还是彩色图像。
到目前为止,我们处理这类结构丰富的数据的方式还不够有效。
我们仅仅通过将图像数据展平成一维向量而忽略了每个图像的空间结构信息,再将数据送入一个全连接的多层感知机中。
因为这些网络特征元素的顺序是不变的,因此最优的结果是利用先验知识,即利用相近像素之间的相互关联性,从图像数据中学习得到有效的模型。
我给我自己再解释一下这句话
上面这段话解释了早期用全连接网络(MLP)处理图像的一个核心缺陷以及解决方案的指导思想。
1. 指出问题;2. 提出解决方案的理念。
第一部分:问题所在
“我们仅仅通过将图像数据展平成一维向量而忽略了每个图像的空间结构信息,再将数据送入一个全连接的多层感知机中。”
这部分描述了一种简单但低效的图像处理方法及其弊端。
-
“将图像数据展平成一维向量”:
- 一张图片在计算机中是一个三维数组(高度 Height × 宽度 Width × 通道 Channel,例如 28x28x1 的灰度图)。
- 为了把它输入到一个标准的全连接层(它要求输入是一个一维向量),我们必须将这个二维或三维的像素矩阵“拉平”,变成一个很长的、一维的列表(例如 28*28=784 个数字)。
- 示意图:
[[1, 2, 3], ---展平---> [1, 2, 3, 4, 5, 6, 7, 8, 9][4, 5, 6],[7, 8, 9]]
-
“忽略了每个图像的空间结构信息”:
- 这是关键弊端。图像的本质在于其空间结构——相邻的像素在语义上是有关联的。比如,眼睛的像素通常紧挨着鼻子和眉毛的像素,共同组成一张脸;一个笔画的像素连在一起才能形成文字。
- 当你把图像展平后,你彻底破坏了像素之间的相对位置关系。对于网络来说,原来在左上角的第一个像素和它正下方的第785个像素,在几何上没有任何区别。它们都只是输入列表中的一个独立的、孤立的数字。
- 这就好比把一幅拼图打乱成一个个碎片,然后不告诉机器任何拼图规则,就让机器去理解整幅画的内容。这几乎是不可能的任务。
-
“送入一个全连接的多层感知机中”:
- 全连接层(Fully Connected Layer)的每个神经元都与上一层的所有神经元相连。
- 处理这种展平后的数据时,网络需要学习所有像素点之间可能存在的两两关系,这会产生巨大的参数量(例如,一个有1000个神经元的隐藏层连接784个输入,需要学习 784 * 1000 = 784,000 个权重!),并且训练效率极低,非常容易过拟合。
第二部分:解决方案的理念
“因为这些网络特征元素的顺序是不变的,因此最优的结果是利用先验知识,即利用相近像素之间的相互关联性,从图像数据中学习得到有效的模型。”
这部分指出了上述方法的根本问题(顺序不变性)并提出了解决思路——引入“先验知识”。
-
“因为这些网络特征元素的顺序是不变的”:
- 这里的“网络”指的是全连接网络(MLP)。
- “顺序不变”是指:全连接网络本身对输入特征的顺序没有内在的感知能力。如果你把展平后的向量中的像素顺序随机打乱,对于全连接网络来说,这只是一个新的、不同的输入样本,它需要重新学习其中的模式。它无法理解“打乱顺序”这个操作,因为它没有关于“空间邻近”的概念。
- 但图像的像素顺序是极其重要的!打乱顺序的图片对人来说也无法识别。
-
“因此最优的结果是利用先验知识”:
- “先验知识(Prior Knowledge)”是指我们人类已经掌握的、关于图像的本质规律,不需要从数据中学习。这里特指:图像中相邻的像素在语义上通常是高度相关的。
- 既然全连接网络无法自己学会这个规律,那么最聪明的做法就是直接把这条规律(先验知识)设计到网络结构中去,让网络从一开始就遵循这个规律来学习。
-
“即利用相近像素之间的相互关联性”:
- 这正是卷积神经网络(CNN)的核心思想!
- CNN通过两种核心操作来嵌入这种先验知识:
- 卷积层(Convolutional Layer):使用一个小的滤波器( kernel,如3x3)在图像上滑动。这个操作强制网络只关注一个局部区域(相邻像素),从而学习局部特征(如边缘、角点)。
- 池化层(Pooling Layer):对局部区域进行下采样,使得网络对微小的位置变化不再敏感,更加关注特征的存在而非其精确位置。
总结
这就是从全连接网络(MLP) 转向卷积神经网络(CNN) 的根本原因:
- 问题:将图像展平后送入全连接网络,会破坏图像固有的空间结构信息,导致网络参数多、效率低、难以训练。
- 原因:全连接网络是**“顺序盲”**的,无法有效利用像素间的空间邻近关系。
- 解决方案:将“相邻像素关联性强”这一先验知识融入到网络设计中,从而诞生了CNN。CNN通过局部连接和权值共享等机制,极大地提升了图像处理的效率和效果。
可以说,正是因为这个核心洞察,才催生了现代深度学习在计算机视觉领域的巨大成功。
卷积神经网络(convolutional neural network,CNN)是一类强大的、为处理图像数据而设计的神经网络。
基于卷积神经网络架构的模型在计算机视觉领域中已经占主导地位,当今几乎所有的图像识别、目标检测或语义分割相关的学术竞赛和商业应用都以这种方法为基础。
现代卷积神经网络的设计得益于生物学、群论和一系列的补充实验。
卷积神经网络需要的参数少于全连接架构的网络,而且卷积也很容易用GPU并行计算。
卷积操作之所以能高效利用GPU并行计算,是因为其核心的滑动窗口计算模式(如同使用同一个滤镜扫描图像的每个位置)能够被分解为海量完全相同的乘加任务,这些任务彼此独立且处理的数据在内存中连续分布,完美契合了GPU拥有的数千个计算核心通过SIMT(单指令多线程)架构同时执行相同指令的能力,并可调用高度优化的底层库(如cuDNN)来极致压榨硬件性能。
因此卷积神经网络除了能够高效地采样从而获得精确的模型,还能够高效地计算。
久而久之,从业人员越来越多地使用卷积神经网络。即使在通常使用循环神经网络的一维序列结构任务上(例如音频、文本和时间序列分析),卷积神经网络也越来越受欢迎。 通过对卷积神经网络一些巧妙的调整,也使它们在图结构数据和推荐系统中发挥作用。
下面介绍一下构成所有卷积网络主干的基本元素。 这包括卷积层本身、填充(padding)和步幅(stride)的基本细节、用于在相邻区域汇聚信息的汇聚层(pooling)、在每一层中多通道(channel)的使用,以及有关现代卷积网络架构的仔细讨论。
1. 从全连接层到卷积
1.1. 不变性
想象一下,假设我们想从一张图片中找到某个物体。
合理的假设是:无论哪种方法找到这个物体,都应该和物体的位置无关。
理想情况下,我们的系统应该能够利用常识:猪通常不在天上飞,飞机通常不在水里游泳。
但是,如果一只猪出现在图片顶部,我们还是应该认出它。 我们可以从儿童游戏”沃尔多在哪里”( 图6.1.1)中得到灵感: 在这个游戏中包含了许多充斥着活动的混乱场景,而沃尔多通常潜伏在一些不太可能的位置,读者的目标就是找出他。
尽管沃尔多的装扮很有特点,但是在眼花缭乱的场景中找到他也如大海捞针。
然而沃尔多的样子并不取决于他潜藏的地方,因此我们可以使用一个“沃尔多检测器”扫描图像。 该检测器将图像分割成多个区域,并为每个区域包含沃尔多的可能性打分。 卷积神经网络正是将空间不变性(spatial invariance)的这一概念系统化,从而基于这个模型使用较少的参数来学习有用的表示。
现在,我们将上述想法总结一下,从而帮助我们设计适合于计算机视觉的神经网络架构。
-
平移不变性(translation invariance):不管检测对象出现在图像中的哪个位置,神经网络的前面几层应该对相同的图像区域具有相似的反应,即为“平移不变性”。
-
局部性(locality):神经网络的前面几层应该只探索输入图像中的局部区域,而不过度在意图像中相隔较远区域的关系,这就是“局部性”原则。最终,可以聚合这些局部特征,以在整个图像级别进行预测。
让我们看看这些原则是如何转化为数学表示的。
1.2. 多层感知机的限制
想象一下,你要在一张大照片上找“猫耳朵”。
1. 最“笨”的方法(全连接层的方法):
- 你雇了成千上万个小助理,每个助理只负责看照片上一个固定的、极小的小区域(比如一个像素点)。
- 然后,你又雇了另一个成千上万的小经理,每个经理负责在照片上一个固定的位置告诉你那里有没有猫耳朵。
- 最要命的是,每个小经理在做决定时,都会把每个小助理看到的像素点都问一遍,而且每个经理都有一本独一无二的、超级厚的说明书,上面写着:“如果左上角第一个像素点是黑的,那么我该加几分?如果是白的,又该减几分?…”
这段话说的就是这种“笨”方法:
四阶权重张量 W
就是那成千上万本独一无二的、超级厚的说明书。它为照片上每一个可能的位置(i, j)都准备了一套独立的、复杂的规则,来处理每一个输入像素(k, l)。从W到V的转换
只是换了一种记账方式,但本质没变:每个位置的经理([H]_{i,j}
)还是靠着自己那套独有的规则([V]_{i,j,a,b}
),去盘问它周围所有的像素点。
2. 这种方法为什么“笨”得离谱?
- 浪费到极致:猫耳朵无论在照片左上角还是右下角,它都长一样。但你的方法却为每个位置都重新发明了一套识别猫耳朵的规则。这需要海量的说明书(参数爆炸),而且训练起来慢得要死。
- 根本学不会:就算你花了巨大代价训练好了,如果一只猫的耳朵移动了几个像素,对于新位置的经理来说,这完全是一套没见过的像素组合,它就不认识了!这非常违反直觉。
3. 聪明的方法是什么?(卷积神经网络的方法)
- 你只需要一个通用的“猫耳朵探测镜”(卷积核)。
- 你拿着这个探测镜,从照片的左上角开始,滑动到右下角。无论滑到哪里,你都用同一把尺子、同一个标准去判断“这里是不是猫耳朵”。
- 这样,你只需要学会识别“猫耳朵”这一种模式就够了,不需要为每个位置都学一次。参数大大减少,而且无论猫耳朵在哪都能识别出来(平移不变性)。
这图片阐述了使用全连接层处理二维图像时,在数学形式上的复杂表达及其重大缺陷,从而为引入卷积神经网络(CNN)的“局部连接”和“权值共享”思想做了铺垫。
以下是逐部分的详细解释:
-
问题出发点:图片开头指出,输入
X
和隐藏层表示H
都是二维矩阵(如图像),它们天然具有空间结构。我们希望构建一个模型,其中每个隐藏神经元[H]_{i,j}
都能接收到所有输入像素的信息。 -
全连接层的复杂表达:为了实现“全连接”的概念,传统的权重矩阵不再适用。图片中将其替换为一个四阶权重张量
W
。这个张量的四个维度可以理解为:i, j
:指向输出隐藏层H
中的某个特定位置(i, j)
的神经元。k, l
:指向输入图像X
中的某个特定像素(k, l)
。- 因此,权重
[W]_{i,j,k,l}
的唯一作用就是专门连接输入像素(k,l)
和输出神经元(i,j)
。
公式
[H]_{i,j} = [U]_{i,j} + Σ_k Σ_l [W]_{i,j,k,l} [X]_{k,l}
描述的就是这个复杂的全连接过程。它为每一对输入-输出位置都分配了一个独立的权重参数。 -
关键的数学转换(重新索引):这是图片中最重要的一步。通过设
k = i + a
和l = j + b
,将求和下标从(k, l)
转换为(a, b)
。这里的(a, b)
可以理解为相对于中心点(i, j)
的偏移量。- 例如,
a=-1, b=-1
代表输入图像中位于(i, j)
左上方(i-1, j-1)
的像素。 - 转换后,权重张量也相应地变成了
[V]_{i,j,a,b}
。这个转换只是数学上的重新表述,参数数量完全没有变化。
- 例如,
-
转换后的物理意义:转换后的公式
[H]_{i,j} = [U]_{i,j} + Σ_a Σ_b [V]_{i,j,a,b} [X]_{i+a, j+b}
揭示了一个更清晰的视角:- 要计算输出特征图
H
在(i, j)
位置的值,做法是:以输入图像X
中对应的(i, j)
位置为中心,取出一个范围由(a, b)
决定的区域,然后用权重[V]_{i,j,a,b}
对这个区域进行加权求和。 - 这已经非常接近卷积的操作了!但还不是真正的卷积。
- 要计算输出特征图
-
由此暴露的核心缺陷:
- 参数爆炸:权重张量
V
的大小直接依赖于输入图像的大小(i, j)
和感知范围(a, b)
。对于一张不小的图片,参数数量会变得极其庞大,难以训练且极易过拟合。 - 未能利用“平移不变性”:对于不同位置
(i, j)
的神经元,模型使用了完全不同的一套权重[V]_{i,j,a,b}
。这意味着即使图像中的同一个图案(如猫耳朵)出现在不同位置,模型也需要分别学习如何识别它,这不仅是巨大的浪费,也违背了图像的基本特性。
- 参数爆炸:权重张量
总结来说,这张图片通过严谨的数学形式推导出了全连接网络处理图像时的真实模样,并清晰地暴露了其参数过多、效率低下的致命弱点。它由此引出了一个关键的改进思路:如果我们强制规定对于所有位置 (i, j)
,都使用同一套权重 [V]_{a,b}
(即权值共享),那么这个操作就变成了卷积,参数 [V]_{a,b}
就变成了卷积核(kernel/filter)。 这正是卷积神经网络成功的关键所在。
1.2.1. 平移不变性
图片内容解读
- 核心原则:平移不变性
开篇就点明了出发点:平移不变性。
- 通俗解释:这意味着如果图片里的目标物体(比如一只猫)移动了位置,那么识别出它的“特征”也应该相应地移动位置,但识别这个特征所用的“方法”或“工具”应该是不变的。
- 例子:一个用来检测“猫耳朵”的探测器,无论猫耳朵出现在图像的左上角还是右下角,都应该使用同一个探测器。不需要因为位置变化而使用不同的探测器。
- 全连接层的问题回顾
正如我们之前讨论的,如果用全连接层处理图像,会得到一个非常复杂的公式。它为输出特征图 H
的每一个位置 (i, j)
都配置了一组独立的权重 [V]_{i,j,a,b}
。
- 问题:这违背了平移不变性。猫耳朵在
(1,1)
位置时用一套权重,移动到(5,5)
位置时就得用另一套完全不同的权重,这既低效又不合理。
- 革命性的简化:权值共享
图片提出了解决方案:既然特征检测器不应该依赖于位置,那我们强制让它不依赖就好了!
这就是图中所说的:
“V和U实际上不依赖于(i,j)的值,即
[V]_i,j,a,b = [V]_a,b
。并且U是一个常数,比如u。”
-
[V]_i,j,a,b = [V]_a,b
的含义:- 之前,权重有四个维度
i, j, a, b
,因为它为每个输出位置(i, j)
都准备了一套独特的权重。 - 现在,我们砍掉了
i
和j
这两个维度。这意味着,对于输出特征图H
上的所有位置,我们都使用同一套权重[V]_a,b
。 - 这套固定的权重
[V]_a,b
就是卷积核(或叫滤波器)。a
和b
是卷积核内部的偏移索引。
- 之前,权重有四个维度
-
U
是一个常数u
的含义:U
代表偏置项。原来每个神经元可能有自己的偏置[U]_{i,j}
,现在我们也强制所有神经元使用同一个偏置u
。- 这进一步减少了参数,是另一个层面的“权值共享”。
- 得到卷积公式
将这些简化代入原公式,就得到了图中最重要的结论——卷积公式:
[H]i,j=u+∑a∑b[V]a,b[X]i+a,j+b [\mathbf{H}]_{i,j} = u + \sum_{a}\sum_{b}[\mathbf{V}]_{a,b}[\mathbf{X}]_{i+a,j+b} [H]i,j=u+a∑b∑[V]a,b[X]i+a,j+b
这个公式的直观理解:
要计算输出特征图 H
在位置 (i, j)
的值,你需要:
- 拿出一个叫做
[V]_a,b
的小模板(卷积核)。 - 把这个小模板扣在输入图像
X
上,以(i, j)
这个点为中心对齐。 - 将模板上的每个权重
[V]_a,b
与它覆盖到的图像像素[X]_{i+a, j+b}
相乘。 - 把所有乘积累加起来,最后再加上一个统一的偏置
u
。 - 得到的结果,就代表了“在
(i, j)
这个位置,用模板V
检测到的特征的强度”。
然后,你只需要滑动这个模板,让它扫过图像的每一个位置,就能得到完整的输出特征图 H
。这就是卷积操作。
总结与意义
这张图片描述的是深度学习中的一个“恍然大悟”的时刻:
-
从直觉到数学:将对图像的先验知识(平移不变性)通过数学约束(权值共享)形式化地融入到了模型结构中。
-
巨大的进步:
- 参数锐减:参数数量从可怕的四维张量
[V]_i,j,a,b
降到了二维的[V]_a,b
。原来需要学习数百万个参数,现在可能只需要学习一个3x3
(9个参数)的卷积核和一个偏置(1个参数)。 - 效率飙升:参数减少使得模型更易于训练,更不容易过拟合。
- 符合直觉:模型现在学会了“通用特征检测器”,无论特征出现在哪里,都能用同一把“尺子”去测量它。
- 参数锐减:参数数量从可怕的四维张量
一句话概括:这张图解释了,通过“权值共享”来实现“平移不变性”的理念,直接推导出了“卷积”操作,这是卷积神经网络高效且强大的根本原因之一。
1.2.2. 局部性
卷积神经网络(CNN)的第二个核心思想:局部性原则,展示了它如何与第一个思想(平移不变性)结合,最终形成卷积操作。
核心思想:局部性原则
图片开篇就点明了主题:局部性(Locality)。
- 通俗解释:这意味着要识别图像中某个点(比如
(i, j)
)的特征,你不需要去看离它非常遥远的像素。你只需要关注它周围那一小片区域就够了。 - 例子:要判断一个像素是不是猫耳朵的一部分,你只需要看它周围的像素(比如颜色、边缘)是否构成耳朵的形状。你完全不需要去看图片角落的猫尾巴来做出这个判断。猫尾巴的信息对于识别猫耳朵是无关的噪声。
从直觉到数学:限制感知范围
图片中的数学公式 (6.1.3) 就是将这个原则数学化的结果:
[H]i,j=u+∑a=−ΔΔ∑b=−ΔΔ[V]a,b[X]i+a,j+b [\mathbf{H}]_{i,j} = u + \sum_{a=-\Delta}^{\Delta}\sum_{b=-\Delta}^{\Delta}[\mathbf{V}]_{a,b}[\mathbf{X}]_{i+a,j+b} [H]i,j=u+a=−Δ∑Δb=−Δ∑Δ[V]a,b[X]i+a,j+b
这个公式相比之前我们得到的卷积公式,有一个关键的变化:求和符号有了上下限 ±Δ
。
Δ
是什么?:Δ
是一个超参数,你可以把它理解为卷积核的“半径”。它定义了“局部”的范围有多大。a
和b
的范围:a
和b
不再是从图像的一头加到另一头,而是被限制在[-Δ, Δ]
这个范围内。[V]_a,b = 0
:对于超出这个范围的偏移量,我们直接规定其权重为0。这意味着卷积核只在一个有限的 (2Δ+1
x2Δ+1
) 的窗口内有效,窗口之外的像素对当前计算毫无影响。
一个生动的比喻:
想象你是一个只通过一个小窥视孔看世界的神经元。这个窥视孔的大小是 (2Δ+1) x (2Δ+1)
。你只能看到你正前方这一小块区域的景象(局部性),并且无论把你放在世界的哪个角落,你都用同一套标准来理解你看到的东西(平移不变性)。卷积核 V
就是你大脑里那套固定的“理解模式”。
带来的巨大优势:参数量的急剧减少
图片非常明确地指出了这样做的好处:
- 之前(全连接层):一层网络可能需要数十亿个参数。因为每个神经元都要和所有输入像素连接。
- 现在(卷积层):一层通常只需要几百个参数。因为参数数量只取决于卷积核的大小(例如
Δ=1
对应3x3
核,共9个权重参数 + 1个偏置参数),而与原始图像的大小无关!
无论你输入的图片是 32x32
还是 4000x3000
,一个 3x3
的卷积核永远只有9个权重参数。这解决了全连接层的参数爆炸问题。
付出的代价与背后的哲学:归纳偏置
图片也客观地指出了这种设计的“代价”或特点:
- 特征现在是平移不变的:这是优点,我们之前讨论过。
- 每一层只包含局部信息:在网络的底层,每个神经元只能看到非常小的局部区域。高层神经元通过组合底层的局部信息,才能逐渐形成全局的、复杂的感知。这是一个由局部到全局的构建过程。
所有这些都依赖于一个叫做 “归纳偏置”(Inductive Bias) 的核心哲学概念。
- 什么是归纳偏置?:它不是数据中存在的偏见,而是我们预先置入模型中的、关于问题本质的“假设”或“偏好”。是我们教给模型的一条捷径。
- **CNN的归纳偏置是什么?**就是这两条:
- 平移不变性:特征的位置不重要。
- 局部性:特征可以由其邻近像素定义。
- 为什么重要?:当这种偏置与现实世界的情况相符时(比如处理自然图像),模型就能用极少的数据学到极其有效的特征,泛化能力非常强。
- 风险是什么?:如果这种偏置与现实不符,模型就会表现极差。例如,如果一张图片的标签完全依赖于两个相隔很远的像素的值(而这在自然图像中几乎不存在),CNN就会因为其局部性的设计而难以学习到这种关系。
总结
CNN的成功不是偶然的,而是通过巧妙地引入两条符合图像本质的先验知识(归纳偏置)来实现的:
- 平移不变性 (
[V]_i,j,a,b
->[V]_a,b
):用同一套模式扫描全图。 - 局部性原则 (
∑_a∑_b
->∑_{a=-Δ}^{Δ}∑_{b=-Δ}^{Δ}
):只看眼前的一小块地方。
这两条原则共同作用,将复杂的全连接操作简化成了高效的卷积操作,使得用少量参数处理大规模图像成为可能,奠定了现代计算机视觉发展的基础。
1.3. 卷积
这里从纯数学的角度,精确地定义了卷积(Convolution)操作,并澄清了深度学习中的一个重要概念:我们通常在CNN中使用的操作,严格来说是“互相关”(Cross-correlation),但习惯上仍称之为“卷积”。
- 核心公式解读:从连续到离散
图片给出了三个逐层递进的公式,阐述了卷积的数学定义。
a) 连续函数的卷积 (公式 6.1.4)
(f∗g)(x)=∫f(z)g(x−z)dz(f*g)(\mathbf{x})=\int f(\mathbf{z})g(\mathbf{x}-\mathbf{z})d\mathbf{z}(f∗g)(x)=∫f(z)g(x−z)dz
- 这是最一般的定义:适用于定义在连续空间(如一段音频信号、一张无限分辨率的图片)上的两个函数
f
和g
。 - 操作过程:可以理解为将一个函数(比如
g
)翻转并平移后,与另一个函数f
逐点相乘,再对所有这些乘积求和(积分)。 - 直观理解:
(f*g)(x)
的值度量了:当把g
翻转并移动到位置x
时,它与函数f
的重叠程度。这个定义在信号处理等领域有着深厚的物理意义。
b) 离散向量的卷积 (公式 6.1.5)
(f∗g)(i)=∑af(a)g(i−a)(f*g)(i)=\sum_{a}f(a)g(i-a)(f∗g)(i)=a∑f(a)g(i−a)
- 从连续到离散:当处理离散数据(比如一个一维序列、一个向量)时,积分符号
∫
就自然而然地替换为了求和符号Σ
。 - 操作过程:过程与连续情况类似。将一个核函数
g
翻转后,滑过另一个向量f
,在每个位置i
上,将翻转后的g
与f
的对应部分相乘后求和。
c) 二维张量的卷积 (公式 6.1.6)
(f∗g)(i,j)=∑a∑bf(a,b)g(i−a,j−b)(f*g)(i,j)=\sum_{a}\sum_{b}f(a,b)g(i-a,j-b)(f∗g)(i,j)=a∑b∑f(a,b)g(i−a,j−b)
- 扩展到图像:这是处理图像(二维张量)时最常用的形式。求和需要在两个维度(
a
和b
)上进行。 - 操作过程:将一个二维核(例如一个
3x3
的滤波器)进行二维翻转(即左右翻转后再上下翻转),然后滑过输入图像,在每个位置(i, j)
上执行乘加操作。
- 关键区别:卷积 vs. 互相关
这是图片最后一段话揭示的核心要点,也是深度学习实践中一个“美丽的误会”。
-
数学上的卷积:包含翻转操作。即核函数
g
的参数是(i-a, j-b)
,这意味着核被翻转了。- 例如:一个核
[a, b, c]
在卷积前会被翻转为[c, b, a]
。
- 例如:一个核
-
CNN中的“卷积”:在我们之前讨论的公式
[H]_{i,j} = u + Σ_a Σ_b [V]_{a,b} [X]_{i+a, j+b}
中,核V
的参数是(i+a, j+b)
。这里没有翻转!- 我们只是简单地将核(也叫滤波器)按原样滑过图像,进行乘加操作。
-
术语澄清:
- 这种不翻转的操作,在数学上更准确的名称是互相关(Cross-correlation)。
- 然而,在整个深度学习领域,大家习惯性地将这种互相关操作称为“卷积”。
-
为什么可以混用?
- 效果等价:对于神经网络来说,核
[V]_{a,b}
的参数是通过训练学习得到的。一个翻转的核[V]_{-a,-b}
本身也是一个可以通过训练得到的参数集合。因此,无论操作前是否翻转,网络都能学习到本质上完全相同的特征。学习过程会自动适应这种差异。 - 实现简便:不翻转的实现更直接、更直观,代码写起来也更简单。
- 惯例形成:由于上述原因,“卷积层”实际上执行“互相关操作”就成了一个大家心照不宣的惯例。
- 效果等价:对于神经网络来说,核
总结
这张图片完成了从直观理念到数学定义的升华:
- 数学定义:它严格定义了数学中的卷积运算,其核心是翻转+滑动窗口+乘加。
- 术语澄清:它指出,深度学习CNN中的“卷积”操作,其数学实质是互相关(没有翻转的卷积)。
- 为何通用:它解释了这种术语上的不一致并无实际影响,因为可学习的核参数使得翻转变得无关紧要。网络总能学到所需的特征检测器。
因此,当你在深度学习框架(如PyTorch, TensorFlow)中调用 Conv2d
层时,你实际上是在进行互相关计算,但出于历史和实用原因,我们所有人都称之为“卷积”。理解这两者之间的细微差别,有助于更深入地理解论文中的数学公式和实际代码实现之间的联系。
生活化一下
想象一下,你要在一张复杂的图片上找一个特定的图案,比如一只猫的眼睛。
你有两个工具:
- 一张大照片(这就是输入图像
f
)。 - 一个小巧的“猫眼睛透明模板”(这就是卷积核
g
)。这个模板上画着一只理想化的猫眼睛。
现在有两种方法来使用这个模板:
方法一:数学教科书上的标准方法(真正的“卷积”)
- 翻转模板:在开始找之前,你先把这个透明模板水平翻转一下,再垂直翻转一下。就像是把它翻了个面,印迹都反了。
- 滑动比对:然后,你把这个翻转后的模板扣在照片的左上角。
- 计算匹配度:你透过模板看下面的照片像素,将模板上每个点的权重(比如,瞳孔位置应该是黑色,权重高)与它正下方的照片像素颜色相乘,最后把所有乘积加起来,得到一个分数。这个分数代表了“在这个位置,照片和翻转后的模板有多像”。
- 移动重复:你把模板向右移动一点,再算一个分数……直到滑完整张照片。
为什么这么做? 在数学和信号处理领域,这个“翻转”的步骤有它深刻的意义,能完美解决一些数学问题(比如系统的响应)。但对我们的直觉来说,它显得有点绕。
简单说:真卷积 = 先把模板翻个面,再滑动着去匹配。
方法二:深度学习中的常用方法(实际是“互相关”)
- 直接使用:你不需要翻转模板。就直接拿着那个画着猫眼睛的透明模板。
- 滑动比对:直接把它扣在照片的左上角。
- 计算匹配度:同样,将模板每个点的权重与它正下方的照片像素相乘并求和,得到一个分数。这个分数直接代表了“在这个位置,照片和我的猫眼睛模板直接有多像”。
- 移动重复:滑动模板,计算整个照片。
这个方法直观得多!我们就是想用原样的模板去图片里找一模一样的东西。
简单说:互相关 = 直接拿着原样的模板,滑动着去匹配。
核心矛盾与解答
现在你会发现图和文字在讨论一个问题:
- 数学定义(图中公式)用的是 方法一 (带翻转的,真卷积)。
- 我们之前用的CNN公式 是 方法二 (不带翻转的,互相关)。
那么,到底谁错了?
谁都没错,而且这根本不重要!
这就是图片最后一段话的意思。原因如下:
你的“猫眼睛模板”不是手工设计好的,而是神经网络自己学出来的。
- 想象一下,神经网络一开始拿到的是一个随机的、乱七八糟的模板。
- 在训练过程中,它通过数据慢慢调整这个模板,让它变得越来越像一只“猫眼睛”。
- 最终,它学出的可能是一个 “正向的猫眼睛模板”,也可能是一个 “翻转后的猫眼睛模板”。
- 这完全没关系!因为网络在学习过程中,会自动适应并学会它需要的任何模式。
- 如果它需要一个翻转的核才能有效,它就会学出一个翻转的核。本质上,方法一和方法二是等价的。
一句话总结
数学家们说“卷积”时,他们心里想的是那个带“翻转”的标准操作。但深度学习领域的人们嘴上说“卷积”,实际干的是“互相关”的活儿。不过没关系,因为我们的卷积核是自学成才的,它自己会把翻不翻转的事儿搞定,所以大家就心照不宣地这么叫下来了。
所以,你以后在看到“卷积层”时,就把它理解成**“拿一个局部小模板在图像上滑动匹配”**就行了,这是最核心、最直观的思想。
1.4. “沃尔多在哪里”回顾
回到上面的“沃尔多在哪里”游戏,让我们看看它到底是什么样子。卷积层根据滤波器V选取给定大小的窗口,并加权处理图片,如 图6.1.2中所示。
我们的目标是学习一个模型,以便探测出在“沃尔多”最可能出现的地方。
1.4.1. 通道
我们之前“在黑白世界里找特征”的游戏,现在升级到彩色的现实世界。它主要说了三件事:
- 图像不是一张薄纸,而是一个“三层夹心饼干”
之前的例子为了简单,我们把图像当成灰度图(只有明暗,没有颜色)。但现实世界的图像是彩色的!
- 三维张量:你可以把一张彩色图片想象成一个三层夹心饼干。
- 第一层:红色通道 -> 只记录图片每个点红色的强度。
- 第二层:绿色通道 -> 只记录每个点绿色的强度。
- 第三层:蓝色通道 -> 只记录每个点蓝色的强度。
- 这三个层叠在一起,才构成了我们看到的彩色世界。所以,图片在电脑里不是一个二维矩阵,而是一个三维立方体, dimensions是
[高度, 宽度, 通道数]
。
- 卷积核也要升级成“三色眼镜”
既然输入变成了三层,我们之前那个小小的、单一的卷积核(模板)也不够用了。
- 新卷积核:现在,我们的每一个卷积核也要变成三层的,像一个三色小立方体。它的深度必须和输入图片的通道数匹配(这里是3)。
- 如何工作:这个三层的卷积核会同时对准输入图片的RGB三个通道。它在每个位置
(i, j)
的计算是:- 分别计算:让卷积核的红色层和图片的红色通道做乘加操作,绿色对绿色,蓝色对蓝色。得到三个数字。
- 合并结果:把这三个数字加在一起,再加上一个偏置值
b
,最终得到一个总和。 - 这个总和,就是输出特征图在
(i, j)
这个位置的值。
一个绝佳的比喻:
想象你戴上了一副神奇的三色眼镜(这就是一个卷积核)去扫描这幅彩色画。
- 你这副眼镜的红色镜片只让你看到红色的信息,绿色镜片只看到绿色的信息,蓝色镜片只看到蓝色的信息。
- 你的大脑(卷积操作)会把三只眼睛看到的信息融合起来,形成一个整体的判断(输出结果):“哦,这里看起来像一条黄色的边!” (因为红色和绿色都很强,蓝色很弱)。
- 从“一个特征”到“一本特征百科全书”
通常,我们不会只用一个卷积核。我们会同时用很多个(比如64个)不同的卷积核。
- 每个卷积核学一种特征:一个核可能专门负责寻找“红色的水平边缘”,另一个可能专门寻找“蓝色的圆形”,第三个可能专门寻找“皮肤纹理”。
- 输出也是一个“夹心饼干”:这些卷积核产生的输出,也会被堆叠起来。每一个核的输出结果变成新“夹心饼干”中的一层(一个通道)。
- 这个新的、多层的输出,就叫特征映射(Feature Map)。它的每一个通道,都像是从图像中提取出的一种“基础特征”清单。
所以,卷积层的作用就是:用一堆不同的“三色眼镜”(卷积核),从原始图像的像素中,提炼出一本厚厚的“特征百科全书”(特征映射),供后面的网络层继续阅读和理解。
图中最后提出的问题是什么意思?
文章最后说“仍有许多问题”,这其实是引出了后续章节要讨论的内容,也点明了设计CNN时的关键决策:
-
“图像中是否到处都有存在沃尔多的可能?” -> 感受野问题
- 比喻:一个只盯着3x3像素小窗口的卷积核,怎么能理解一整只大象?这就需要通过堆叠多个卷积层,让后面的层能够基于前面层的输出,间接地“看到”更大的区域(扩大感受野)。
-
“如何有效地计算输出层?” -> 计算效率与架构创新
- 比喻:用这么大的卷积核在这么大的图像上滑动,计算量太大怎么办?这就引出了 “步长”(Stride) 和 “池化”(Pooling) 的概念,通过降采样来减少计算量。
-
“如何选择适当的激活函数?” -> 引入非线性
- 比喻:如果只是简单的乘加,那么多层网络叠在一起也等价于一个巨型的线性函数,无法学习复杂模式。因此必须在卷积后加入 ReLU 等激活函数,给系统注入“非线性”的判断力。
-
“如何做出合理的网络设计选择?” -> 网络架构设计
- 比喻:到底用几个卷积层?每层用多少个卷积核?这就是CNN模型设计(如VGG, ResNet等)的核心艺术。
总结一下,这张图把我们带入了卷积神经网络更真实、更强大的彩色世界,并为我们后续学习所有关键概念(如多通道、特征映射、感受野、激活函数、网络设计)打下了坚实的基础。
1.5. 小结
-
图像的平移不变性使我们以相同的方式处理局部图像,而不在乎它的位置。
-
局部性意味着计算相应的隐藏表示只需一小部分局部图像像素。
-
在图像处理中,卷积层通常比全连接层需要更少的参数,但依旧获得高效用的模型。
-
卷积神经网络(CNN)是一类特殊的神经网络,它可以包含多个卷积层。
-
多个输入和输出通道使模型在每个空间位置可以获取图像的多方面特征。
1.6. 练习
1. 假设卷积层(6.1.3)覆盖的局部区域 Δ=0\Delta=0Δ=0。在这种情况下,证明卷积内核为每组通道独立地实现一个全连接层。
解答:
公式 (6.1.3) 为:[H]i,j=u+∑a=−ΔΔ∑b=−ΔΔ[V]a,b[X]i+a,j+b[\mathbf{H}]_{i,j} = u + \sum_{a=-\Delta}^{\Delta}\sum_{b=-\Delta}^{\Delta}[\mathbf{V}]_{a,b}[\mathbf{X}]_{i+a,j+b}[H]i,j=u+∑a=−ΔΔ∑b=−ΔΔ[V]a,b[X]i+a,j+b。
当 Δ=0\Delta = 0Δ=0 时,求和符号的上下限都为0。这意味着卷积核的大小为 1x1
。此时,公式简化为:
[H]i,j=u+[V]0,0[X]i,j[\mathbf{H}]_{i,j} = u + [\mathbf{V}]_{0,0}[\mathbf{X}]_{i,j}[H]i,j=u+[V]0,0[X]i,j
解读与证明:
- 全连接:在这个简化公式中,输出特征图 H\mathbf{H}H 在任意位置
(i, j)
的值,只依赖于输入 X\mathbf{X}X 在完全相同的位置(i, j)
的值。它不再关注任何邻近像素。这相当于输出层的每个神经元都只与输入层正对它的那个神经元相连接,形成了“全连接”的模式。 - 每组通道独立:需要注意的是,原始的输入和输出通常是多通道的。一个
1x1
的卷积核会作用于所有输入通道的同一位置(i, j)
上,并将其加权求和后得到该位置的一个输出值。如果我们有多个这样的1x1
卷积核,每个核都会独立地产生一个输出通道。 - 结论:因此,一个 Δ=0\Delta=0Δ=0 的卷积层,本质上就是一个共享参数的全连接层。这里的“共享”是指,对于图像中的每一个位置
(i, j)
,连接它们的权重(即1x1
卷积核的值)都是相同的([V]_{0,0}
)。它实现了全连接的功能,但参数量远少于一个传统的全连接层。
2. 为什么平移不变性可能也不是好主意呢?
解答:
平移不变性是一个强大的先验知识,但并非在所有场景下都是最优的。它可能不好的情况包括:
- 位置信息至关重要时:如果任务的目标本身就对物体的绝对位置或相对位置高度敏感,平移不变性会损害性能。
- 例子1:人脸关键点检测。我们需要精确检测出眼睛、鼻尖、嘴角的像素级位置。如果网络对平移不敏感,它就无法完成这种高精度的定位任务。
- 例子2:天空中出现一辆汽车。在常规数据集中,汽车通常出现在地面区域。如果一张图片中汽车出现在了天空(发生了不常见的平移),一个具有强平移不变性的模型可能会因为“先验知识”而将其误判为飞机或鸟,而一个对位置敏感的模型则可能捕捉到这个异常。
- 计算效率与表征冗余:严格的平移不变性要求模型在任何位置都使用相同的特征检测器。这意味着即使图像中的某些区域是空白或无意义的(例如纯色背景),网络也会“不辞辛劳”地用同样的计算复杂度去处理它们,造成计算资源的浪费。有时,让网络自主决定在哪些位置集中计算资源(如使用注意力机制)可能更高效。
3. 当从图像边界像素获取隐藏表示时,我们需要思考哪些问题?
解答:
这是一个非常实际的问题。当卷积核滑动到图像边界时,其部分会悬空在图像之外,没有真实的像素值与之相乘。这就引出了边界像素处理的问题,我们需要思考:
- 输出尺寸缩小:如果不做任何处理,每进行一次卷积操作,输出特征图的尺寸都会比输入缩小一些(例如,
3x3
卷积会使每边缩小1个像素)。经过多层网络后,特征图可能变得非常小。 - 信息丢失:图像边缘的像素被计算的次数远少于中心像素,这意味着它们的信息在网络中得到的传播和利用率较低。
解决方案(需要思考的选择):
- 填充(Padding):最常见的解决方案。在图像边界外围填充一圈像素(通常填0),让卷积核能够覆盖到边界像素,从而保持输出尺寸不变。需要思考填充策略(填零、复制、反射等)。
- 有效卷积(Valid Convolution):直接忽略边界,只在不需填充的位置进行卷积,接受输出变小的结果。
- 步长(Stride):滑动卷积核的步长也会影响边界处理和输出尺寸。
4. 描述一个类似的音频卷积层的架构。
解答:
音频数据是一维的时间序列信号(波形)或二维的时频谱(时间 x 频率)。
- 输入:原始音频波形(一维序列)或将其转换后的时频谱图(二维,可视为单通道“图像”)。
- 卷积核:
- 对于波形(一维):使用一维卷积核。核不再是方形的,而是一个长度固定的向量。它在时间轴方向上滑动,用于捕获短时的音频模式(如一个音素的起始、一个冲击声)。
- 对于时频谱(二维):可以使用二维卷积核,同时在时间和频率两个维度上操作,捕获时频域中的局部模式(如一个和弦在特定时间范围内的 pattern)。
- 平移不变性:这里的“平移”指的是时间平移。架构具有时间平移不变性,即一个声音模式(如鸟叫)无论它在音频的开头、中间还是结尾出现,都应该被同一个卷积核检测到。
- 局部性:卷积核只关注一个短时间窗口内的音频信号,而不是整个音频序列。
5. 卷积层也适合于文本数据吗?为什么?
解答:
适合,但需要调整。
-
为什么适合?:文本数据也可以被构造成一种“伪图像”。常见的做法是将词嵌入(Word Embedding)后,将一句话排列成一个二维矩阵:
- 一维:序列方向(单词的顺序,类似于时间)。
- 另一维:词嵌入向量的维度(每个词的表示,类似于通道)。
- 在这个结构上使用一维卷积(核在序列方向上滑动),可以非常有效地捕获局部词序列中的模式,即 N-gram 特征。例如,一个大小为3的卷积核可以学习到类似“not good”、“very bad”这样的三元组短语特征。
-
需要注意什么?(为什么是“但”):
- 与RNN/Transformer的对比:卷积核的感受野通常受限,难以直接建模序列中相距很远的单词之间的长期依赖关系(尽管通过堆叠多层卷积可以扩大感受野)。而循环神经网络(RNN)或Transformer的自注意力机制天生更擅长处理这种长程依赖。
- 应用场景:卷积在文本分类(如情感分析、垃圾邮件识别)、文本生成和机器翻译等任务中都有成功应用,它通常能非常快速和高效地提取局部特征。
6. 证明在(6.1.6)中,fg = gf。
解答:
公式 (6.1.6) 是二维离散卷积的定义:(f∗g)(i,j)=∑a∑bf(a,b)g(i−a,j−b)(f*g)(i,j)=\sum_{a}\sum_{b}f(a,b)g(i-a,j-b)(f∗g)(i,j)=∑a∑bf(a,b)g(i−a,j−b)。
要证明卷积操作满足交换律,即 f∗g=g∗ff*g = g*ff∗g=g∗f。
证明:
我们通过变量替换来证明。
令 a′=i−aa' = i - aa′=i−a 和 b′=j−bb' = j - bb′=j−b。反之,则 a=i−a′a = i - a'a=i−a′, b=j−b′b = j - b'b=j−b′。
当 aaa 和 bbb 在求和范围内遍历所有值时,a′a'a′ 和 b′b'b′ 同样会遍历所有值。
将替换代入原式:
(f∗g)(i,j)=∑a∑bf(a,b)g(i−a,j−b)(f*g)(i,j)=\sum_{a}\sum_{b}f(a,b)g(i-a,j-b)(f∗g)(i,j)=a∑b∑f(a,b)g(i−a,j−b)
=∑a′∑b′f(i−a′,j−b′)g(a′,b′)=\sum_{a'}\sum_{b'}f(i-a', j-b')g(a', b')=a′∑b′∑f(i−a′,j−b′)g(a′,b′)
=∑a′∑b′g(a′,b′)f(i−a′,j−b′)=\sum_{a'}\sum_{b'}g(a', b')f(i-a', j-b')=a′∑b′∑g(a′,b′)f(i−a′,j−b′)
=(g∗f)(i,j)=(g*f)(i,j)=(g∗f)(i,j)
证毕。
直观理解:卷积的交换律意味着,无论是将滤波器 g
滑过信号 f
,还是将信号 f
滑过滤波器 g
,最终得到的结果都是一样的。