【YOLOV1】流程详解

YOLO(You Only Look Once)是一种实时物体检测系统,它将物体检测视为回归问题,直接从整张图像预测物体边界框坐标、置信度和类别概率。YOLO在速度与准确性之间取得了良好平衡,具有快速检测、背景错误率低和泛化能力强的优点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

You Only Look Once: Unified, Real-Time Object Detection

论文:https://arxiv.org/abs/1506.02640

Abstract

作者提出了一种新的物体检测方法YOLO。YOLO之前的物体检测方法主要是通过region proposal产生大量的可能包含待检测物体的 potential bounding box,再用分类器去判断每个 bounding box里是否包含有物体,以及物体所属类别的 probability或者 confidence,如R-CNN,Fast-R-CNN,Faster-R-CNN等。

YOLO不同于这些物体检测方法,它将物体检测任务当做一个regression问题来处理,使用一个神经网络,直接从一整张图像来预测出bounding box 的坐标、box中包含物体的置信度和物体的probabilities。因为YOLO的物体检测流程是在一个神经网络里完成的,所以可以end to end来优化物体检测性能。

YOLO检测物体的速度很快,标准版本的YOLO在Titan X 的 GPU 上能达到45 FPS。网络较小的版本Fast YOLO在保持mAP是之前的其他实时物体检测器的两倍的同时,检测速度可以达到155 FPS。

相较于其他的state-of-the-art 物体检测系统,YOLO在物体定位时更容易出错,但是在背景上预测出不存在的物体(false positives)的情况会少一些。而且,YOLO比DPM、R-CNN等物体检测系统能够学到更加抽象的物体的特征,这使得YOLO可以从真实图像领域迁移到其他领域,如艺术。

Introduction

YOLO之前的物体检测系统使用分类器来完成物体检测任务。为了检测一个物体,这些物体检测系统要在一张测试图的不同位置和不同尺寸的bounding box上使用该物体的分类器去评估是否有该物体。如DPM系统,要使用一个滑窗(sliding window)在整张图像上均匀滑动,用分类器评估是否有物体。

在DPM之后提出的其他方法,如R-CNN方法使用region proposal来生成整张图像中可能包含待检测物体的potential bounding boxes,然后用分类器来评估这些boxes,接着通过post-processing来改善bounding boxes,消除重复的检测目标,并基于整个场景中的其他物体重新对boxes进行打分。整个流程执行下来很慢,而且因为这些环节都是分开训练的,检测性能很难进行优化。

作者设计了YOLO(you only look once),将物体检测任务当做回归问题(regression problem)来处理,直接通过整张图片的所有像素得到bounding box的坐标、box中包含物体的置信度和class probabilities。通过YOLO,每张图像只需要看一眼就能得出图像中都有哪些物体和这些物体的位置。

如图所示,使用YOLO来检测物体,其流程是非常简单明了的: 
1、将图像resize到448 * 448作为神经网络的输入 
2、运行神经网络,得到一些bounding box坐标、box中包含物体的置信度和class probabilities 
3、进行非极大值抑制,筛选Boxes

下图是各物体检测系统的检测流程对比:

YOLO模型相对于之前的物体检测方法有多个优点:

1、YOLO检测物体非常快。 
因为没有复杂的检测流程,只需要将图像输入到神经网络就可以得到检测结果,YOLO可以非常快的完成物体检测任务。标准版本的YOLO在Titan X 的 GPU 上能达到45 FPS。更快的Fast YOLO检测速度可以达到155 FPS。而且,YOLO的mAP是之前其他实时物体检测系统的两倍以上。

2、YOLO可以很好的避免背景错误,产生false positives。 
不像其他物体检测系统使用了滑窗或region proposal,分类器只能得到图像的局部信息。YOLO在训练和测试时都能够看到一整张图像的信息,因此YOLO在检测物体时能很好的利用上下文信息,从而不容易在背景上预测出错误的物体信息。和Fast-R-CNN相比,YOLO的背景错误不到Fast-R-CNN的一半。

3、YOLO可以学到物体的泛化特征。 
当YOLO在自然图像上做训练,在艺术作品上做测试时,YOLO表现的性能比DPM、R-CNN等之前的物体检测系统要好很多。因为YOLO可以学习到高度泛化的特征,从而迁移到其他领域。

尽管YOLO有这些优点,它也有一些缺点:

