【YOLO系列】 YOLOv1 目标检测算法原理详解

本博客部分笔记来源参考 bilibili 炮哥带你学 https://www.bilibili.com/video/BV1WT421r72w?spm_id_from=333.788.player.switch\&vd_source=adac1e72946f55515de8ee1fb8b6571d\&p=3

背景

目标检测涉及两个步骤:

  1. 检测目标位置
  2. 对目标物体进行分类

主流算法涉及两种:

  1. 单阶段模型: YOLO 快
  2. 双阶段模型: faster RCNN

2015年Joseph Redmon首次提出You Only Look Once, 把目标检测看成一个回归问题,在一个神经网络中同时预测目标的位置和类别,2016年推出v2, 2018年推出v3。

Yolov1网络结构

通过对网络结构的观察,不难发现,在输出层7x7x30前面,跟传统的CNN架构是及其相似的,去掉softmax替换成7x7x30的输出层,就变成了yolo。

类似的,我们可以将resnet等backbone放进来,接入一个7x7x30,改成目标检测模型。

一些细节:

  1. 在输出层前面有两个全连接层,实际上这一块有一部分弊端,参数量过大会导致过拟合,因此较多网络架构在输出时移除了全连接层,这也是v2优化的一个点。

  2. 卷积结构上依旧采取了主流做法,对size做逐步下采样,通道数逐步增加作为特征提取

  3. 除了最后一层用了线性激活函数,其他都是LeakyRelu。

  4. Dropout和数据增强来防止过拟合。

Size 计算

H = (H+2P - K)/ S + 1

output_H = (448+2x3-7) / 2 + 1 = 447/2 + 1 = 224.5 = 224

7x7x30的输出

  1. 7x7可以理解成把图像划分成7x7个区域,30可以理解成每个区域有长度为30的向量输出(实际内容为2个区域(x,y,w,h,c),20个类别的概率值( p ))

  2. 对于每个grid cell:

1)预测B个边界框(v1是2个)

2)每个边界框包含5个元素:中心坐标x,y; 检测框的宽高:w, h; 框的置信度c。

3)类别概率

结果解析(x,y,w,h)

前面我们得到了7x7x30的结果,并且知道了7x7可以理解成将原图划分成49个小方格,并且每个小方格是得到全局信息的。 而在每个小方格的长度为30的向量中,里面有两个(x,y,w,h,c),以及20个类别的概率。

  1. 这里x,y的坐标代表的是每个小方格里物体中心位置的坐标。 逻辑与opencv一致,左上角为(0,0),注意每个小方格的左上角都是(0,0)。
  2. x,y的坐标是归一化后的坐标值,在0-1的范围内,所以需要反归一化才能得到坐标。
  3. w,h 是指bounding box 的宽和高,也是归一化到了0-1之间(相较于全图的size 448)

置信度

IOU

交并比(Intersection Over Union). IOU计算的是预测的边框和真实边框的交集和并集的比值。

IoU = 两个框"重叠得有多像"

IoU = 并集面积 / 交集面积

交集(Intersection):两个框重叠的那一块
并集(Union):两个框加起来的总面积(重叠部分只算一次)

IoU 值 含义
1.0 完全重合
0.7+ 非常好
0.5 勉强可接受(常见阈值)
< 0.5 定位不准
0 完全没对上

置信度c

  1. 代表当前box是否有对象的概率Pr(Object), 注意是有对象而不是某个类别的对象。 用来区分是背景还是有物体。
  2. 也代表当box有物体的时候,它自己预测的box与真实box之间的IOU。

实际上,test的时候,我们也没有真实box传给模型,所以这里的置信度代表模型框出物体的自信程度。

C = P r ( O b j e c t ) ∗ I O U C = Pr(Object)*IOU C=Pr(Object)∗IOU

概率值

概率值就是softmax后面的值,20个类别的概率值和为1。

类别置信度

