☰
目标检测入门:从图像分类到边界框回归的完整指南(AI-For-Beginners 第 11 课)
2026/10/3 12:37:53 网站建设 项目流程
  • 教程
  • 人工智能
  • 机器学习
  • 深度学习

【免费下载链接】AI-For-Beginners

12 Weeks, 24 Lessons, AI for All!

项目地址:https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners
点击查看免费下载

目标检测(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 中的实验):

  1. 把图片切分成若干小块(tile);
  2. 对每一小块分别执行图像分类;
  3. 那些分类激活值足够高的小块,即可认为包含目标物体。

以"在一张照片里找猫"为例,可以借助预训练的 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 / U

AP(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 是最常被引用的数字。

目标检测算法的两大流派

主流目标检测算法可以划分为两大类:

  1. 基于区域提议的网络(Region Proposal Networks):R-CNN、Fast R-CNN、Faster R-CNN。核心思路是先生成"感兴趣区域(ROI)",再对 ROI 运行 CNN 寻找最大激活。它与朴素方法相似,但 ROI 的生成方式更聪明。主要缺点是慢——需要对同一图像多次运行 CNN 分类器。

  2. 单次(One-pass)方法:YOLO、SSD、RetinaNet。网络被设计为一次前向传播同时预测类别与 ROI,速度更快,适合实时场景。

R-CNN:基于区域的卷积神经网络

R-CNN 使用Selective Search(选择性搜索)生成 ROI 的层次化结构,这些 ROI 依次经过 CNN 特征提取器与 SVM 分类器确定物体类别,再由线性回归确定边界框坐标。典型流程如下:

  1. 用 Selective Search 在原图上生成约 2000 个候选区域;
  2. 对每个候选区域缩放后送入 CNN 提取特征;
  3. 用 SVM 分类每个区域的特征,判断物体类别;
  4. 用线性回归精修边界框坐标。

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 更快,核心思路是:

  1. 使用ResNet-101提取特征;
  2. 特征经Position-Sensitive Score Map(位置敏感得分图)处理:将 C 类物体的每个类别划分为k×k个区域,训练网络预测物体的各个"部位";
  3. 每个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。实验路径概括为:

  1. 用预训练 VGG-16 实现朴素格子检测与概率热力图;
  2. 生成合成矩形数据,训练全连接网络完成边界框回归;
  3. 用 IoU 实现评估预测质量并计算平均 IoU;
  4. 延伸了解 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!

项目地址:https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询