1、YOLO的物体检测精度低于其他state-of-the-art的物体检测系统。 
2、YOLO容易产生物体的定位错误。 
3、YOLO对小物体的检测效果不好(尤其是密集的小物体,因为一个栅格只能预测2个物体)。

下图是各物体检测系统的检测性能对比: 

Unified Detection

YOLO将输入图像划分为S*S的栅格,每个栅格负责检测中心落在该栅格中的物体,如下图所示: 

每一个栅格预测B个bounding boxes,以及这些bounding boxes的confidence scores。 
这个 confidence scores反映了模型对于这个栅格的预测:该栅格是否含有物体,以及这个box的坐标预测的有多准。 
公式定义如下: 

如果这个栅格中不存在一个 object,则confidence score应该为0;否则的话,confidence score则为 predicted bounding box与 ground truth box之间的 IOU(intersection over union)。

YOLO对每个bounding box有5个predictions:x, y, w, h, 
and confidence。 
坐标x,y代表了预测的bounding box的中心与栅格边界的相对值。 
坐标w,h代表了预测的bounding box的width、height相对于整幅图像width,height的比例。 
confidence就是预测的bounding box和ground truth box的IOU值。 

每一个栅格还要预测C个 conditional class probability(条件类别概率):Pr(Classi|Object)。即在一个栅格包含一个Object的前提下,它属于某个类的概率。 
我们只为每个栅格预测一组(C个)类概率,而不考虑框B的数量。

注意: 
conditional class probability信息是针对每个网格的。 
confidence信息是针对每个bounding box的。

在测试阶段,将每个栅格的conditional class probabilities与每个 bounding box的 confidence相乘: 

这样既可得到每个bounding box的具体类别的confidence score。 
这乘积既包含了bounding box中预测的class的 probability信息,也反映了bounding box是否含有Object和bounding box坐标的准确度。

将YOLO用于PASCAL VOC数据集时: 
论文使用的 S=7,即将一张图像分为7×7=49个栅格每一个栅格预测B=2个boxes(每个box有 x,y,w,h,confidence,5个预测值),同时C=20(PASCAL数据集中有20个类别)。 
因此,最后的prediction是7×7×30 { 即S * S * ( B * 5 + C) }的Tensor。

Network Design

YOLO检测网络包括24个卷积层和2个全连接层,如图所示: 

其中,卷积层用来提取图像特征,全连接层用来预测图像位置和类别概率值。

YOLO网络借鉴了GoogLeNet分类网络结构。不同的是,YOLO未使用inception module,而是使用1x1卷积层(此处1x1卷积层的存在是为了跨通道信息整合)+3x3卷积层简单替代。

Training

首先利用ImageNet 1000-class的分类任务数据集Pretrain卷积层。使用上述网络中的前20 个卷积层,加上一个 average-pooling layer,最后加一个全连接层,作为 Pretrain 的网络。训练大约一周的时间,使得在ImageNet 2012的验证数据集Top-5的精度达到 88%,这个结果跟 GoogleNet 的效果相当。

将Pretrain的结果的前20层卷积层应用到Detection中,并加入剩下的4个卷积层及2个全连接。 
同时为了获取更精细化的结果,将输入图像的分辨率由 224* 224 提升到 448* 448。 
将所有的预测结果都归一化到 0~1, 使用 Leaky RELU 作为激活函数。 
为了防止过拟合,在第一个全连接层后面接了一个 ratio=0.5 的 Dropout 层。 
为了提高精度,对原始图像做数据提升。

损失函数

损失函数的设计目标就是让坐标(x,y,w,h),confidence,classification 这个三个方面达到很好的平衡。 
简单的全部采用了sum-squared error loss来做这件事会有以下不足: 
a) 8维的localization error和20维的classification error同等重要显然是不合理的。 
b) 如果一些栅格中没有object(一幅图中这种栅格很多),那么就会将这些栅格中的bounding box的confidence 置为0,相比于较少的有object的栅格,这些不包含物体的栅格对梯度更新的贡献会远大于包含物体的栅格对梯度更新的贡献,这会导致网络不稳定甚至发散。

解决方案如下: 
更重视8维的坐标预测,给这些损失前面赋予更大的loss weight, 记为 λcoord ,在pascal VOC训练中取5。(上图蓝色框) 
对没有object的bbox的confidence loss,赋予小的loss weight,记为 λnoobj ,在pascal VOC训练中取0.5。(上图橙色框) 
有object的bbox的confidence loss (上图红色框) 和类别的loss (上图紫色框)的loss weight正常取1。