C c l s = P r ( C l a s s i ∣ O b j e c t ) P r ( O b j e c t ) ∗ I O U = C ∗ P r ( C l a s s i ) C_{cls} =Pr(Class_i|Object) Pr(Object)*IOU = C*Pr(Class_i) Ccls=Pr(Classi∣Object)Pr(Object)∗IOU=C∗Pr(Classi)

类别置信度,代表一种自信程度。框出的box内确实有物体,并且是该类别,包括整个物体(IOU)的自信程度。

NMS 非极大值抑制

每个小方格都会有2个框,所以大概率模型每个预测的目标有多个bounding box,我们需要筛选。

NMS 的作用:

同一个目标,只保留"最靠谱"的那个框,把其它高度重叠的框删掉。

NMS 是怎么做的?(核心 4 步)

1. 按类别分开处理

NMS 是"按类别"做的

比如:

所有 chicken 框一组

所有 basketball 框一组

不同类别之间 互不影响

类别置信度<0.5可以先过滤掉

2. 选置信度最高的框

在某一类(比如 chicken)里:

找到 类别置信度最高的那个框

记为 box_best

先保留它

这个框是"当前最可信的"

3. 算 IOU,删掉"太像"的框

把 box_best

和 剩下所有同类别的框 计算 IOU:

如果

I O U > 阈值(通常 0.5 ) IOU>阈值(通常 0.5) IOU>阈值(通常0.5)

说明:它们框的是同一个目标

结果:只保留 box_best

其它框 全部删掉

这一步就是"抑制(Suppression)"

4. 重复,直到没有框了

在剩下的框中

再选一个置信度最高的

重复上面的 IOU 判断

直到处理完所有框

损失函数

坐标损失+置信度损失+类别损失

  1. YOLOv1 把目标检测当成回归问题,一个 grid 只负责预测中心点落在该 grid 内的目标,其余 grid 即使框到了也不参与坐标学习
  2. 每个 grid 会预测 B 个框,但只有与 GT IOU 最大的那个框被指定为"负责框",只有它才计算坐标和有目标置信度损失
  3. 坐标损失对 (x,y,w,h) 使用 MSE,其中 (w,h) 取平方根是为了降低大框误差、提高小目标的相对权重
  4. 置信度在 YOLOv1 中被定义为 ( P ( object ) × I O U P(\text{object}) \times IOU P(object)×IOU),有目标时实际学习的是 IOU,本质是在回归定位质量
  5. 绝大多数预测框是背景,如果不加区分会淹没梯度,因此无目标置信度损失 单独设置权重 ( λ n o o b j \lambda_{noobj} λnoobj) 来压低影响
  6. 分类损失只在 grid 内确实存在目标时 计算,并且是对类别概率做 MSE,而不是交叉熵
  7. 整个 loss 是多项加权和,其中 ( λ c o o r d \lambda_{coord} λcoord) 用来强调定位的重要性,防止被分类和置信度项主导训练
  8. YOLOv1 的 loss 设计简单但耦合严重,定位、分类和置信度互相干扰,这是后续 YOLOv2+ 改进的核心动机

