【目标检测】 YOLO

本文主要介绍了YOLO v1目标检测算法。首先明确目标检测任务及方法分类,回顾one - stage方法。接着阐述YOLO检测思路,包括图像划分、框框预测和类别预测。还介绍了网络结构、损失函数,损失函数含框体位置、置信度和类别预测三部分损失。最后分析了算法优缺点。

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

YOLO v1

论文

前言

这周的目标是把目标检测的算法复习一下,同时研读下CVPR2019目标检测的新文章。

首先我们明确下 目标检测要完成一个什么样的任务。目标检测顾名思义就是检测图像中哪里有我们要检测的物体,这些物体是什么。“哪里有我们要检测的物体”,进一步抽象就是定位,确定物体在哪里;“这些物体是什么”,进一步抽象就是分类,确定物体的类别。看图说话 ↓ \downarrow

定位就是把物体框出来,分类就是确定物体的类别。

根据目标检测要完成的任务,目标检测的方法也主要分两类,one-stage和two-stage。one-stage是一步解决定位和分类的问题,主要网络YOLO、SSD、YOLO-v2、YOLO-v3等;two-stage是定位,分类两步走,主要网络是R-CNN家族,有R-CNN、Fast R-CNN、Faster R-CNN、Mask R-CNN等。本周回顾one-stage的方法。

YOLO目标检测的思路

YOLO全称是 You Only Look Once。

第一步,将图像划分成 S × S S×S S×S个网格,图片中物体的中心落在某一个网格上,那么该物体与该网格建立关系,该网格对该物体负责!每个物体都能找到对应的网格。

第二步,每个网格预测B个框框(bounding boxes)的位置和每个框框对应的置信度(confidence)。表示一个框框需要4个参数,中心点坐标( x , y x,y x,y)和框框的宽高( w , h w,h w,h)。这里的置信度指该框框圈住物体的可信程度。在测试阶段,它直接表示预测框体的可信度,用来执行NMS算法;在训练阶段,它需要制作标签以用于训练。计算包括两项,一是框框对应的网格包含物体的可能性 P r ( O b j e c t ) Pr(Object) Pr(Object);二是框框和物体真实框框的重叠程度,用IoU度量。因此置信度的计算公式为 P r ( O b j e c t ) ⋅ I o U Pr(Object)\cdot IoU Pr(Object)IoU。如果该网格不包含任何物体,那么 P r ( O b j e c t ) = 0 Pr(Object)=0 Pr(Object)=0,该框框的置信度也为0;如果该网格包含物体,那么 P r ( O b j e c t ) = 1 Pr(Object)=1 Pr(Object)=1,则该框框的置信度为IoU的值。

第三步,预测包含物体的网格所属的类别,即计算网格属于各个类别的条件概率, P r ( C l a s s i ∣ O b j e c t ) Pr(Class_i|Object) Pr(ClassiObject)。结合第二步得到的置信度,我们可以得到每一个框框对每一个类别的置信度。
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 = P r ( c l a s s i ) ⋅ I o U Pr(Class_i|Object) \cdot Pr(Object) \cdot IoU = Pr(class_i) \cdot IoU Pr(ClassiObject)Pr(Object)IoU=Pr(classi)IoU

第二步完成物体的定位,第三步完成了物体的分类。其实第二、第三步是在一次性完成,此处只是为了便于理解,分点说明。

按照YOLO的检测思路,总结一下我们的网络应该输出什么内容。先看第二步,一个网格需要B个框框,而一个框框需要 x , y , w , h x,y,w,h x,y,w,h四个参数定位参数和一个置信度,共计5个参数,因此共计 S ⋅ S ⋅ B ⋅ 5 S \cdot S \cdot B \cdot 5 SSB5;再看第三步,一个网格要预测 C C C个类别,共计 S ⋅ S ⋅ C S \cdot S \cdot C SSC。所以!最终的输出的维度是 S ⋅ S ⋅ ( B ⋅ 5 + C ) S \cdot S \cdot (B\cdot 5 + C) SS(B5+C)

