Harris
发布于 2026-03-23 / 11 阅读
0
0

深入通俗理解“卷积”:从数学物理到深度学习

深入通俗理解“卷积”:从数学物理到深度学习

无论是在信号与系统课程中,还是在学习卷积神经网络(CNN)时,“卷积 (Convolution)”都是一个绕不开的幽灵。初学者往往会被它的数学积分公式吓倒,但如果你懂得了它的物理意义,就会发现这是一个极其优雅且自然的概念。

一、 到底什么是“卷积”?(一个完美的物理比喻)

我们先不看公式,来想象一个极其生活化的场景:吃药与药物残留

假设你生病了,医生让你持续吃药。

  1. 输入信号:表示你在 ​t 时刻吃进去的药物剂量。
  2. 衰减函数:表示吃下一单位药物后,经过 ​\tau 时间,它在体内的残留比例。

现在问:在第 t 时刻,你体内的药物总残留量是多少?

显然,你在 t 时刻体内的药,不仅包含你刚好在 t 时刻吃下的药,还包含你昨天、前天、甚至大前天吃下的药的残留

  • 在过去的某个时刻 ​t'​t' < t),你吃下了 ​x(t') 剂量的药。
  • ​t' 到现在 ​t,经历的时间是 ​t - t'
  • 那么这批药在现在的残留量就是:​x(t') \cdot h(t - t')

要把所有过去时刻吃下的药在 t 时刻的残留量加起来,这就是积分(或求和):

(t) = \int_{-\infty}^{\infty} x(t') \cdot h(t - t') \, dt'

恭喜你,你已经完美理解了卷积的数学定义!这就是卷积的最核心物理意义:一个系统在某一个特定时刻的输出,是过去所有输入信号在系统中的“余音(残留影响)”的叠加。

二、 卷积的严格数学定义

通过上面的比喻,我们再来看数学公式,就会觉得非常亲切了。

1. 连续型卷积

对于两个连续函数 f(t)g(t),它们的卷积运算记为 (f * g)(t),定义为:

(f * g)(t) = \int_{-\infty}^{\infty} f(\tau) \cdot g(t - \tau) \, d\tau

2. 离散型卷积

在计算机中(比如图像处理),信号是离散的(像素点),积分就变成了求和:

(f * g)[n] = \sum_{m=-\infty}^{\infty} f[m] \cdot g[n - m]

3. “卷”和“积”到底体现在哪?

  • “卷” (Flip/Roll):体现在 ​g(t - \tau) 中。由于时间差是 ​t - \tau,在这个积分关于 ​\tau 的函数里,​g 是被反转(翻转,Flip)过来的,且随时间向右平移(滑动)
  • “积” (Product & Integral):体现在二者相乘 ​f(\tau) \cdot g(t - \tau),然后求积分(求和)叠加。

总结操作步骤:一翻(翻转),二移(平移滑动),三乘,四求和。

三、 从一维到二维:图像处理中的卷积

在深度学习和计算机视觉中,我们处理的是二维的图片。二维离散卷积的原理与一维完全一致,只是滑动窗口变成了二维的矩阵(卷积核 / Kernel)

假设我们有一张大图片矩阵 I,和一个 k \times k 的卷积核矩阵 K。 卷积操作就是:

  1. 把卷积核 ​K 翻转 180 度(在深度学习中通常省略这一步,后文会解释)。
  2. 将卷积核盖在图片的左上角。
  3. 把重叠部分的像素值与卷积核的权重对应相乘,然后全部加起来,得到中心点的新像素值。
  4. 每次向右/向下移动一个步长(Stride),重复上述操作。

直观作用:特征提取

不同的卷积核可以提取出不同的图像特征(这就叫滤波):

  • 平滑/模糊核(平均滤波):所有权重都是正数(如 ​\frac{1}{9}\begin{bmatrix}1&1&1\\1&1&1\\1&1&1\end{bmatrix}),作用是把周围像素的平均值赋予中心点,图像变模糊。
  • 边缘检测核(如 Sobel 算子):左边是正数,右边是负数(如 ​\begin{bmatrix}-1&0&1\\-1&0&1\\-1&0&1\end{bmatrix})。如果图像区域是纯色,乘完相加是 0(黑色);如果在物体边缘(颜色突变),乘完相加绝对值很大(亮边)。

四、 深度学习 (CNN) 中的“假”卷积

如果你去翻看 PyTorch 或 TensorFlow 的底层源码,会发现一个让人震惊的事实: 深度学习框架里的 Conv2d,在数学严格意义上,根本不是卷积!

数学上的卷积,卷积核 K 在滑动相乘前,必须先做一次180 度翻转(即公式里的负号 g(t - \tau))。 但在深度学习中,我们直接拿着卷积核去图像上滑动相乘了。这种没有翻转的操作,在数学上叫做 互相关 (Cross-Correlation)

为什么深度学习不翻转卷积核?

因为没有必要! 在图像处理或信号系统中,卷积核是人为设计好的(比如高斯滤波核),翻转具有明确的物理意义(时间因果性)。 但在 CNN 中,卷积核的权重 是随机初始化,并通过反向传播 (BP) 算法让机器自己“学习”出来的。 既然参数是学出来的,机器直接学出一个“原本就翻转好”的核,和学出一个没翻转的核,本质上是完全等价的。省去翻转这一步,反而提高了计算效率。

五、 代码直观演示:用 NumPy 实现 2D 卷积 (互相关)

理解底层原理最好的方式就是手写一段极简代码:

import numpy as np

def conv2d(image, kernel):
    """一个极简的二维卷积(互相关)实现,步长为1,无 padding"""
    # 获取图像和卷积核的尺寸
    img_h, img_w = image.shape
    ker_h, ker_w = kernel.shape
  
    # 计算输出矩阵的尺寸
    out_h = img_h - ker_h + 1
    out_w = img_w - ker_w + 1
  
    # 初始化输出矩阵
    output = np.zeros((out_h, out_w))
  
    # 滑动窗口遍历全图
    for y in range(out_h):
        for x in range(out_w):
            # 切片取出感受野 (Receptive Field)
            region = image[y : y + ker_h, x : x + ker_w]
            # 对应元素相乘并求和
            output[y, x] = np.sum(region * kernel)
          
    return output

# 测试:边缘检测
img = np.array([
    [10, 10, 10, 0, 0, 0],
    [10, 10, 10, 0, 0, 0],
    [10, 10, 10, 0, 0, 0],
    [10, 10, 10, 0, 0, 0]
])

# 垂直边缘检测核 (Prewitt 算子)
kernel_edge = np.array([
    [ 1, 0, -1],
    [ 1, 0, -1],
    [ 1, 0, -1]
])

print(conv2d(img, kernel_edge))
# 输出结果将会在第 2 列产生巨大的正值(30),完美捕捉到了像素值从 10 突变到 0 的垂直边缘边界!

六、 总结

  1. 物理意义:卷积是过去所有输入信号在当前时刻的“叠加残留”。
  2. 操作过程:翻转 → 滑动 → 相乘 → 求和。
  3. 二维应用:用一个“模板(Kernel)”在图像上滑动,提取特定的特征(如边缘、纹理)。
  4. 深度学习中的卷积:实际上是“互相关”操作,去掉了翻转步骤,让神经网络自己学习这块滑动的模板。

评论