📚 课程目录

第13课:目标检测基础

📖 本课概述

目标检测不仅要识别"是什么",还要定位"在哪里"。本课从滑动窗口到锚框,理解目标检测的核心思想。

🎯 一、目标检测问题定义

输入:图像

输出:{(类别₁, 置信度₁, [x₁,y₁,w₁,h₁]), ...}

核心挑战:多目标、多尺度、遮挡、背景

📐 二、经典方法演进

2.1 滑动窗口

最朴素的方法:在图像上用不同大小的窗口滑动,每个窗口做分类。问题:计算量爆炸!

2.2 R-CNN系列

方法年份速度精度
R-CNN2014慢(47s/图)
Fast R-CNN2015
Faster R-CNN2015

2.3 YOLO系列

YOLO核心思想:将检测视为回归问题

将图像分成S×S网格,每个网格预测B个边界框

输出:S×S×(B×5+C)的张量

2.4 IoU与mAP

IoU = |A∩B| / |A∪B|

mAP = 各类别AP的平均值

AP = PR曲线下的面积

2.5 PyTorch实现锚框与IoU


import torch
import torch.nn as nn
import math

# 锚框生成
def generate_anchors(feature_size, scales, ratios):
    """在特征图上生成锚框"""
    anchors = []
    for i in range(feature_size):
        for j in range(feature_size):
            cx = (j + 0.5) / feature_size
            cy = (i + 0.5) / feature_size
            for scale in scales:
                for ratio in ratios:
                    w = scale * math.sqrt(1/ratio)
                    h = scale * math.sqrt(ratio)
                    anchors.append([cx, cy, w, h])
    return anchors

# 生成锚框
anchors = generate_anchors(8, [0.5, 0.3], [1.0, 2.0, 0.5])
print(f"特征图8×8, 2个尺度, 3个比例 → 锚框数: {len(anchors)}")
print(f"示例锚框: {anchors[:3]}")

# IoU计算
def compute_iou(box1, box2):
    """计算两个框的IoU, box格式: [cx, cy, w, h]"""
    x1 = box1[0] - box1[2]/2
    y1 = box1[1] - box1[3]/2
    x2 = box1[0] + box1[2]/2
    y2 = box1[1] + box1[3]/2
    
    x1g = box2[0] - box2[2]/2
    y1g = box2[1] - box2[3]/2
    x2g = box2[0] + box2[2]/2
    y2g = box2[1] + box2[3]/2
    
    xi1 = max(x1, x1g)
    yi1 = max(y1, y1g)
    xi2 = min(x2, x2g)
    yi2 = min(y2, y2g)
    
    inter = max(0, xi2-xi1) * max(0, yi2-yi1)
    area1 = (x2-x1) * (y2-y1)
    area2 = (x2g-x1g) * (y2g-y1g)
    union = area1 + area2 - inter
    
    return inter / (union + 1e-6)

# IoU测试
boxes = [
    [0.5, 0.5, 0.4, 0.4],  # 真实框
    [0.5, 0.5, 0.4, 0.4],  # 完全重叠
    [0.5, 0.5, 0.5, 0.5],  # 更大
    [0.3, 0.3, 0.2, 0.2],  # 偏移
    [0.8, 0.8, 0.2, 0.2],  # 远离
]
print("\n=== IoU计算 ===")
gt = boxes[0]
for i, box in enumerate(boxes):
    iou = compute_iou(gt, box)
    print(f"GT vs Box{i}: IoU={iou:.4f}")

# NMS实现
def nms(boxes, scores, iou_threshold=0.5):
    """非极大值抑制"""
    indices = sorted(range(len(scores)), key=lambda i: scores[i], reverse=True)
    keep = []
    while indices:
        i = indices.pop(0)
        keep.append(i)
        indices = [j for j in indices if compute_iou(boxes[i], boxes[j]) < iou_threshold]
    return keep

