第四章:卷积神经网络(CNN)基础
各位同学,今天我们来聊聊卷积神经网络。说实话,我刚入行那会儿,做图像识别全靠手工设计特征,又慢又不准。直到接触了CNN,才真正体会到什么叫「让网络自己学特征」。这一章,我会把卷积层、池化层、全连接层这些核心组件讲透,再带大家看看LeNet和AlexNet这两个经典网络。
4.1 卷积层:特征提取的利器
卷积层是CNN的灵魂。它的作用很简单——从输入图像中提取局部特征。比如边缘、纹理、角点这些低级特征,再到更抽象的形状、物体部件。
我习惯把卷积层想象成一个「滑动窗口」。一个小的卷积核(比如3x3或5x5)在输入图像上从左到右、从上到下地滑动,每次做一次点积运算。这个点积结果,就是该位置的特征响应。
关键参数:
- 卷积核大小(Kernel Size):通常用3x3或5x5。太小感受野不够,太大计算量爆炸。
- 步长(Stride):每次滑动的像素数。步长=2时,输出尺寸减半。
- 填充(Padding):在输入边缘补零,控制输出尺寸。我常用'same' padding保持尺寸不变。
- 通道数(Channels):每个卷积核输出一个特征图,多个卷积核堆叠成多个通道。
举个例子,输入一张224x224的RGB图像(3通道),用64个3x3卷积核,步长1,same padding。输出就是224x224x64的特征图。每个通道代表一种特征模式。
我的经验:在汽车电子项目中,比如车道线检测,我通常先用3x3卷积核堆叠。为什么?因为3x3卷积核计算效率高,而且多个3x3堆叠能获得和5x5、7x7一样的感受野,但参数量更少。这是个经典技巧。
4.2 池化层:降维与不变性
池化层的作用很直白——下采样。说白了就是把特征图变小,减少计算量,同时让特征对微小位移更鲁棒。
最常见的两种池化:
- 最大池化(Max Pooling):取窗口内的最大值。我项目中用得最多,因为它能保留最显著的特征。
- 平均池化(Average Pooling):取窗口内的平均值。适合背景平滑的场景。
池化层没有可训练参数,只有窗口大小和步长。通常用2x2窗口,步长2,这样特征图尺寸减半。
注意:池化层会丢失位置信息。在目标检测任务中,我建议谨慎使用过多池化。我曾经在车牌识别项目中,因为池化层太多,导致字符位置信息丢失,识别率上不去。后来改用步长卷积代替部分池化,效果好了很多。
4.3 全连接层:分类决策
全连接层就是传统的神经网络层。每个神经元与上一层的所有神经元相连。它的作用是把卷积层和池化层提取到的「特征」映射到「类别」上。
举个例子,经过几层卷积和池化后,我们得到一个特征向量(比如4096维)。全连接层把这个向量映射到类别数(比如10类),输出每个类别的概率。
全连接层的参数量巨大。一个4096维输入到4096维输出的全连接层,参数量就是4096x4096≈1600万。所以现代网络倾向于用全局平均池化代替全连接层,减少过拟合风险。
避坑指南:我曾经在嵌入式平台上部署模型时,发现全连接层占用了80%的参数量。后来我改用1x1卷积和全局平均池化,模型大小从200MB降到了20MB,精度只掉了0.5%。嗯,这个技巧在资源受限的汽车电子场景下特别实用。
4.4 经典网络结构:LeNet
LeNet是CNN的鼻祖,由Yann LeCun在1998年提出,用于手写数字识别。结构简单,但奠定了现代CNN的基础。
LeNet-5结构:
| 层 | 类型 | 输出尺寸 | 参数 |
|---|---|---|---|
| 输入 | 图像 | 32x32x1 | - |
| C1 | 卷积 | 28x28x6 | 5x5卷积核,步长1 |
| S2 | 平均池化 | 14x14x6 | 2x2窗口,步长2 |
| C3 | 卷积 | 10x10x16 | 5x5卷积核,步长1 |
| S4 | 平均池化 | 5x5x16 | 2x2窗口,步长2 |
| C5 | 卷积 | 1x1x120 | 5x5卷积核 |
| F6 | 全连接 | 84 | - |
| 输出 | 全连接 | 10 | - |
LeNet只有约6万个参数,放在今天看非常轻量。但在90年代,这已经是革命性的了。
我的看法:LeNet虽然简单,但它的设计思想至今适用——卷积提取特征、池化降维、全连接分类。我在做简单的交通标志识别时,有时还会用LeNet的变体,训练快、部署方便。
4.5 经典网络结构:AlexNet
AlexNet是2012年ImageNet竞赛的冠军,由Alex Krizhevsky设计。它让深度学习真正火了起来。相比LeNet,AlexNet更深、更大,还引入了一些新技巧。
AlexNet结构:
| 层 | 类型 | 输出尺寸 | 参数 |
|---|---|---|---|
| 输入 | 图像 | 227x227x3 | - |
| Conv1 | 卷积+ReLU | 55x55x96 | 11x11卷积核,步长4 |
| Pool1 | 最大池化 | 27x27x96 | 3x3窗口,步长2 |
| Conv2 | 卷积+ReLU | 27x27x256 | 5x5卷积核,步长1 |
| Pool2 | 最大池化 | 13x13x256 | 3x3窗口,步长2 |
| Conv3 | 卷积+ReLU | 13x13x384 | 3x3卷积核,步长1 |
| Conv4 | 卷积+ReLU | 13x13x384 | 3x3卷积核,步长1 |
| Conv5 | 卷积+ReLU | 13x13x256 | 3x3卷积核,步长1 |
| Pool5 | 最大池化 | 6x6x256 | 3x3窗口,步长2 |
| FC6 | 全连接+ReLU+Dropout | 4096 | - |
| FC7 | 全连接+ReLU+Dropout | 4096 | - |
| FC8 | 全连接+Softmax | 1000 | - |
AlexNet的几个关键创新:
- ReLU激活函数:解决了梯度消失问题,训练更快。我之前用sigmoid训练深层网络,经常卡住不动,换成ReLU后问题迎刃而解。
- Dropout:随机丢弃部分神经元,防止过拟合。我建议全连接层后加Dropout,保留概率0.5左右。
- 数据增强:随机裁剪、翻转、颜色变换,扩大数据集。在汽车电子项目中,数据增强几乎是必备的,因为真实场景变化太大。
- GPU并行训练:AlexNet用两块GTX 580训练了6天。现在用一块RTX 4090,几个小时就能搞定。
注意:AlexNet的参数量约6000万,是LeNet的1000倍。在嵌入式汽车电子平台上,直接部署AlexNet几乎不可能。我建议用轻量化网络(如MobileNet、SqueezeNet)替代,或者做模型剪枝和量化。
4.6 实践建议
讲完理论,说说我在汽车电子项目中的实际经验。
卷积层设计:
- 优先用3x3卷积核堆叠,而不是大卷积核。计算效率高,参数量少。
- 步长卷积可以替代池化层,减少信息丢失。我习惯在特征图尺寸较大时用池化,尺寸较小时用步长卷积。
- Batch Normalization放在卷积层之后、激活函数之前,能加速训练。
池化层选择:
- 最大池化适合边缘检测、纹理识别。平均池化适合背景平滑的场景。
- 全局平均池化可以替代全连接层,大幅减少参数量。
全连接层优化:
- 如果模型太大,考虑用1x1卷积+全局平均池化替代全连接层。
- 全连接层后一定要加Dropout,防止过拟合。
我的经验:在做一个前车检测项目时,我一开始用AlexNet直接迁移学习,模型太大,在嵌入式设备上跑不到10帧。后来我改用MobileNet作为骨干网络,加上自定义的全连接层,模型小了10倍,帧率到了30帧,精度只降了2%。所以,选网络结构时一定要考虑部署平台。
好了,这一章的内容就到这里。卷积层、池化层、全连接层是CNN的三大基石,LeNet和AlexNet是经典中的经典。下一章我们会讲更现代的网络结构,比如VGG、ResNet,以及它们在汽车电子中的具体应用。大家先把基础打牢,后面才能飞得更高。
课后思考:为什么AlexNet用11x11的大卷积核,而现代网络更倾向用3x3?你能从感受野和计算量的角度分析一下吗?