一、卷积神经网络(CNN)基础回顾

各位同学好,今天咱们来聊聊CNN的基础。说实话,这部分内容很多教程都讲,但真正理解透的人不多。我当年刚入行时也踩过不少坑,今天就把这些经验分享给大家。

1.1 卷积操作:到底在干什么?

卷积操作,说白了就是用一个小的窗口(卷积核)在输入图像上滑动,每次做点乘求和。嗯,就这么简单。

举个例子,假设我们有一个5×5的输入图像,用一个3×3的卷积核去扫它:

输入图像 (5×5):    卷积核 (3×3):
[1 1 1 0 0]        [1 0 1]
[0 1 1 1 0]        [0 1 0]
[0 0 1 1 1]        [1 0 1]
[0 0 1 1 0]
[0 1 1 0 0]

第一次卷积计算:
1×1 + 1×0 + 1×1 + 0×0 + 1×1 + 1×0 + 0×1 + 0×0 + 1×1 = 4

我在项目中遇到过一个问题:很多人以为卷积核越大越好。其实不然,3×3的卷积核堆叠两层,感受野相当于5×5,但参数量更少,非线性更强。这是个很实用的技巧。

关键点:卷积操作的核心是参数共享和局部连接。同一个卷积核在整个图像上滑动,大大减少了参数量。

1.2 池化:为什么要丢掉信息?

池化操作,我习惯叫它"下采样"。它的目的很明确:降低特征图尺寸,减少计算量,同时保留主要特征。

常见的池化方式有两种:

  • 最大池化(Max Pooling):取窗口内的最大值。我一般用它来保留纹理特征。
  • 平均池化(Average Pooling):取窗口内的平均值。适合保留背景信息。

举个例子,2×2的最大池化:

输入特征图 (4×4):    输出特征图 (2×2):
[1 3 2 4]            [3 4]
[5 6 7 8]     →      [7 8]
[9 1 2 3]
[4 5 6 7]

我的经验:池化窗口大小一般选2×2,步长也设为2。太大容易丢失细节,太小又起不到降维作用。

1.3 感受野:网络能看到多大范围?

感受野这个概念,说白了就是特征图上每个像素对应原始图像上的区域大小。你想想看,浅层网络的感受野小,只能看到局部纹理;深层网络的感受野大,能看到全局结构。

计算公式其实很简单:

RF_l = RF_{l-1} + (kernel_size - 1) × stride_{l-1}

其中RF_l是第l层的感受野大小。

举个例子,一个3层3×3卷积(步长均为1)的网络:

  • 第1层:感受野 = 3×3
  • 第2层:感受野 = 5×5
  • 第3层:感受野 = 7×7

我曾经犯过一个错误:在移动端部署时,用了太大的卷积核导致感受野过大,结果模型对局部细节不敏感。后来改用小卷积核堆叠,效果反而更好。

注意:空洞卷积可以扩大感受野而不增加参数量,但使用不当会导致网格效应。我建议在需要大感受野的场景下,优先考虑堆叠小卷积核。

1.4 CNN在移动端的局限性

好了,前面讲了CNN的基础,现在说说为什么它在移动端会遇到瓶颈。我做了这么多年移动端部署,总结下来主要有三个问题:

问题 具体表现 影响
计算量大 标准卷积需要大量乘加运算 手机CPU/GPU扛不住
参数量多 全连接层动辄上百万参数 模型文件太大,下载慢
内存占用高 中间特征图占用大量显存 低端手机直接闪退

举个例子,一个标准的VGG-16模型,参数量约1.38亿,模型文件超过500MB。你想想看,哪个用户愿意下载一个500MB的App?

更麻烦的是,CNN的全局建模能力有限。虽然可以通过堆叠层数扩大感受野,但本质上还是局部操作。对于需要全局上下文的任务(比如语义分割),CNN就显得力不从心了。

核心矛盾:CNN擅长局部特征提取,但缺乏全局建模能力。而移动端又要求模型轻量高效。这就是为什么我们需要MobileViT这样的混合架构。

嗯,说到这里,大家应该对CNN的基础和局限性有了清晰的认识。下一节我们会深入探讨自注意力机制,看看它是如何解决这些问题的。

CNN基础回顾知识体系 卷积神经网络(CNN) 卷积操作 参数共享 + 局部连接 池化操作 最大池化 / 平均池化 感受野 局部 → 全局 移动端局限性 计算量大 / 参数量多 / 内存高 3×3卷积堆叠 空洞卷积 保留主要特征 降低计算量 小卷积核堆叠 避免网格效应 缺乏全局建模能力 移动端部署困难 解决方案:MobileViT(CNN + Transformer)