AI 入门 30 天挑战 - Day 15 费曼学习法版 - 目标检测基础

张开发
2026/4/21 0:13:48 15 分钟阅读

分享文章

AI 入门 30 天挑战 - Day 15 费曼学习法版 - 目标检测基础
完整项目和代码本教程是AI 入门 30 天挑战系列的一部分GitHub 仓库: https://github.com/Lee985-cmd/AI-30-Day-ChallengeCSDN 专栏: https://blog.csdn.net/m0_67081842?typeblog⭐欢迎 Star 支持Week 3 第一天目标检测基础不仅知道是什么还要知道在哪里每个概念都解释每行代码都说明白预计时间2.5-3.5 小时含费曼输出练习 第 1 步快速复习 Week 2 的内容30 分钟费曼输出 #0考考你合上教程尝试回答□ CNN 是怎么提取图像特征的用卷积核的例子说明 □ 什么是池化层为什么要降维 □ ResNet 的核心创新是什么解决了什么问题 □ RNN 和 LSTM 的区别在哪里各适合什么场景 □ 如果你要做图像分类项目你会怎么设计流程⏰ 时间25 分钟如果能答出 80% 以上我们开始今天的目标检测之旅如果不够花 5 分钟翻一下 Week 2 的笔记。 第 2 步什么是目标检测40 分钟故事时间 图像分类 vs 目标检测场景一张足球比赛的照片 图像分类Week 2 学的: 你问这是什么场景 AI 答足球场 ❌ 只有整体标签 问题 - 场上有多少人不知道 - 球在哪里不知道 - 球门在哪个位置不知道 目标检测今天要学的: 你问图里有什么在哪里 AI 答 - 左上角有个人边界框 95% 置信度✅ - 中间有个足球边界框 88% 置信度✅ - 右下角有球门边界框 92% 置信度✅ 既知道是什么又知道在哪里生活中的例子超市找商品 图像分类就像 你妈说去超市买水果 你到了超市这是水果区 ✅ 但不知道苹果、香蕉具体在哪里 ❌ 目标检测就像 你妈说去超市买苹果和香蕉 你不仅能找到水果区 还能准确地指出 - 苹果在这里伸手拿 - 香蕉在那里伸手拿 这就是目标检测的价值目标检测的任务详解输入一张图片 ↓ [目标检测模型] ↓ 输出多个边界框 类别标签 例如 ┌──────────────┐ │ 人 95% │ ← 边界框 1 │ ┌────┐ │ │ 车 98% │ ← 边界框 2 │ └────┘ │ │ 猫 92% │ ← 边界框 3 └──────────────┘ 每个检测包含 ✓ 位置x, y, 宽高 ✓ 类别人、车、猫... ✓ 置信度95%、98%... 应用 - 自动驾驶检测行人、车辆 - 安防监控检测可疑人员 - 医疗影像检测病变区域 - 零售检测货架商品 费曼输出 #1解释目标检测任务 1向小学生解释场景有个小朋友问你目标检测是什么要求不用边界框、置信度、IoU这些专业术语用游戏、寻宝、拍照等生活场景比喻让小学生能听懂参考模板目标检测就像______一样。 比如你在______ 要找到______。 你不仅要说出______ 还要指出______。 这样就能______⏰ 时间15 分钟 卡壳检查点如果你在解释时卡住了□ 我说不清楚图像分类和目标检测的区别 □ 我不知道如何解释定位的概念 □ 我只能说检测物体但不能说明白怎么做到的这很正常标记下来回去再看上面的内容然后重新尝试解释提示图像分类 整体判断这是什么地方目标检测 个体识别什么东西在哪里就像看森林 vs 数树木 第 3 步核心概念详解60 分钟1. 边界框Bounding Box生活中的例子相框你要给墙上的一幅画拍照 方法 1把整面墙拍下来 ❌ 画太小看不清 方法 2只拍画的部分 ✅ 正好框住画 这个正好框住就是边界框 在目标检测中 - 找到物体的最小矩形框 - 用 4 个数字表示 两种常用表示方法 方法 1[x_min, y_min, x_max, y_max] → 左上角和右下角坐标 → PyTorch 默认用这个 方法 2[center_x, center_y, width, height] → 中心点 宽高 → YOLO 等模型用这个 可以互相转换2. IoU交并比怎么判断框得准不准真实框Ground Truth: ┌─────────┐ │ │ │ │ ← 实际的物体 │ │ └─────────┘ 预测框Prediction: ┌─────────┐ │ │ │ │ ← AI 预测的框 │ │ └─────────┘ IoU 交集面积 / 并集面积 解释 - 交集 两个框重叠的部分 - 并集 两个框覆盖的全部区域 IoU 1.0 → 完美重合 ✅ IoU 0.7 → 还不错 IoU 0.3 → 差太远 ❌ 一般 IoU 0.5 就认为检测成功 就像考试评分 - 90 分以上 优秀 - 60 分以上 及格 - 60 分以下 不及格3. 非极大值抑制NMS问题同一个物体被框了多次AI 检测一只猫 第 1 次[猫 95%] ┌──┐ 第 2 次[猫 93%] ┌──┐ 第 3 次[猫 85%] ┌──┐ 都框住了同一只猫 ❌ 为什么会出现这个问题 因为 AI 会从不同角度、不同尺度检测 可能会产生多个候选框 解决NMS非极大值抑制 步骤 1. 按置信度排序95% 93% 85% 2. 选最高的95% 这个 3. 去掉和它重叠的93% 和 85% 去掉 4. 结果只保留最好的那个框 ✅ 就像选班长 - 全班投票 - 得票最多的当选 - 其他人淘汰 或者像比赛 - 预赛选出很多人 - 复赛筛选 - 决赛只要冠军 费曼输出 #2深入理解核心概念任务 1创造多个比喻场景 A解释给摄影师听用拍照的例子 取景框 边界框 对焦准确度 IoU 连拍选最佳 NMS场景 B解释给老师听用考试的例子 答题卡上的框 边界框 答案匹配度 IoU 选择题排除法 NMS场景 C解释给厨师听用切菜的例子 切成的方块 边界框 切得准不准 IoU 去掉不好的部分 NMS要求每个场景都要详细说明任务 2解释技术细节思考题1. 为什么要有两种边界框表示方法 2. IoU 为什么用交集除以并集 3. NMS 会不会误删什么情况下会发生 4. 如果两个物体靠得很近怎么办⏰ 时间25 分钟 卡壳检查点□ 我解释不清 IoU 的计算原理 □ 我说不明白 NMS 的必要性 □ 我不能用生活中的例子说明提示边界框 框住物体的矩形IoU 衡量准确度的尺子NMS 去重工具留最优 第 4 步动手实现70 分钟完整代码实现import torch import torchvision from torchvision.ops import nms, box_iou import matplotlib.pyplot as plt import matplotlib.patches as patches import numpy as np print( * 50) print(️ 目标检测基础详解) print( * 50) # # 第 1 步理解边界框表示 # print(\n【1. 边界框表示方法】) # 方法 1[x_min, y_min, x_max, y_max] box1 torch.tensor([[50, 50, 150, 150]], dtypetorch.float32) print(f方法 1[xmin, ymin, xmax, ymax]) print(f 例子{box1}) print(f 含义左上角 (50,50), 右下角 (150,150)) # 方法 2[center_x, center_y, width, height] box2 torch.tensor([[100, 100, 100, 100]], dtypetorch.float32) print(f\n方法 2[cx, cy, w, h]) print(f 例子{box2}) print(f 含义中心点 (100,100), 宽 100, 高 100) print(f\n 两种方法可以互相转换:) print(f PyTorch 默认用方法 1) print(f YOLO 等模型用方法 2) # 可视化 fig, ax plt.subplots(1, figsize(6, 6)) ax.set_xlim(0, 200) ax.set_ylim(0, 200) ax.set_aspect(equal) ax.grid(True, alpha0.3) # 画法 1 rect1 patches.Rectangle( (box1[0, 0], box1[0, 1]), box1[0, 2] - box1[0, 0], box1[0, 3] - box1[0, 1], linewidth2, edgecolorr, facecolornone, label[xmin,ymin,xmax,ymax] ) ax.add_patch(rect1) # 画法 2转换后 x_min box2[0, 0] - box2[0, 2] / 2 y_min box2[0, 1] - box2[0, 3] / 2 rect2 patches.Rectangle( (x_min, y_min), box2[0, 2], box2[0, 3], linewidth2, edgecolorb, facecolornone, linestyle--, label[cx,cy,w,h] ) ax.add_patch(rect2) ax.legend() ax.set_title(边界框的两种表示方法) plt.show() # # 第 2 步计算 IoU # print(\n * 50) print(【2. 计算 IoU交并比】) print( * 50) # 创建两个边界框 box_a torch.tensor([[50, 50, 150, 150]], dtypetorch.float32) # 真实框 box_b torch.tensor([[60, 60, 160, 160]], dtypetorch.float32) # 预测框 print(f真实框{box_a}) print(f预测框{box_b}) # 计算 IoU iou box_iou(box_a, box_b) print(f\nIoU {iou.item():.4f}) # 可视化 fig, ax plt.subplots(1, figsize(6, 6)) ax.set_xlim(0, 200) ax.set_ylim(0, 200) ax.set_aspect(equal) ax.grid(True, alpha0.3) # 画真实框 rect_gt patches.Rectangle( (box_a[0, 0], box_a[0, 1]), box_a[0, 2] - box_a[0, 0], box_a[0, 3] - box_a[0, 1], linewidth2, edgecolorg, facecolorgreen, alpha0.3, label真实框 ) ax.add_patch(rect_gt) # 画预测框 rect_pred patches.Rectangle( (box_b[0, 0], box_b[0, 1]), box_b[0, 2] - box_b[0, 0], box_b[0, 3] - box_b[0, 1], linewidth2, edgecolorr, facecolorred, alpha0.3, label预测框 ) ax.add_patch(rect_pred) ax.legend() ax.set_title(fIoU {iou.item():.4f}) plt.show() print(f\n IoU 解读:) print(f IoU 1.0 → 完美重合 ✅) print(f IoU 0.5 → 检测成功) print(f IoU 0.5 → 需要改进) # # 第 3 步NMS 实战 # print(\n * 50) print(【3. 非极大值抑制NMS】) print( * 50) # 创建一些边界框模拟对同一只猫的多次检测 boxes torch.tensor([ [50, 50, 150, 150, 0.95], # [x1, y1, x2, y2, score] [52, 52, 152, 152, 0.93], [48, 48, 148, 148, 0.85], [200, 200, 300, 300, 0.90], # 另一个物体 [205, 205, 305, 305, 0.80], ], dtypetorch.float32) print(原始检测结果5 个框:) for i, box in enumerate(boxes): print(f 框{i1}: [{box[0]:.0f}, {box[1]:.0f}, {box[2]:.0f}, {box[3]:.0f}] f置信度{box[4]:.2f}) # 分离坐标和分数 boxes_xyxy boxes[:, :4] scores boxes[:, 4] # 应用 NMS keep nms(boxes_xyxy, scores, iou_threshold0.5) print(f\nNMS 后保留的索引{keep}) # 查看保留的框 kept_boxes boxes[keep] print(fNMS 后的结果{len(kept_boxes)} 个框:) for i, box in zip(keep, kept_boxes): print(f 框{i1}: [{box[0]:.0f}, {box[1]:.0f}, {box[2]:.0f}, {box[3]:.0f}] f置信度{box[4]:.2f} ✅) # 可视化 fig, ax plt.subplots(1, figsize(10, 5)) # NMS 前 ax1 ax ax1.set_xlim(0, 400) ax1.set_ylim(0, 400) ax1.set_aspect(equal) ax1.grid(True, alpha0.3) ax1.set_title(NMS 前5 个框) colors [red, orange, yellow, blue, purple] for i, box in enumerate(boxes): rect patches.Rectangle( (box[0], box[1]), box[2] - box[0], box[3] - box[1], linewidth2, edgecolorcolors[i], facecolorcolors[i], alpha0.3, labelf框{i1} ({box[4]:.2f}) ) ax1.add_patch(rect) ax1.text(box[0], box[1]-5, f{box[4]:.2f}, fontsize9, colorcolors[i]) # NMS 后 ax2 ax1.twin() ax2.set_xlim(0, 400) ax2.set_ylim(0, 400) ax2.set_aspect(equal) ax2.grid(True, alpha0.3) ax2.set_title(NMS 后保留 2 个框) for i, box in zip(keep, kept_boxes): rect patches.Rectangle( (box[0], box[1]), box[2] - box[0], box[3] - box[1], linewidth3, edgecolorgreen, facecolorgreen, alpha0.3, labelf保留框{i1} ({box[4]:.2f}) ) ax2.add_patch(rect) ax2.text(box[0], box[1]-5, f{box[4]:.2f} ✅, fontsize10, colorgreen, fontweightbold) plt.tight_layout() plt.show() print(f\n NMS 的作用:) print(f 去除重复检测) print(f 保留置信度最高的框) print(f 让结果更干净) # # 第 4 步使用预训练的目标检测模型 # print(\n * 50) print(【4. 使用 Faster R-CNN 进行目标检测】) print( * 50) # 加载预训练的 Faster R-CNN 模型 model torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrainedTrue) model.eval() print(✓ Faster R-CNN 模型加载完成) print( 可以检测 COCO 数据集的 80 种物体) # 读取一张图片 from PIL import Image import requests from io import BytesIO print(\n正在下载测试图片...) url https://farm.staticflickr.com/2/1715103333_13a0a7d4fc_z.jpg try: response requests.get(url) img Image.open(BytesIO(response.content)) # 转换为 Tensor transform transforms.Compose([ transforms.ToTensor() ]) img_tensor transform(img).unsqueeze(0) # 进行检测 with torch.no_grad(): prediction model(img_tensor) print(f✓ 检测完成) print(f 检测到 {len(prediction[0][boxes])} 个物体) # 显示结果 fig, ax plt.subplots(1, figsize(12, 8)) ax.imshow(img) # 获取类别名称 COCO_CATEGORIES [ __background__, person, bicycle, car, motorcycle, airplane, bus, train, truck, boat, traffic light, fire hydrant, stop sign, parking meter, bench, bird, cat, dog, horse, sheep, cow, elephant, bear, zebra, giraffe, backpack, umbrella, handbag, tie, suitcase, frisbee, skis, snowboard, sports ball, kite, baseball bat, baseball glove, skateboard, surfboard, tennis racket, bottle, wine glass, cup, fork, knife, spoon, bowl, banana, apple, sandwich, orange, broccoli, carrot, hot dog, pizza, donut, cake, chair, couch, potted plant, bed, dining table, toilet, tv, laptop, mouse, remote, keyboard, cell phone, microwave, oven, toaster, sink, refrigerator, book, clock, vase, scissors, teddy bear, hair drier, toothbrush ] # 画边界框 for box, label, score in zip( prediction[0][boxes], prediction[0][labels], prediction[0][scores] ): if score 0.5: # 只显示置信度50%的 box box.numpy() class_name COCO_CATEGORIES[label] rect patches.Rectangle( (box[0], box[1]), box[2] - box[0], box[3] - box[1], linewidth2, edgecolorlime, facecolornone, labelf{class_name} ({score:.2f}) ) ax.add_patch(rect) ax.text(box[0], box[1]-5, f{class_name} {score:.2f}, fontsize9, colorlime, fontweightbold) ax.set_title(Faster R-CNN 目标检测结果) plt.tight_layout() plt.show() except Exception as e: print(f下载或处理图片失败{e}) print(跳过此步骤继续下面的内容) print(\n 恭喜你理解了目标检测的基础) print( * 50)按 Shift Enter 运行 费曼输出 #3解释代码含义逐行解释给小白听任务假装你在教一个完全不懂编程的人要解释清楚1. 边界框的 4 个数字各代表什么 2. IoU 是怎么计算的为什么要这样算 3. NMS 的算法流程是怎样的 4. 预训练模型能做什么要求不用张量、阈值、索引等术语用生活化的比喻每行代码都要说明白参考思路torch.tensor 就像是______ box_iou 就像是______ nms 就像是______ pretrained 就像是______⏰ 时间30 分钟 卡壳检查点□ 我解释不清边界框的坐标含义 □ 我说不明白 NMS 的去重逻辑 □ 我不能用生活中的例子说明提示torch.tensor 装数据的容器box_iou 计算两个框的重叠程度nms 去掉重复的留最好的pretrained 别人训练好的模型 今日费曼总结30 分钟⭐完整的费曼学习流程第 1 步回顾今天的内容5 分钟□ 图像分类 vs 目标检测的区别 □ 边界框的两种表示方法 □ IoU 的计算和意义 □ NMS 的原理和作用 □ 使用预训练模型检测第 2 步合上教程尝试完整教授15 分钟⭐任务假装你在给一个完全不懂的人上第十五堂课要覆盖目标检测和图像分类的区别用至少 2 个例子边界框是怎么框住物体的IoU 是怎么判断准确度的NMS 是怎么去重的演示一个实际的目标检测应用方式 写一篇 800 字左右的文章 录一段 10-15 分钟的视频 找个朋友给他讲一遍第 3 步标记卡壳点5 分钟我今天卡壳的地方 □ _________________________________ □ _________________________________ □ _________________________________第 4 步针对性复习5 分钟回到教程中卡壳的地方重新学习然后再次尝试解释 费曼学习笔记模板╔═══════════════════════════════════════════════════╗ ║ Day 15 费曼学习笔记 ║ ╠═══════════════════════════════════════════════════╣ ║ 日期__________ ║ ║ 学习时长__________ ║ ╠═══════════════════════════════════════════════════╣ ║ ║ ║ 1. 我向小白解释了 ║ ║ _______________________________________________ ║ ║ _______________________________________________ ║ ║ ║ ║ 2. 我卡壳的地方 ║ ║ □ _____________________________________________ ║ ║ □ _____________________________________________ ║ ║ ║ ║ 3. 我的通俗比喻 ║ ║ • 目标检测就像 ______ ║ ║ • 边界框就像 ______ ║ ║ • IoU 就像 ______ ║ ║ • NMS 就像 ______ ║ ║ ║ ║ 4. 我还想知道 ║ ║ _______________________________________________ ║ ║ ║ ╚═══════════════════════════════════════════════════╝ 今日总结✅ 你今天学到了1. 目标检测基础图像分类 vs 目标检测检测 定位的双重任务实际应用场景2. 核心技术边界框两种表示方法IoU交并比NMS非极大值抑制3. 实践能力边界框的可视化IoU 的计算NMS 的应用使用预训练模型4. 费曼输出能力⭐能用比喻解释目标检测能向小白说明边界框能完整讲解 NMS 流程 明日预告明天你将学习主题图像分割语义分割 内容 ✓ 比目标检测更精细 ✓ 精确到像素级别 ✓ 每个像素都分类 ✓ 医学影像分析 ✓ 自动驾驶道路识别 需要准备 ✓ 复习今天的边界框概念 ✓ 了解像素的基本概念 ✓ 保持好奇心 常见问题Q1: 目标检测和图像分类到底有什么区别图像分类: → 整张图片一个标签 → 这是猫 → 不管猫在哪里 目标检测: → 多个物体多个标签 → 这里有一只猫那里有一个人 → 既知道是什么又知道在哪里 选择 - 只需要判断场景 → 图像分类 - 需要找出所有物体 → 目标检测Q2: IoU 为什么重要IoU 是目标检测的核心指标 ✓ 衡量检测准确度 ✓ 训练时的优化目标 ✓ NMS 的关键参数 ✓ 评估模型性能 就像考试的分数 - 告诉你做得好不好 - 指导你怎么改进 - 比较谁做得更好Q3: NMS 会不会误删会有以下情况 情况 1两个物体靠得很近 → 可能被当成同一个物体 → 解决方案调低 NMS 阈值 情况 2遮挡严重 → 多个小框可能被保留 → 解决方案结合其他信息 实际应用中的权衡 - 阈值高 → 可能漏检 - 阈值低 → 可能重复 - 需要根据场景调整 最后的鼓励第十五天完成了你已经掌握了 ✓ Week 1: 机器学习基础 ✓ Week 2: 深度学习入门 ✓ Day 15: 目标检测基础 这是质的飞跃 从今天起 ✓ 你能做目标检测了 ✓ 你能解释边界框了 ✓ 你能用预训练模型了 ✓ 你能创造生动的比喻了 记住这个成就感 每天都在进步 每天都在变强 继续加油明天学习图像分割 记住 定位和识别同样重要 你现在有了这种能力 可以做更多有趣的事情了 加油我相信你一定可以的✨ 打卡模板日期___________ 学习时长_______ 小时 费曼输出次数_______ 次 今天学会了 遇到的卡壳点 如何用比喻解释的 明天的目标明天见继续加油✨ 相关链接 项目资源GitHub 仓库: https://github.com/Lee985-cmd/AI-30-Day-ChallengeCSDN 专栏: https://blog.csdn.net/m0_67081842?typeblog⭐如果觉得有帮助请给 GitHub 仓库 Star 支持本教程属于 AI 入门 30 天挑战 系列 恭喜你完成今天的学习 资源汇总完整 30 天教程CSDN 专栏 - AI 入门 30 天挑战完整代码 项目实战GitHub 仓库 ⭐欢迎 Star❓遇到问题GitHub Issues 提问 互动时间思考题今天的知识点中哪个让你印象最深刻为什么欢迎在评论区分享你的想法或疑问❤️ 如果有帮助点赞让更多人看到这篇教程⭐Star GitHub获取完整代码和项目➕关注专栏不错过后续更新分享给朋友一起学习进步明天见继续 Day 16 的学习~学习建议如果本篇教程对你有帮助欢迎Star GitHub 项目https://github.com/Lee985-cmd/AI-30-Day-Challenge留言交流你的学习困惑一起学习一起进步

更多文章