- 教程
- 人工智能
- 机器学习
- 深度学习
【免费下载链接】AI-For-Beginners
12 Weeks, 24 Lessons, AI for All!
目标检测(Object Detection)是计算机视觉的核心任务之一:不仅要知道"图片里有什么",还要回答"物体在哪里"。本文基于 AI-For-Beginners 课程第 11 课"Object Detection"展开,系统讲解目标检测的朴素方法、回归思路、经典数据集(PASCAL VOC 与 COCO)、评估指标(IoU、AP、mAP),以及 R-CNN 家族与 YOLO 等主流算法原理,并结合仓库中的 ObjectDetection.ipynb 提供可直接运行的动手实践。读完后你将理解目标检测算法的分类脉络,并能在 TensorFlow/Keras 中亲手实现一个从零训练的边界框回归模型。
从图像分类到目标检测:问题定义的转变
此前课程(如 MNIST 手写数字识别)中处理的都是图像分类问题:输入一张图片,输出一个类别结果,例如"这是一个数字 3"。但在大量真实场景中,我们不仅要确认图片里有物体,还需要确定物体的精确位置——这正是目标检测要解决的问题。
典型应用包括:
- 视频监控画面中统计人数、识别行人;
- 商店客流统计、餐厅高峰期人流量估算;
- 自动驾驶中检测车辆、行人、交通标志等目标。
目标检测的输出通常是一组边界框(bounding box),即每个检测到的目标都由一个矩形区域(通常用左上角坐标x, y与宽高w, h表示)加上一个类别标签来定位。
朴素目标检测方法及其局限
最直观的"朴素方法"可以概括为三步(见 ObjectDetection.ipynb 中的实验):
- 把图片切分成若干小块(tile);
- 对每一小块分别执行图像分类;
- 那些分类激活值足够高的小块,即可认为包含目标物体。
以"在一张照片里找猫"为例,可以借助预训练的 VGG-16 模型来实现:由于 ImageNet 中猫的类别索引为 281~294,只要把各猫类别概率求和,就得到整张图"是猫"的置信度。然后定义一个predict_map函数把图片划分为n×n的方格,逐个格子计算猫概率,即可生成一张概率热力图:
import cv2 from tensorflow import keras import numpy as np img = cv2.imread('images/1200px-Girl_and_cat.jpg') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = np.pad(img, ((158,158),(0,0),(0,0)), mode='edge') vgg = keras.applications.vgg16.VGG16(weights='imagenet') def predict(img): im = cv2.resize(img, (224, 224)) im = keras.applications.vgg16.preprocess_input(im) pr = vgg.predict(np.expand_dims(im, axis=0))[0] return np.sum(pr[281:294]) # VGG 中猫的类别索引为 281~294 def predict_map(img, n): dx = img.shape[0] // n res = np.zeros((n, n), dtype=np.float32) for i in range(n): for j in range(n): im = img[dx*i:dx*(i+1), dx*j:dx*(j+1)] res[i, j] = predict(im) return res局限:这种方法只能把边界框定位到"某个格子"的粒度,定位非常粗糙,无法给出物体的精确轮廓。要实现更精准的定位,需要引入回归(regression)——直接预测边界框的坐标。
用回归预测边界框:一个从零训练的示例
为了让网络输出落在[0,1]区间便于训练,实践中通常把边界框坐标除以图像尺寸做归一化。目标检测的回归任务一般使用MSE(均方误差)作为损失函数、SGD 作为优化器(因为这是回归而非分类任务)。
ObjectDetection.ipynb 提供了一个完整的迷你示例:在8×8的黑色图像上随机放置白色矩形,网络输入为图像像素,输出为 4 个边界框数值[x, y, w, h]。
首先生成 10 万张带标注的训练样本:
def generate_images(num_imgs, img_size=8, min_object_size=1, max_object_size=4): bboxes = np.zeros((num_imgs, 4)) imgs = np.zeros((num_imgs, img_size, img_size)) # 背景为 0 for i_img in range(num_imgs): w, h = np.random.randint(min_object_size, max_object_size, size=2) x = np.random.randint(0, img_size - w) y = np.random.randint(0, img_size - h) imgs[i_img, x:x+w, y:y+h] = 1. # 矩形区域置 1 bboxes[i_img] = [x, y, w, h] return imgs, bboxes imgs, bboxes = generate_images(100000) bb = bboxes / 8.0 # 归一化到 [0,1]然后搭建一个简单的全连接网络(真实场景中物体形状复杂,更适合使用 CNN):
model = keras.Sequential([ keras.layers.Flatten(input_shape=(8, 8)), keras.layers.Dense(200, activation='relu'), keras.layers.Dropout(0.2), keras.layers.Dense(4) ]) model.compile('sgd', 'mse')训练时对输入做标准化处理(减去均值、除以标准差),可略微提升性能:
imgs_norm = (imgs - np.mean(imgs)) / np.std(imgs) model.fit(imgs_norm, bb, epochs=30)训练完成后,还可以用 IoU 指标来评估预测框与真实框的重合质量,并计算整体平均 IoU(详见下文"目标检测评估指标"一节)。该回归思路正是所有现代目标检测算法的基础——分类网络负责"是什么",回归头负责"在哪里"。
目标检测常用数据集
以下两个数据集是该任务中最常遇到的:
- PASCAL VOC:包含 20 个物体类别,每个图像配有 XML 格式的边界框标注;
- COCO(Common Objects in Context,上下文中的常见物体):包含 80 个类别,不仅提供边界框,还提供实例分割掩码(segmentation masks),是目前目标检测研究中最主流的基准数据集之一。
此外,课程作业 lab/README.md 还推荐了Hollywood Heads 数据集:它包含 369,846 个人头标注,分布在 224,740 个好莱坞电影帧中,以 PASCAL VOC 格式提供。每个图像对应一个 XML 描述文件,例如:
<annotation> <folder>HollywoodHeads</folder> <filename>mov_021_149390.jpeg</filename> <size> <width>608</width> <height>320</height> <depth>3</depth> </size> <object> <name>head</name> <bndbox> <xmin>201</xmin> <ymin>1</ymin> <xmax>480</xmax> <ymax>263</ymax> </bndbox> </object> </annotation>该数据集只有head一个类别,每个目标给出边界框坐标。可以用 Python 的 XML 解析库读取标注,或使用 PASCAL VOC 相关的现成库直接处理。
目标检测评估指标
图像分类很容易用准确率衡量,但目标检测必须同时考核类别的正确性与边界框位置的精确度,因此需要专门指标。
IoU(Intersection over Union,交并比)
IoU 衡量两个边界框(或任意两个区域)的重叠程度:两个区域的交集面积除以并集面积。
- 两个完全相同的区域,IoU = 1;
- 两个完全不相交的区域,IoU = 0;
- 一般情况下 IoU 取值在 0 到 1 之间。
实际评估中通常只把 IoU 超过某一阈值的检测视为有效。notebook 中给出了 IoU 的参考实现(基于[x, y, w, h]格式的边界框):
def IOU(bbox1, bbox2): '''计算两个边界框 [x, y, w, h] 的重叠程度:交集面积 / 并集面积''' x1, y1, w1, h1 = bbox1[0], bbox1[1], bbox1[2], bbox1[3] x2, y2, w2, h2 = bbox2[0], bbox2[1], bbox2[2], bbox2[3] w_I = min(x1 + w1, x2 + w2) - max(x1, x2) h_I = min(y1 + h1, y2 + h2) - max(y1, y2) if w_I <= 0 or h_I <= 0: # 无重叠 return 0. I = w_I * h_I U = w1 * h1 + w2 * h2 - I return I / UAP(Average Precision,平均精度)
要衡量某个类别 C 的识别效果,可以考察其Precision-Recall 曲线:随着检测阈值从 0 到 1 变化,图像中被检出的目标数量、精确率和召回率都会随之变化,从而画出一条曲线。
类别 C 的平均精度就是该曲线下的面积。更精确地说,召回率轴通常被等分为 10 段,对 11 个等分点处的精确率取平均:
$$AP = \frac{1}{11}\sum_{i=0}^{10}\text{Precision}(\text{Recall}=\frac{i}{10})$$
在计算 AP 时,只考虑 IoU 超过某个阈值的检测。不同数据集约定不同:
- PASCAL VOC:通常取
IoU Threshold = 0.5; - COCO:AP 会对多个 IoU 阈值分别测量。
mAP(Mean Average Precision,平均平均精度)
mAP 是目标检测的核心评估指标:它是所有物体类别 AP 的平均值,有时还会进一步对多个 IoU 阈值求平均。在模型间横向比较(如论文中的 benchmark 表格)时,mAP 是最常被引用的数字。
目标检测算法的两大流派
主流目标检测算法可以划分为两大类:
基于区域提议的网络(Region Proposal Networks):R-CNN、Fast R-CNN、Faster R-CNN。核心思路是先生成"感兴趣区域(ROI)",再对 ROI 运行 CNN 寻找最大激活。它与朴素方法相似,但 ROI 的生成方式更聪明。主要缺点是慢——需要对同一图像多次运行 CNN 分类器。
单次(One-pass)方法:YOLO、SSD、RetinaNet。网络被设计为一次前向传播同时预测类别与 ROI,速度更快,适合实时场景。
R-CNN:基于区域的卷积神经网络
R-CNN 使用Selective Search(选择性搜索)生成 ROI 的层次化结构,这些 ROI 依次经过 CNN 特征提取器与 SVM 分类器确定物体类别,再由线性回归确定边界框坐标。典型流程如下:
- 用 Selective Search 在原图上生成约 2000 个候选区域;
- 对每个候选区域缩放后送入 CNN 提取特征;
- 用 SVM 分类每个区域的特征,判断物体类别;
- 用线性回归精修边界框坐标。
Fast R-CNN
Fast R-CNN 与 R-CNN 思路类似,但区域是在卷积层应用之后才确定的。共享的卷积特征先计算一次,再针对每个 ROI 进行池化与分类,避免了对每个候选区域重复跑 CNN,从而大幅提速。
Faster R-CNN
Faster R-CNN 的核心创新是用神经网络来预测 ROI,即引入所谓的"区域提议网络(Region Proposal Network, RPN)"。RPN 与检测网络共享卷积特征,端到端联合训练,将区域提议的成本进一步降低,成为后续大量两阶段检测器的基础。
R-FCN:基于区域的全卷积网络
R-FCN 比 Faster R-CNN 更快,核心思路是:
- 使用ResNet-101提取特征;
- 特征经Position-Sensitive Score Map(位置敏感得分图)处理:将 C 类物体的每个类别划分为
k×k个区域,训练网络预测物体的各个"部位"; - 每个
k×k区域的所有子网络对物体类别投票,得票最多的类别胜出。
YOLO:You Only Look Once
YOLO 是经典的实时单次检测算法,核心思想非常简洁:
- 将图像划分为
S×S个区域(网格); - 对每个区域,CNN 预测
n个可能的物体、边界框坐标,以及置信度(置信度 = 概率 × IoU)。
由于只做一次前向传播,YOLO 可以做到实时推理,成为工业界部署最广泛的检测器之一。课程的"🚀 挑战"环节鼓励读者进一步阅读 YOLO 相关文章、官方文档与 Keras 实现,并亲手运行其分步 notebook 实验。
其他值得了解的算法
- RetinaNet:通过 Focal Loss 缓解单次检测器在"前景-背景类别极度不平衡"时的训练困难,在单次方法中取得了很高的精度。其 PyTorch 实现内置于 Torchvision(
torchvision.models.detection.RetinaNet),Keras 官方示例也提供了完整的训练教程。 - SSD(Single Shot Detector,单次检测器):在不同尺度的特征图上直接预测边界框与类别,兼顾速度与精度。
动手实验与作业
✍️ 练习:目标检测
继续学习请运行课程 notebook:ObjectDetection.ipynb。实验路径概括为:
- 用预训练 VGG-16 实现朴素格子检测与概率热力图;
- 生成合成矩形数据,训练全连接网络完成边界框回归;
- 用 IoU 实现评估预测质量并计算平均 IoU;
- 延伸了解 Keras 官方的 RetinaNet 目标检测教程。
🚀 作业:基于 Hollywood Heads 数据集的人头检测
作业详见 lab/README.md,任务场景是视频监控流中的人数统计——通过检测不同角度的人头来估算商店访客数或餐厅高峰时段客流。数据集为 Hollywood Heads(PASCAL VOC 格式,仅head一个类别)。训练方式可任选其一:
- 使用Azure Custom Vision及其 Python API 在云端以编程方式训练模型(Custom Vision 通常只能使用数百张训练图片,因此需要限制数据集规模);
- 参照 Keras 官方教程训练RetinaNet模型;
- 使用 Torchvision 内置的
torchvision.models.detection.RetinaNet模块直接训练。
总结
本课快速巡览了目标检测的多种实现路径:
- 从朴素格子分类到回归预测边界框,理解了为什么需要专门的数据集与回归头;
- 掌握了PASCAL VOC / COCO等数据集形态与Hollywood Heads的 PASCAL VOC XML 标注格式;
- 学会了IoU、AP、mAP这一整套评估体系,以及各数据集对 IoU 阈值的不同约定;
- 理清了两阶段检测器(R-CNN → Fast R-CNN → Faster R-CNN → R-FCN)与单次检测器(YOLO、SSD、RetinaNet)两大算法流派的设计思想与取舍。
目标检测是工业界高频需求:虽然已有成熟的云端检测服务(如 Azure Custom Vision),但理解其工作原理、能够训练自己的模型,仍然是一项关键能力。继续深入可在 12-Segmentation 语义分割 一课中学习像素级分割,两者的数据集与评估体系相互关联。
- 教程
- 人工智能
- 机器学习
- 深度学习
【免费下载链接】AI-For-Beginners
12 Weeks, 24 Lessons, AI for All!
相关推荐
AI-For-Beginners 目标检测实战指南:从分类到定位、从 IoU 到 YOLO
AI For Beginners 目标检测实战指南:从分类到定位、从 IoU 到 YOLO 导读:本文以 AI For Beginners https://li
教程人工智能机器学习深度学习从文本到图像:构建文生图应用的完整实践指南(generative-ai-for-beginners 第 9 课)
从文本到图像:构建文生图应用的完整实践指南(generative ai for beginners 第 9 课) 本指南围绕开源课程《generative ai
教程人工智能大模型ML-For-Beginners 回归课第 3 课:用 Scikit-learn 实现线性回归、多项式回归与类别特征编码的完整实战
ML For Beginners 回归课第 3 课:用 Scikit learn 实现线性回归、多项式回归与类别特征编码的完整实战 本篇指南基于 ML For
教程机器学习人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考