深度学习基础回顾:卷积神经网络(CNN)核心概念
各位同学,咱们今天聊聊CNN。说实话,很多做工业视觉的朋友,模型调包用得飞起,但一碰到奇怪的缺陷检测不准,就抓瞎了。根子在哪?往往是对CNN这些底层概念理解不够深。我当年刚入行时也吃过这个亏,后来老老实实把基础补上,才算是真正入了门。
1. 卷积操作:不只是“滑动窗口”
卷积说白了,就是用一个小矩阵(我们叫它卷积核或滤波器)在输入图像上滑动,逐元素相乘后求和。这个过程提取的是局部特征。
举个例子,输入是 32×32 的图像,用 3×3 的卷积核,步长为1,不填充(Valid卷积),输出就是 30×30。为什么?因为滑动了30次嘛。
我在项目中遇到过一个典型的坑:检测电路板上的微小焊点缺陷。图像分辨率很高,但直接用大卷积核(比如7×7)去扫,计算量爆炸,而且小焊点的细节全被模糊掉了。后来我改用堆叠小卷积核(3×3),效果反而更好。
2. 感受野:你的神经元到底看到了什么?
感受野这个概念,我建议你一定要理解透。它指的是特征图上某个点,对应回输入图像上的区域大小。
你想想看,浅层的神经元感受野小,只能看到边缘、纹理这些局部信息。深层的神经元感受野大,能看到物体的整体轮廓。这就是为什么CNN能层层抽象。
| 网络层数 | 感受野大小 | 看到的内容 |
|---|---|---|
| Conv1 (3×3) | 3×3 | 边缘、角点 |
| Conv2 (3×3) | 5×5 | 纹理、图案 |
| Conv3 (3×3) | 7×7 | 物体部件 |
| Conv4 (3×3) | 9×9 | 完整物体 |
3. 池化:降维但不丢关键信息
池化层的作用很直接:缩小特征图尺寸,减少参数量,同时保留主要特征。常用的有两种:最大池化(Max Pooling)和平均池化(Average Pooling)。
- 最大池化: 取窗口内的最大值。保留最显著的特征,适合提取边缘、纹理。
- 平均池化: 取窗口内的平均值。保留整体信息,适合平滑背景。
我个人习惯在工业缺陷检测中多用最大池化。因为缺陷往往是局部突变,最大池化能更好地抓住这些异常点。平均池化容易把微小的缺陷给“平均”没了。
4. 激活函数:给网络注入非线性
如果没有激活函数,再多层卷积也只是线性变换的堆叠,那跟单层网络没区别。激活函数就是引入非线性的关键。
| 函数 | 公式 | 优点 | 缺点 |
|---|---|---|---|
| Sigmoid | 1/(1+e-x) | 输出在0~1,适合二分类 | 梯度消失,计算慢 |
| Tanh | (ex-e-x)/(ex+e-x) | 输出在-1~1,零中心 | 仍有梯度消失问题 |
| ReLU | max(0, x) | 计算快,缓解梯度消失 | 神经元“死亡”问题 |
| Leaky ReLU | max(0.01x, x) | 解决神经元死亡 | 参数需调优 |
我建议你在YOLO这类目标检测网络中,优先用Leaky ReLU或Mish。ReLU虽然快,但负半轴直接置零,训练时有些神经元可能永远不再激活。嗯,这个现象叫“神经元死亡”,我在训练一个钢材表面缺陷检测模型时就遇到过,换成Leaky ReLU后问题就解决了。
5. 损失函数:模型学习的“指挥棒”
损失函数衡量的是模型预测值和真实值之间的差距。训练过程就是不断减小这个差距。
在YOLO中,损失函数通常包含三部分:
- 边界框回归损失: 预测框和真实框的位置差异。常用CIoU Loss,比原始的MSE更稳定。
- 置信度损失: 判断网格内是否有目标的概率。用二值交叉熵(BCE Loss)。
- 分类损失: 判断目标类别的概率。也是交叉熵损失。
6. 知识结构总览
下面这张图把CNN的核心概念串起来了。你可以把它当作一个思维导图来记。
7. 实战中的一点体会
说了这么多理论,最后分享一个我自己的经验。做工业视觉项目,尤其是YOLO模型训练,千万别一上来就调网络结构。先把数据搞清楚,再把损失函数和激活函数选对,往往能解决80%的问题。
我记得有一次做手机屏幕划痕检测,模型怎么都学不好。后来发现是激活函数选错了,ReLU把负半轴的微弱划痕信号全砍掉了。换成Leaky ReLU后,召回率直接提升了15%。