网络结构

网络结构比较常规,毕竟本文关键在于思路!想法!
连续的卷积池化,最后接两个全连接层。设置的参数 S = 7 , B = 2 , C = 20 S=7, B=2, C=20 S=7,B=2C=20,因此模型的输出为 7 × 7 × 30 7×7×30 7×7×30

损失函数

个人觉得损失函数部分是这篇文章的精髓之处,表达式如下:
λ  coord  ∑ i = 0 S 2 ∑ j = 0 B l i j o b j [ ( x i − x ^ i ) 2 + ( y i − y ^ i ) 2 ] + λ  coord  ∑ i = 0 S 2 ∑ j = 0 B l i j o b j [ ( w i − w ^ i ) 2 + ( h i − h ^ i ) 2 ] + ∑ i = 0 S 2 ∑ j = 0 B l i j o b j ( C i − C ^ i ) 2 + λ  noobj  ∑ i = 0 S 2 ∑ j = 0 B l i j  noobj  ( C i − C ^ i ) 2 + ∑ i = 0 S 2 l i o b j ∑ c ∈  classes  ( p i ( c ) − p ^ i ( c ) ) 2 \lambda_{\text { coord }} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{l}_{i j}^{\mathrm{obj}}\left[\left(x_{i}-\hat{x}_{i}\right)^{2}+\left(y_{i}-\hat{y}_{i}\right)^{2}\right] \\ +\lambda_{\text { coord }} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{l}_{i j}^{\mathrm{obj}}\left[\left(\sqrt{w_{i}}-\sqrt{\hat{w}_{i}}\right)^{2}+\left(\sqrt{h_{i}}-\sqrt{\hat{h}_{i}}\right)^{2}\right] \\ +\sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{l}_{i j}^{\mathrm{obj}}\left(C_{i}-\hat{C}_{i}\right)^{2}\\ +\lambda_{\text { noobj }} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{l}_{i j}^{\text { noobj }}\left(C_{i}-\hat{C}_{i}\right)^{2}\\ +\sum_{i=0}^{S^{2}} \mathbb{l}_{i}^{\mathrm{obj}} \sum_{c \in \text { classes }}\left(p_{i}(c)-\hat{p}_{i}(c)\right)^{2} λ coord i=0S2j=0Blijobj[(xix^i)2+(yiy^i)2]+λ coord i=0S2j=0Blijobj[(wi w^i )2+(hi h^i )2]+i=0S2j=0Blijobj(CiC^i)2+λ noobj i=0S2j=0Blij noobj (CiC^i)2+i=0S2liobjc classes (pi(c)p^i(c))2

损失函数共有三部分,框体位置损失(第一二项),框体置信度损失(第三四项),网格类别损失(第五项)。接下一个一个看。

框体位置损失

先看第一项:
λ  coord  ∑ i = 0 S 2 ∑ j = 0 B l i j o b j [ ( x i − x ^ i ) 2 + ( y i − y ^ i ) 2 ] \lambda_{\text { coord }} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{l}_{i j}^{\mathrm{obj}}\left[\left(x_{i}-\hat{x}_{i}\right)^{2}+\left(y_{i}-\hat{y}_{i}\right)^{2}\right] λ coord i=0S2j=0Blijobj[(xix^i)2+(yiy^i)2]
这一项计算框体中心点坐标损失。

  • λ c o o r d \lambda_{coord} λcoord是赋予该项损失的权重,权重越大,表明我们希望该项能优化的更好
  • ∑ i = 0 S 2 ∑ j = 0 B \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} i=0S2j=0B表示每一个预测框体都要计算损失,总共要计算 S 2 ⋅ B S^2\cdot B S2B个框体的损失
  • l i j o b j \mathbb{l}_{i j}^{\mathrm{obj}} lijobj表示哪些预测结果需要计算loss。作者定义了一类预测框体,如果有物体的中心落在网格 i i i中,并且第 j j j个预测框体是 B B B个预测框体中与实际框体IoU最大的框体,那么称 j j j框体对该网格负责(reasonable),对应地 l i j o b j = 1 \mathbb{l}_{i j}^{\mathrm{obj}}=1 lijobj=1;否则为0。
  • x i , y i x_i,y_i xi,yi是物体框体中心点坐标的实际值,是经过归一化的的。归一化的方法如图所示。