# NMS测试
pred_boxes = [[0.5,0.5,0.4,0.4], [0.52,0.5,0.38,0.4], [0.5,0.52,0.4,0.38], [0.2,0.2,0.3,0.3]]
scores = [0.95, 0.85, 0.80, 0.70]
keep = nms(pred_boxes, scores, 0.5)
print(f"\nNMS前: {len(pred_boxes)}个框, NMS后: {len(keep)}个框, 保留索引: {keep}")
🟢 运行结果 ✅验证通过 特征图8×8, 2个尺度, 3个比例 → 锚框数: 384 示例锚框: [[0.0625, 0.0625, 0.5, 0.5], [0.0625, 0.0625, 0.3535533905932738, 0.7071067811865476], [0.0625, 0.0625, 0.7071067811865476, 0.3535533905932738]] === IoU计算 === GT vs Box0: IoU=1.0000 GT vs Box1: IoU=1.0000 GT vs Box2: IoU=0.6400 GT vs Box3: IoU=0.0526 GT vs Box4: IoU=0.0000 NMS前: 4个框, NMS后: 2个框, 保留索引: [0, 3]

🔬 深入拓展

核心要点回顾

本课的核心知识点构成了CNN学习的重要一环。让我们从更高维度审视这些知识之间的关系:

常见陷阱与最佳实践

⚠️ 初学者常犯的错误:

💡 最佳实践:

与前后课程的联系

深度学习是一个整体——每一课的知识都不是孤立的:

📖 延伸阅读

💡 继续深入的学习路径:

📝 练习

练习1:实现Faster R-CNN的RPN

实现区域建议网络,理解anchor生成和筛选。

练习2:mAP计算

在模拟数据上实现完整的mAP计算流程。

练习3:YOLO v5结构

分析YOLOv5的网络结构,与原始YOLO对比改进点。

💡 目标检测实践

检测器选择指南

常见错误与解决方案

⚠️ 需要避免的典型错误:

  1. 不了解模型假设就盲目使用
  2. 没有建立基线就追求复杂方法
  3. 忽视数据质量和预处理
  4. 过度调参而不理解原理
  5. 只看训练指标忽略验证指标

性能优化建议

💡 提升模型性能的系统方法:

  1. 确保数据管道正确且高效
  2. 建立简单但正确的基线模型
  3. 分析基线的错误类型
  4. 针对性地改进(数据/模型/训练)
  5. 持续迭代,每步验证

🔬 深度拓展:从理论到实践

核心概念网络

理解本课内容需要将其置于更大的知识网络中。每个核心概念都不是孤立的,它们相互关联、相互支撑:

关键洞察与直觉

建立正确的直觉比记住公式更重要:

1. 维度直觉:高维空间中,数据分布与低维直觉截然不同(维度诅咒)

2. 信息瓶颈:神经网络逐层压缩信息,保留任务相关的、丢弃无关的

3. 流形假设:高维数据实际分布在低维流形上,学习即发现流形结构

4. 偏差-方差权衡:简单模型欠拟合(高偏差),复杂模型过拟合(高方差)

与其他课程的关联

本课作为CNN阶段的核心内容,与前后课程紧密关联:

关联课程关联点协同效应
前序课程提供了本课的基础知识循序渐进的理解
后续课程本课内容是后续的基础逐步构建能力
平行课程同一阶段的互补知识多角度深入理解
实战项目综合运用所有知识理论与实践结合

面试常见问题

💡 准备面试时,确保能回答以下问题:

  1. 用简单语言解释本课核心概念
  2. 画出关键算法/结构的流程图
  3. 比较不同方法的优缺点
  4. 举出实际应用场景
  5. 讨论常见误解和注意事项

进阶学习路径

掌握本课内容后,可以通过以下方式继续深入:

🎯

成就解锁:检测先锋

目标检测不仅要识别还要定位——你开始理解视觉感知!