4、图像分类核心概念:卷积神经网络(CNN)基础,卷积、池化、全连接层,分类损失与准确率
TinyML 物体识别项目的本质,是在资源极度受限的微控制器上完成“图像进、类别出”的推理任务。要理解这一过程,必须掌握卷积神经网络(CNN)的核心构件:卷积层负责提取局部特征,池化层负责压缩空间尺寸,全连接层负责将特征映射为类别得分,而损失函数与准确率则构成了模型训练的“方向盘”与“仪表盘”。本章将逐一拆解这些概念,并结合 TinyML 场景说明其设计约束。
4.1 卷积层:局部特征提取的核心机制
卷积层是 CNN 的“眼睛”。它通过一组可学习的卷积核(Filter/Kernel)在输入图像上滑动,计算局部区域的加权和,从而提取边缘、纹理、颜色块等低级特征。在 TinyML 场景中,卷积核尺寸通常取 3×3 或 1×1,因为更大的核(如 5×5、7×7)会显著增加乘加运算量和参数量,超出微控制器的算力预算。
卷积操作的核心参数包括:卷积核数量(决定输出通道数)、步长(Stride,决定滑动间隔)、填充(Padding,决定输出尺寸是否保持不变)。对于 32×32 的输入图像,使用 3×3 卷积核、步长 1、无填充时,输出尺寸为 30×30。若使用 8 个卷积核,则输出张量为 30×30×8,参数量为 3×3×3×8 = 216 个权重(假设输入为 RGB 三通道)。
在微控制器上,卷积层通常以深度可分离卷积(Depthwise Separable Convolution)替代标准卷积。它将标准卷积拆分为逐通道卷积(Depthwise)和逐点卷积(Pointwise),参数量可减少约 8~9 倍。例如 MobileNet 系列架构正是基于此设计,使其成为 TinyML 物体识别的主流骨干网络。
4.2 池化层:空间降维与平移不变性
池化层(Pooling)紧随卷积层之后,其作用是降低特征图的空间分辨率,同时保留主要特征。最常用的是最大池化(Max Pooling),它取窗口内最大值作为输出;平均池化(Average Pooling)则取均值。在 TinyML 中,2×2 最大池化、步长 2 是最常见配置,它可将特征图尺寸减半,从而大幅减少后续全连接层的输入维度。
池化层不引入额外参数,计算量也极低(仅需比较或求和),非常适合资源受限设备。更重要的是,池化赋予了模型一定的平移不变性——即使目标物体在图像中轻微移动,池化后的特征仍能保持稳定,这对低分辨率图像分类尤为重要。
| 池化类型 | 计算方式 | 优点 | TinyML 适用性 |
|---|---|---|---|
| 最大池化 | 取窗口内最大值 | 保留最强激活,对纹理敏感 | 推荐,计算量极小 |
| 平均池化 | 取窗口内平均值 | 保留整体信息,抑制噪声 | 可用于全局平均池化 |
| 全局平均池化 | 整个特征图取均值 | 替代全连接层,大幅减少参数 | 强烈推荐,常用于最后分类 |
在 TinyML 实践中,全局平均池化(Global Average Pooling)常被用作全连接层的替代方案。它将每个通道的特征图压缩为一个数值,直接送入分类输出层,从而消除全连接层的大量参数。例如,若卷积输出为 4×4×16,全局平均池化后变为 16 维向量,参数量从 4×4×16×N 骤降至 16×N。
4.3 全连接层与分类输出
全连接层(Fully Connected Layer)将池化后的特征展平为一维向量,并通过矩阵乘法映射到类别得分。假设输入特征维度为 D,输出类别数为 C,则全连接层包含 D×C 个权重和 C 个偏置。在 TinyML 中,全连接层往往是参数量最大的部分,因此需要严格控制 D 和 C 的规模。
分类输出层通常配合 Softmax 激活函数,将得分转换为概率分布。Softmax 的公式为:
P(y=i|x) = exp(z_i) / Σ exp(z_j) (j=1..C)
其中 z_i 为第 i 类的得分。Softmax 输出总和为 1,便于解释和计算交叉熵损失。在微控制器上,Softmax 的指数运算可通过查表或近似算法实现,以避免浮点运算开销。
4.4 分类损失函数与准确率评估
训练 CNN 时,损失函数衡量预测分布与真实标签之间的差异。最常用的是交叉熵损失(Cross-Entropy Loss):
L = -Σ y_i · log(p_i)
其中 y_i 为真实标签的 one-hot 编码,p_i 为 Softmax 输出的概率。交叉熵损失在错误预测时产生较大梯度,能有效驱动模型学习。在 TinyML 场景中,由于模型容量有限,常需配合权重衰减(L2 正则化)防止过拟合。
准确率(Accuracy)是分类任务最直观的评估指标:
Accuracy = 正确预测样本数 / 总样本数
但在类别不平衡时,准确率可能产生误导。例如,若 90% 样本属于“背景”类,模型全部预测为背景也能获得 90% 准确率。因此,TinyML 项目常同时监控精确率(Precision)、召回率(Recall)和 F1 分数。
| 指标 | 公式 | 含义 | TinyML 场景建议 |
|---|---|---|---|
| 准确率 | (TP+TN)/(TP+TN+FP+FN) | 整体正确率 | 类别均衡时使用 |
| 精确率 | TP/(TP+FP) | 预测为正类的样本中真实正类比例 | 误报代价高时关注 |
| 召回率 | TP/(TP+FN) | 真实正类中被正确预测的比例 | 漏报代价高时关注 |
| F1 分数 | 2×P×R/(P+R) | 精确率与召回率的调和平均 | 综合评估推荐 |
4.5 案例拆解:基于 CNN 的 10 类物品分类器
假设我们需要在 Arduino Nano 33 BLE Sense 上部署一个识别 10 类日常物品(如钥匙、硬币、橡皮、笔帽等)的分类器。输入图像为 32×32 灰度图,RAM 限制 50KB,Flash 限制 256KB。
模型设计:
- 输入层:32×32×1(灰度)
- 卷积层 1:8 个 3×3 卷积核,步长 1,无填充 → 输出 30×30×8,参数量 8×3×3×1+8=80
- 池化层 1:2×2 最大池化 → 输出 15×15×8
- 卷积层 2:16 个 3×3 卷积核,步长 1,无填充 → 输出 13×13×16,参数量 16×3×3×8+16=1168
- 池化层 2:2×2 最大池化 → 输出 6×6×16(向下取整)
- 全局平均池化 → 输出 16 维向量
- 全连接层:16×10+10=170 个参数
总参数量:80+1168+170=1418 个参数,约 5.5KB(按 4 字节浮点存储)。加上中间激活值(30×30×8+15×15×8+13×13×16+6×6×16≈12.8KB),总 RAM 占用约 18KB,满足约束。
训练与量化:在 PC 端使用 TensorFlow 训练,准确率达 92%。随后进行 8 位量化,将权重从 float32 转为 int8,模型大小压缩至约 1.4KB,推理速度提升 3 倍。部署后实测准确率 89%,下降 3 个百分点,但仍在可接受范围。
4.6 常见误区与总结复盘
误区一:盲目增加卷积核数量。在 TinyML 中,算力和内存是硬约束。8 个卷积核可能已足够提取特征,增加到 32 个虽能提升精度,但会导致 RAM 溢出。应优先通过数据增强(旋转、平移、亮度变化)提升泛化能力,而非增加模型容量。
误区二:忽略输入分辨率的影响。32×32 输入在 TinyML 中是常见选择,但若物体过小或细节丰富,可尝试 48×48 输入,同时减少卷积核数量以平衡计算量。需通过实验对比不同分辨率的准确率与延迟。
误区三:将准确率作为唯一指标。在嵌入式场景中,推理延迟、功耗、RAM 峰值同样关键。一个准确率 95% 但延迟 500ms 的模型,可能不如准确率 90% 但延迟 50ms 的模型实用。
误区四:忽视 Softmax 的计算开销。在 Cortex-M4 等无 FPU 的 MCU 上,Softmax 的指数运算可能消耗大量 CPU 周期。建议在推理阶段省略 Softmax,直接比较 logits 大小。
总结:CNN 的四个核心组件——卷积、池化、全连接、损失函数——构成了 TinyML 图像分类的基础。卷积层提取特征,池化层降维,全连接层分类,损失函数指导优化。在资源受限环境下,每个组件的设计都需要在精度与效率之间权衡。掌握这些概念后,下一步将进入数据采集与预处理环节,为模型训练准备高质量数据集。