图中的网格划分是 3 × 3 3×3 3×3,框体的中心落在中间的网格。 x , y x,y x,y是框体中心点在中间网格中的相对位置,值介于 0 , 1 0,1 0,1之间。

再看第二项:
λ  coord  ∑ i = 0 S 2 ∑ j = 0 B l i j o b j [ ( w i − w ^ i ) 2 + ( h i − h ^ i ) 2 ] \lambda_{\text { coord }} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{l}_{i j}^{\mathrm{obj}}\left[\left(\sqrt{w_{i}}-\sqrt{\hat{w}_{i}}\right)^{2}+\left(\sqrt{h_{i}}-\sqrt{\hat{h}_{i}}\right)^{2}\right] λ coord i=0S2j=0Blijobj[(wi w^i )2+(hi h^i )2]
这一项计算框体宽高的损失。

  • w i , h i w_i,h_i wi,hi同样是经过归一化的值,归一化的方法是除以图片的宽和高
  • 此处对宽和高取平方根是因为同样的损失对于大小不同的框体精度的影响不一致。大框体收到的影响小于小框体。例如原来w=10,h=20,预测出来w=8,h=22,跟原来w=3,h=5,预测出来w1,h=7相比,损失大小都是 2 2 + 2 2 = 8 2^2+2^2=8 22+22=8,但其实前者的误差比后者小。加上根号后,前者: ( 10 − 8 ) 2 + ( 20 − 22 ) 2 = 0.159 (\sqrt{10}-\sqrt{8})^2 + (\sqrt{20}-\sqrt{22})^2=0.159 (10 8 )2+(20 22 )2=0.159, 后者: ( 3 − 1 ) 2 + ( 5 − 7 ) 2 = 0.704 (\sqrt{3}-\sqrt{1})^2 + (\sqrt{5}-\sqrt{7})^2=0.704 (3 1 )2+(5 7 )2=0.704,前者比后者小,能正确度量!

框体置信度损失

先看第一项
∑ i = 0 S 2 ∑ j = 0 B l i j o b j ( C i − C ^ i ) 2 \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{l}_{i j}^{\mathrm{obj}}\left(C_{i}-\hat{C}_{i}\right)^{2} i=0S2j=0Blijobj(CiC^i)2

  • l i j o b j \mathbb{l}_{i j}^{\mathrm{obj}} lijobj表示的含义和上一项一致。
  • C i C_i Ci是框体的置信度真实值,大小等于预测框体与实际框体的IoU。
  • 这一项计算的是对网格负责的框体的损失。

再看第二项
λ  noobj  ∑ i = 0 S 2 ∑ j = 0 B l i j  noobj  ( C i − C ^ i ) 2 \lambda_{\text { noobj }} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{l}_{i j}^{\text { noobj }}\left(C_{i}-\hat{C}_{i}\right)^{2} λ noobj i=0S2j=0Blij noobj (CiC^i)2

  • 这一项计算的是不对网格负责的框体的损失
  • 由于不对网格负责的框体的数量一般来说都大于对网格负责框体的损失,因此为它增加一个权重 λ n o o b j \lambda_{noobj} λnoobj,文中取值为0.5