对不同大小的bbox预测中,相比于大bbox预测偏一点,小box预测偏相同的尺寸对IOU的影响更大。而sum-square error loss中对同样的偏移loss是一样。 
为了缓和这个问题,作者用了一个巧妙的办法,就是将box的width和height取平方根代替原本的height和width。 如下图:small bbox的横轴值较小,发生偏移时,反应到y轴上的loss(下图绿色)比big box(下图红色)要大。

在 YOLO中,每个栅格预测多个bounding box,但在网络模型的训练中,希望每一个物体最后由一个bounding box predictor来负责预测。 
因此,当前哪一个predictor预测的bounding box与ground truth box的IOU最大,这个 predictor就负责 predict object。 
这会使得每个predictor可以专门的负责特定的物体检测。随着训练的进行,每一个 predictor对特定的物体尺寸、长宽比的物体的类别的预测会越来越好。

神经网络输出后的检测流程

非极大值抑制

获取Object Detect 结果

参考文档

https://zhuanlan.zhihu.com/p/25236464 
http://blog.youkuaiyun.com/surgewong/article/details/51864859 
https://deepsystems.io/en/reviews 
https://zhuanlan.zhihu.com/p/24916786?utm_source=qq&utm_medium=social 
https://arxiv.org/abs/1506.02640

### YOLOv5 Backbone 架构详解及实现原理 YOLOv5 的 Backbone 是整个模型的核心组件之一,主要用于从输入图像中提取特征。它的设计旨在高效地捕捉不同层次的空间和语义信息,从而为后续的 Neck 和 Head 提供高质量的特征表示。 #### 1. **CSP (Cross Stage Partial Network)** 结构的应用 YOLOv5 中引入了 CSPNet(Cross Stage Partial Network),这是一种高效的网络结构,能够显著减少计算开销并提升性能[^1]。具体来说,CSPNet 将特征图分为两个分支:一部分通过卷积操作处理,另一部分保持不变;最后再将两者拼接在一起。这种设计可以有效增加网络宽度的同时降低内存消耗。 ```python class BottleneckCSP(nn.Module): def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): super(BottleneckCSP, self).__init__() c_ = int(c2 * e) # hidden channels self.cv1 = Conv(c1, c_, 1, 1) self.cv2 = nn.Conv2d(c1, c_, 1, 1, bias=False) self.cv3 = nn.Conv2d(c_, c_, 1, 1, bias=False) self.bn = nn.BatchNorm2d(2 * c_) self.act = Mish() self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)]) def forward(self, x): y1 = self.cv3(self.m(self.cv1(x))) y2 = self.cv2(x) return self.act(self.bn(torch.cat((y1, y2), dim=1))) ``` 上述代码展示了 `BottleneckCSP` 模块的具体实现方式,它是 YOLOv5 Backbone 中的关键组成部分。 --- #### 2. **Focus 结构** Focus 是 YOLOv5 特有的一个创新模块,用于替代传统的卷积层作为初始特征提取器。它通过对输入图像进行切片操作来重新排列像素位置,从而有效地减少了计算复杂度并提升了效率。 ```python class Focus(nn.Module): def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True): # ch_in, ch_out, kernel, stride, padding, groups super(Focus, self).__init__() self.conv = Conv(c1 * 4, c2, k, s, p, g, act) def forward(self, x): # x(b,c,h,w) -> y(b,4c,h/2,w/2) return self.conv( torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1)) ``` 这段代码定义了 Focus 层的功能逻辑,其中输入张量被分割成四个子区域后再组合起来送入下一个卷积层。 --- #### 3. **CBS 模块的作用** 虽然 CBS 模块最初是在 YOLOv7 中提出的概念[^2],但在理解 YOLOv5 的 Backbone 设计时也可以借鉴类似的思路。CBS 实际上代表了一种基础构建单元——Convolution-BatchNorm-SiLU 组合形式,在多个版本的 YOLO 家族成员里广泛存在。对于 YOLOv5 来说,这样的标准化流程有助于加速训练过程以及提高泛化能力[^3]。 --- #### 总结 综上所述,YOLOv5 的 Backbone 部分采用了先进的 CSP 结构与独特的 Focus 切片技术相结合的方式来进行特征抽取工作。这些方法不仅保证了良好的检测效果,还兼顾到了实际应用中的运行速度需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值