L =    λ coord ∑ i = 1 S 2 ∑ j = 1 B 1 i j obj [ ( x i − x ^ i ) 2 + ( y i − y ^ i ) 2 ] + λ coord ∑ i = 1 S 2 ∑ j = 1 B 1 i j obj [ ( w i − w ^ i ) 2 + ( h i − h ^ i ) 2 ] + ∑ i = 1 S 2 ∑ j = 1 B 1 i j obj ( C i − C ^ i ) 2 + λ noobj ∑ i = 1 S 2 ∑ j = 1 B 1 i j noobj ( C i − C ^ i ) 2 + ∑ i = 1 S 2 1 i obj ∑ c = 1 C ( p i ( c ) − p ^ i ( c ) ) 2 \begin{aligned} \mathcal{L} =&\;\lambda_{\text{coord}} \sum_{i=1}^{S^2} \sum_{j=1}^{B} \mathbb{1}{ij}^{\text{obj}} \Big[ (x_i-\hat{x}i)^2 +(y_i-\hat{y}i)^2 \Big] \\ &+\lambda{\text{coord}} \sum{i=1}^{S^2} \sum{j=1}^{B} \mathbb{1}{ij}^{\text{obj}} \Big[ (\sqrt{w_i}-\sqrt{\hat{w}i})^2 +(\sqrt{h_i}-\sqrt{\hat{h}i})^2 \Big] \\ &+ \sum{i=1}^{S^2} \sum{j=1}^{B} \mathbb{1}{ij}^{\text{obj}} (C_i-\hat{C}i)^2 \\ &+ \lambda{\text{noobj}} \sum_{i=1}^{S^2} \sum_{j=1}^{B} \mathbb{1}{ij}^{\text{noobj}} (C_i-\hat{C}i)^2 \\ &+ \sum{i=1}^{S^2} \mathbb{1}{i}^{\text{obj}} \sum_{c=1}^{C} (p_i(c)-\hat{p}_i(c))^2 \end{aligned} L=λcoordi=1∑S2j=1∑B1ijobj[(xi−x^i)2+(yi−y^i)2]+λcoordi=1∑S2j=1∑B1ijobj[(wi −w^i )2+(hi −h^i )2]+i=1∑S2j=1∑B1ijobj(Ci−C^i)2+λnoobji=1∑S2j=1∑B1ijnoobj(Ci−C^i)2+i=1∑S21iobjc=1∑C(pi(c)−p^i(c))2

坐标损失

x,y都是mse,对 w,h 开根号,是为了让"小框更敏感、大框更稳",避免大目标主导 loss。

举例来说,大框宽度从 200 变到 210 和小框从 20 变到 30,在像素上都是 10,但对小框是灾难、对大框影响很小

λ coord \lambda_{\text{coord}} λcoord 是5, λ noobj \lambda_{\text{noobj}} λnoobj是0.5,避免过度学习到没有目标的区域(大多数)

置信度损失

C i C_i Ci指的是预测和真实框的IOU

概率损失

只算有对象的

训练

v1的训练有两个阶段

  1. 在ImageNet上先预训练分类模型(224的输入)
  2. 网络输入改成448,去除全局平均池化并加入4个卷积层和2个全连接层,输出层改为7x7x30,继续finetuning(135轮).

优缺点

优点

  1. 快,不需要复杂组件
  2. 全图检测,不需要滑动窗口,预选区技术

缺点

  1. 准确率不够高(当然,后期够高了)
  2. 小物体表现差
  3. 可以检测的目标少 (最多7x7个结果)
相关推荐
2301_765703142 小时前
C++中的职责链模式实战
开发语言·c++·算法
StandbyTime2 小时前
《算法笔记》学习记录-第一章
c++·算法·算法笔记
近津薪荼2 小时前
优选算法——双指针8(单调性)
数据结构·c++·学习·算法
格林威2 小时前
Baumer相机铆钉安装状态检测:判断铆接是否到位的 5 个核心算法,附 OpenCV+Halcon 的实战代码!
人工智能·opencv·算法·计算机视觉·视觉检测·工业相机·堡盟相机
星空露珠3 小时前
速算24点检测生成核心lua
开发语言·数据库·算法·游戏·lua
FL16238631293 小时前
MMA综合格斗动作检测数据集VOC+YOLO格式1780张16类别
人工智能·yolo·机器学习
happygrilclh3 小时前
高压高频电源的pid算法
算法
格林威3 小时前
Baumer相机铸件气孔与缩松识别:提升铸造良品率的 6 个核心算法,附 OpenCV+Halcon 实战代码!
人工智能·opencv·算法·安全·计算机视觉·堡盟相机·baumer相机
葫三生3 小时前
存在之思:三生原理与现象学对话可能?
数据库·人工智能·神经网络·算法·区块链