类别预测损失
∑ i = 0 S 2 l i o b j ∑ c ∈  classes  ( p i ( c ) − p ^ i ( c ) ) 2 \sum_{i=0}^{S^{2}} \mathbb{l}_{i}^{\mathrm{obj}} \sum_{c \in \text { classes }}\left(p_{i}(c)-\hat{p}_{i}(c)\right)^{2} i=0S2liobjc classes (pi(c)p^i(c))2

  • ∑ i = 0 S 2 l i o b j \sum_{i=0}^{S^{2}} \mathbb{l}_{i}^{\mathrm{obj}} i=0S2liobj 只计算有物体中心的网格。
  • p i ( c ) p_i(c) pi(c)网格所属类别对应的独热编码,0或1.
  • 这里没有采用交叉熵,将它当成回归问题,直接差值的平方作为损失。

算法优缺点

优点

  • 快。将物体检测问题作为回归问题进行求解,网络结构简单,在保证检测准确率的情况下,能达到45FPS的检测速度(TianX)
  • 背景误检率低。YOLO在训练和推理过程中能‘看到’整张图像的整体信息,而基于region proposal的物体检测方法(如rcnn/fast rcnn),在检测过程中,只‘看到’候选框内的局部图像信息。因此,若当图像背景(非物体)中的部分数据被包含在候选框中送入检测网络进行检测时,容易被误检测成物体。测试证明,YOLO对于背景图像的误检率低于fast rcnn误检率的一半。

缺点

  • 由于YOLO默认同一个网格中框体属于同一种物体,因此当网格内出现不同物体时,效果差;
  • 由于YOLO一个网格只能预测两个物体,因此网格中出现多余两个物体时,效果差
  • 定位精度较差,模型召回率较低。
### YOLO算法在目标检测中的应用 YOLO(You Only Look Once)是一种先进的实时目标检测框架,在计算机视觉领域得到了广泛的应用。其核心思想是将目标检测视为单一的回归问题,直接从图像像素到边界框坐标和类别的映射[^1]。 #### 1. YOLO算法的核心原理 YOLO算法的主要特点是快速性和高效率。它通过单次前向传播即可完成整个图像的目标检测任务,而不是像传统的滑动窗口方法那样多次扫描图像[^2]。具体来说,YOLO将输入图像划分为S×S的网格结构,并为每个网格单元预测B个边框及其置信度分数以及C种类别概率。这种设计使得YOLO能够在一次推理过程中同时处理多个目标。 #### 2. YOLO算法的具体实现流程 以下是YOLO算法的一个典型实现过程: - **模型配置** 需要调整`yolo.py`文件中的关键参数设置。其中,`model_path`应指向存储有预训练权重的`.h5`文件位置;而`classes_path`需指定类别名称列表所在的文本文件地址,该文件定义了模型可以识别的对象类别[^3]。 - **预测阶段** 完成上述配置后,可以通过执行`predict.py`脚本来加载已训练好的模型并对新图片实施预测操作。在此期间,用户只需提供一张待测图像作为输入数据源,程序便会自动调用先前设定好的模型架构来进行分析并返回最终的结果可视化图示。 ```python from yolo import YOLO import cv2 def detect_image(image_path): # 初始化YOLO实例 yolo_model = YOLO(model_path='logs/trained_weights.h5', classes_path='model_data/cls_classes.txt') # 加载测试图像 image = cv2.imread(image_path) # 进行目标检测 result_image, detections = yolo_model.detect_image(image) # 显示结果 cv2.imshow('Detection Result', result_image) cv2.waitKey(0) cv2.destroyAllWindows() # 调用函数 detect_image('test.jpg') ``` 此代码片段展示了如何利用自定义路径初始化YOLO对象,并读取一幅静态照片以供进一步处理。 --- #### 3. YOLO的优势与局限性 尽管YOLO因其速度优势备受青睐,但也存在一些不足之处: - **优点**: 极高的运行效率使其非常适合于视频流或其他需要实时反馈的应用场景。 - **缺点**: 对小型物体或者密集排列的目标可能表现不佳,因为它的空间分辨率较低且依赖固定大小的网格划分策略。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值