4、物体识别核心概念:图像分类、目标检测、特征提取、卷积神经网络(CNN)的基本原理
在TinyML摄像头项目中,我们最终要让一块指甲盖大小的微控制器“看懂”世界。但在动手编写代码之前,必须先建立一套清晰的概念框架。本章将拆解物体识别领域的四个核心支柱:图像分类、目标检测、特征提取与卷积神经网络(CNN)。理解这些概念之间的层级关系,能帮助你在后续部署模型时做出正确的架构选择——例如,为什么某些任务适合MobileNet,而另一些任务必须使用SSD或YOLO-Tiny。
4.1 图像分类:从“这是什么”开始
核心原理:图像分类的任务是给整张输入图片分配一个语义标签。例如,一张包含一只橘猫的照片,分类模型输出“猫”的概率为0.92,“狗”的概率为0.05。在数学上,分类器学习的是一个从像素空间到类别空间的映射函数 f: R^(H×W×C) → [0,1]^K,其中K是类别总数。对于TinyML场景,K通常不超过10,因为类别越多,模型参数和计算量越大。
判断方法:当你需要回答“这张图里最主要的东西是什么”时,使用图像分类。它不关心物体在图片中的位置,也不关心图片里是否有多个物体。典型的应用场景包括:质检流水线上的良品/次品判别、植物叶片病害种类识别、手势数字识别(如摄像头前比出1-5)。
| 特性 | 图像分类 | 目标检测 |
|---|---|---|
| 输出粒度 | 整图一个标签 | 每个物体一个标签+位置框 |
| 计算量 | 较低 | 较高(需区域提议或密集锚点) |
| TinyML可行性 | 高(MobileNetV1量化后约0.5MB) | 中(需SSD-Tiny或YOLO-Tiny) |
| 典型模型 | LeNet、MobileNet、EfficientNet | SSD-MobileNet、YOLO-Tiny |
| 标注成本 | 每张图一个标签 | 每个物体需画框+标签 |
案例拆解:假设我们要做一个“垃圾分类”TinyML设备,摄像头对准垃圾桶入口,判断当前扔的是“可回收”还是“不可回收”。这里使用图像分类就足够了——因为每次只会有一样东西进入画面。我们收集了2000张可回收物(塑料瓶、易拉罐)和2000张不可回收物(果皮、纸巾)的图片,缩放到96×96像素,训练一个MobileNetV1模型。在树莓派Pico上部署时,单次推理耗时约180ms,准确率91%。
4.2 目标检测:定位与分类的协同
核心原理:目标检测需要同时回答两个问题:“图中有什么?”和“它在哪?”输出通常是一个边界框列表,每个框包含四个坐标值(中心点x、y,宽度w,高度h)和类别概率。在TinyML领域,主流方案是单阶段检测器(如SSD、YOLO-Tiny),它们将检测任务转化为回归问题——直接在特征图上预测边界框偏移量和类别置信度。
操作流程:一个典型的TinyML检测流程分为四步:① 输入图像缩放至模型要求尺寸(如192×192);② 通过骨干网络(如MobileNet)提取特征;③ 在多个尺度的特征图上生成预设锚点框;④ 对每个锚点框预测类别概率和坐标偏移,最后通过非极大值抑制(NMS)去除重叠框。
# 伪代码:TinyML检测输出后处理
for each anchor_box in predictions:
if anchor_box.confidence > 0.5:
x = anchor_box.dx * anchor_box.width + anchor_box.center_x
y = anchor_box.dy * anchor_box.height + anchor_box.center_y
w = exp(anchor_box.dw) * anchor_box.width
h = exp(anchor_box.dh) * anchor_box.height
keep_box(x, y, w, h, label)
# 执行NMS,保留置信度最高的框,删除IoU>0.5的重复框
案例拆解:我们为智能门铃设计了一个“宠物检测”功能,需要识别画面中的猫和狗,并框出它们的位置。使用SSD-MobileNetV2-Tiny,输入尺寸192×192,训练数据包含8000张标注图片(每张平均1.5个目标)。在ESP32-S3上部署时,模型大小1.2MB(INT8量化),推理时间320ms,mAP(平均精度均值)达到0.78。关键调优点在于锚点框的宽高比——猫和狗多为直立姿态,我们将锚点框比例从默认的{1:1, 1:2, 2:1}调整为{1:1, 0.8:1.5, 1.5:0.8},mAP提升了4个百分点。
4.3 特征提取:从像素到语义的桥梁
核心原理:特征提取是CNN的核心能力——将原始像素矩阵逐步转化为高层次的语义特征。浅层卷积核提取边缘、颜色块等低级特征;中层卷积核组合出纹理、局部形状;深层卷积核则能响应“眼睛”“轮子”等语义部件。在TinyML中,我们通常使用预训练模型的前若干层作为特征提取器,然后接一个轻量级分类头。
判断方法:当你的任务数据量较小(如每类只有200张图),但又想获得较好的准确率时,可以采用“迁移学习+特征提取”策略:冻结预训练模型(如MobileNet在ImageNet上训练)的卷积层权重,只训练最后的全连接层。这样可以将训练时间从数小时缩短到几分钟,且准确率远高于从零训练。
| 特征提取策略 | 适用场景 | 模型大小 | 训练数据需求 |
|---|---|---|---|
| 从零训练 | 数据量大、领域特殊(如X光片) | 完整模型 | 每类≥1000张 |
| 迁移学习(冻结骨干) | 数据中等、通用物体 | 骨干+新分类头 | 每类≥100张 |
| 迁移学习(微调) | 数据充足、需适应新域 | 全模型可训练 | 每类≥500张 |
实战场景:在“识别三种鸟类”项目中,我们使用在ImageNet上预训练的MobileNetV1作为特征提取器,冻结前20层卷积权重,只训练最后的全连接层。输入图像96×96,训练集每类150张。训练10个epoch后,验证准确率从随机初始化的68%提升到93%。关键操作是:在全局平均池化层后添加一个Dropout(0.5)层,有效防止过拟合。
4.4 卷积神经网络(CNN)基本原理
核心原理:CNN通过三个关键机制实现高效图像理解:局部感受野(每个神经元只连接输入的小块区域)、权值共享(同一个卷积核滑过整张图)、空间下采样(池化层逐步缩小特征图尺寸)。在TinyML中,我们特别关注卷积层的计算量公式:FLOPs = 2 × H_out × W_out × C_in × C_out × K × K,其中K是卷积核尺寸。
操作流程:一个标准卷积块包含:卷积→批归一化→ReLU激活→最大池化。在微控制器上,批归一化层在推理时可以融合到卷积层中(通过数学变换),从而减少一次内存访问。深度可分离卷积(MobileNet的核心)将标准卷积分解为深度卷积(每个通道独立卷积)和逐点卷积(1×1卷积),计算量降低到原来的1/8到1/9。
# 深度可分离卷积的PyTorch实现示意
class DepthwiseSeparableConv(nn.Module):
def __init__(self, in_channels, out_channels, stride=1):
super().__init__()
self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size=3,
stride=stride, padding=1, groups=in_channels)
self.pointwise = nn.Conv2d(in_channels, out_channels, kernel_size=1)
self.bn = nn.BatchNorm2d(out_channels)
self.relu = nn.ReLU()
def forward(self, x):
x = self.depthwise(x)
x = self.pointwise(x)
x = self.bn(x)
return self.relu(x)
案例拆解:我们对比了标准卷积和深度可分离卷积在ESP32-C3上的性能。输入特征图尺寸32×32×16,输出通道32,卷积核3×3。标准卷积需要计算量约1.5M FLOPs,耗时8.2ms;深度可分离卷积仅需0.19M FLOPs,耗时1.1ms。准确率在CIFAR-10小型分类任务上仅下降1.2%。这验证了深度可分离卷积是TinyML的首选结构。
| CNN组件 | 作用 | TinyML优化要点 |
|---|---|---|
| 卷积层 | 提取局部特征 | 使用3×3小核,避免5×5以上 |
| 批归一化 | 加速收敛、稳定训练 | 推理时融合到卷积权重中 |
| ReLU激活 | 引入非线性 | 计算量极低,适合MCU |
| 最大池化 | 下采样、平移不变性 | 使用2×2步长2,减少计算 |
| 全连接层 | 最终分类 | 用全局平均池化替代,减少参数 |
总结复盘:本章四个概念构成了递进关系:图像分类是最基础的认知任务,目标检测在分类基础上增加了空间定位,特征提取是两者的共同基石,而CNN提供了实现特征提取的具体计算框架。在TinyML实践中,你需要根据任务需求(分类还是检测)、硬件资源(内存、算力)和数据集规模,综合选择模型架构和输入分辨率。记住一个关键数字:在微控制器上,每1MB模型参数大约需要4MB RAM来运行推理,因此模型大小和激活值内存必须同时考虑。