一、卷积神经网络基础:卷积运算的数学原理、特征图与感受野、权值共享与局部连接

各位同学好,我是你们的FPGA工程师老K。今天咱们开始聊卷积神经网络的基础,这部分内容我做了快十年,踩过的坑不少,但收获也很多。说实话,很多做FPGA加速的同学,一上来就撸代码,结果连卷积到底在算什么都没搞明白——嗯,这其实挺要命的。

咱们先别急着写Verilog,先把数学底子打牢。你想想看,FPGA加速的本质是什么?就是把算法里的计算密集型操作,用硬件并行流水的方式跑得更快。如果连算法本身都理解不透,那优化就无从谈起。

1.1 卷积运算的数学原理

卷积运算,说白了就是“加权求和”。我习惯用一个简单的例子来理解:

假设你有一张灰度图,大小是5×5像素。你拿一个3×3的小窗口(我们叫它“卷积核”或者“滤波器”),在这个大图上从左到右、从上到下地滑动。每滑动到一个位置,就把窗口里的9个像素值,和卷积核里对应的9个权重值,一一相乘,然后把这9个乘积加起来。这个结果,就是输出特征图上的一个像素值。

数学表达式长这样:

输出像素值 = Σ (输入像素 × 对应权重) + 偏置

我在项目中遇到过一件事:有个同事把卷积和互相关搞混了。其实在CNN里,我们用的严格来说是“互相关”运算,不是数学意义上的卷积。数学卷积需要把核翻转180度再算,但CNN里不翻转。为什么?因为权重是训练出来的,翻转不翻转,网络都能学到特征,只是参数位置不同而已。所以大家放心,咱们平时写的卷积代码,就是直接乘加,不用翻转。

核心要点:卷积 = 滑动窗口 × 加权求和。就这么简单。

再举个例子。假设输入是4×4,卷积核是3×3,步长是1,没有填充。那么输出尺寸怎么算?

输出尺寸 = (输入尺寸 - 核尺寸) / 步长 + 1
         = (4 - 3) / 1 + 1
         = 2

所以输出是2×2的特征图。这个公式我建议你记牢,写RTL代码时经常要用到。

1.2 特征图与感受野

特征图是什么?就是卷积层输出的结果。每一层卷积,都会生成一组特征图。每个特征图对应一个卷积核的检测结果。比如你有32个卷积核,那这一层就会输出32张特征图。

我刚开始做FPGA加速时,有个误区:以为特征图就是“图像”。其实不是。特征图是“特征”的响应图。浅层的特征图可能检测边缘、纹理;深层的特征图检测更抽象的概念,比如眼睛、车轮。

感受野这个概念,我觉得特别重要。它指的是输出特征图上的一个像素点,对应到输入图像上有多大区域。你想想看,第一层卷积,3×3的核,感受野就是3×3。但到了第二层,如果还是3×3的核,感受野就变大了——因为第二层的输入已经是第一层的输出,而第一层的每个像素已经“看过”了3×3的区域。

我习惯用一个递推公式来算:

感受野大小 = 上一层的感受野 + (当前核尺寸 - 1) × 步长累积

举个例子:

  • 第一层:核3×3,步长1,感受野 = 3
  • 第二层:核3×3,步长1,感受野 = 3 + (3-1)×1 = 5
  • 第三层:核3×3,步长1,感受野 = 5 + (3-1)×1×1 = 7

你看,三层3×3卷积堆叠,感受野达到了7×7。而直接用7×7卷积,参数量是3×3×3 = 27个权重,而7×7卷积需要49个权重。这就是为什么现代网络喜欢用小卷积核堆叠——感受野大,参数量还少。

我的经验:做FPGA加速时,感受野决定了你的数据复用策略。感受野越大,数据重用的机会就越多,流水线设计就越有优化空间。

1.3 权值共享与局部连接

这两个概念,是CNN能火起来的核心原因。咱们对比一下全连接网络就明白了。

全连接网络:每个输入神经元,都连接到每个输出神经元。假设输入是1000×1000的图像,第一层有1000个神经元,那参数量就是1000×1000×1000 = 10^9,10亿个参数。这谁受得了?

CNN用了两招来解决:

  • 局部连接:每个神经元只连接输入的一个局部区域(感受野)。比如3×3的核,每个神经元只连9个输入像素。参数量瞬间降到9×1000 = 9000。
  • 权值共享:同一个卷积核,在整个输入图上滑动时,权重是不变的。也就是说,检测同一个特征(比如水平边缘)的神经元,共用同一套权重。

我打个比方:全连接就像每个员工都要认识公司所有人;局部连接就像每个员工只认识自己小组的人;权值共享就像所有小组都用同一套考核标准。这样管理成本就低多了。

权值共享还有个好处——平移不变性。一个特征不管出现在图像的哪个位置,都能被同一个卷积核检测到。这在FPGA实现时特别友好,因为你可以把权重存在BRAM里,反复读取使用,不用为每个位置存不同的权重。

注意:权值共享不是所有层都适用。有些网络(比如SENet)会在通道维度上做注意力,每个通道的权重是不同的。但基础的卷积层,权值共享是默认的。

1.4 本章知识体系总览

下面这张图,是我自己画的,把本章的核心逻辑串起来了。你看一眼,应该能对卷积基础有个整体把握。

卷积神经网络基础 - 知识体系 卷积运算 特征图与感受野 权值共享与局部连接 加权求和 滑动窗口 输出尺寸计算 特征提取 感受野递推 小核堆叠优势 参数减少 平移不变性 BRAM权重复用 FPGA加速核心思路 数据复用 + 流水并行 + 权重缓存

这张图把三个核心概念串起来了。卷积运算是基础操作,特征图和感受野是理解网络行为的工具,权值共享和局部连接是减少参数量的关键。这三者结合起来,才有了我们在FPGA上做加速优化的空间。

1.5 小结

这一章咱们聊了卷积的数学本质、特征图和感受野的概念、以及权值共享和局部连接为什么能大幅减少参数量。我个人觉得,这些基础概念比具体的代码实现更重要——方向对了,代码怎么写都行;方向错了,优化再狠也白搭。

我曾经见过一个团队,花三个月优化卷积核的乘法器,结果发现算法本身用的是depthwise卷积,权值共享的方式完全不同。嗯,这就是基础没打牢的代价。

下一章咱们会深入聊卷积在FPGA上的具体实现,包括行缓存、数据复用、流水线设计这些实战内容。到时候我会拿我实际做过的项目来举例,把踩过的坑都告诉你。

课后思考:如果输入是RGB三通道彩色图像,卷积核的维度应该怎么设计?输出特征图的通道数又由什么决定?想明白这个问题,你就真正理解了卷积的维度变换。

可可精品资料库