现代目标检测算法:YOLO全解析与实践
立即解锁
发布时间: 2025-09-01 01:57:41 阅读量: 13 订阅数: 21 AIGC 


现代计算机视觉与PyTorch
### 现代目标检测算法:YOLO 全解析与实践
#### 1. 目标检测算法对比
在目标检测领域,Faster R - CNN 是一种常用的算法。之前的代码运行结果显示,生成一张图像的预测结果,Faster R - CNN 需要约 1.5 秒,而现在的方法仅需约 400 毫秒。Faster R - CNN 使用锚框在图像上滑动,识别可能包含物体的区域,然后进行边界框修正。然而,它存在一些局限性:
- **信息不完整**:在全连接层,仅将检测区域的 RoI 池化输出作为输入。当区域不能完全包含物体时(物体超出区域建议的边界框),网络由于未看到完整图像,只能猜测物体的真实边界。
- **速度较慢**:Faster R - CNN 有两个网络,即区域提议网络(RPN)和最终预测物体类别及边界框的网络,这导致其速度较慢。
而 YOLO(You Only Look Once)及其变体是一种杰出的目标检测算法,它能一次性完成物体类别检测和区域修正,无需单独的 RPN。
#### 2. YOLO 工作原理
##### 2.1 数据准备
为了训练 YOLO 模型,需要为给定图像创建真实标签(ground truth),具体步骤如下:
1. **确定真实边界框**:考虑一张带有红色真实边界框的图像。
2. **划分网格**:将图像划分为 N x N 个网格单元,这里以 N = 3 为例,即划分为 3 x 3 的网格。
3. **确定负责单元**:找出包含至少一个真实边界框中心的网格单元,例如在 3 x 3 的网格图像中,可能是 b1 和 b3 单元。
4. **创建真实标签**:包含真实边界框中点的单元负责预测物体的边界框,为每个单元创建对应的真实标签。
5. **输出真实标签**:每个单元的输出真实标签包括物体存在概率(pc)等信息。pc 表示该单元包含物体的概率。
6. **计算边界框参数**:
- **bx 和 by**:以网格单元为参考,将其归一化到 0 到 1 的范围。bx 和 by 是真实边界框中点相对于网格单元图像的位置。例如,若真实边界框中点距离原点 0.5 个单位,则 bx = 0.5,by = 0.5。
- **bw 和 bh**:bw 是边界框宽度与网格单元宽度的比值,bh 是边界框高度与网格单元高度的比值。
7. **预测类别**:若有三个类别(如卡车、汽车、公交车),则预测该单元包含任意一个类别的物体的概率。由于 pc 已表示单元是否包含物体,这里不需要背景类别。
8. **构建网格输出**:
- 对于不包含物体的单元,如 a3 单元,其第一个输出(pc - 物体存在分数)为 0,其余值无关紧要。
- 对于包含物体的单元,如 b1 单元,其输出包含 bx、by、bw、bh 值以及类别信息。每个单元可获取 8 个输出,因此 3 x 3 的网格可获取 3 x 3 x 8 个输出。
##### 2.2 后续步骤
1. **定义模型**:输入为图像,输出为 3 x 3 x 8,真实标签如上述步骤所定义。
2. **考虑锚框定义真实标签**:在实际情况中,一个网格单元可能包含多个物体,这会导致真实标签不准确。为避免这种情况,可增加网格单元数量,如使用 19 x 19 的网格。但仍可能存在问题,此时锚框就派上用场了。例如,有两个锚框,一个高大于宽(对应人),另一个宽大于高(对应汽车)。每个单元的输出是两个锚框预期输出的拼接,预期输出形状为 N x N x 类别数 x 锚框数。
3. **定义损失函数**:计算模型损失时,需注意以下几点:
- 当物体存在分数低于某个阈值时(对应不包含物体的单元),不计算回归损失和分类损失。
- 若单元包含物体,要确保不同类别之间的分类尽可能准确。
- 若单元包含物体,边界框偏移应尽可能接近预期。由于宽度和高度的偏移可能比中心偏移大很多(中心偏移范围在 0 到 1 之间,而宽度和高度偏移无此限制),因此对宽度和高度偏移取平方根以降低权重。
损失计算公式如下:
\[
L_{loc}=\lambda_{coord}\sum_{i = 0}^{S^{2}}\sum_{j = 0}^{B}1_{ij}^{obj}[(x_{i}-\hat{x}_{i})^{2}+(y_{i}-\hat{y}_{i})^{2}+(\sqrt{w_{i}}-\sqrt{\hat{w}_{i}})^{2}+(\sqrt{h_{i}}-\sqrt{\hat{h}_{i}})^{2}]
\]
\[
L_{cls}=\sum_{i = 0}^{S^{2}}\sum_{j = 0}^{B}(1_{ij}^{obj}+\lambda_{noobj}(1 - 1_{ij}^{obj}))(C_{ij}-\hat{C}_{ij})^{2}+\sum_{i = 0}^{S^{2}}1_{i}^{obj}\sum_{c\in classes}(p_{i}(c)-\hat{p}_{i}(c))^{2}
\]
\[
L = L_{loc}+L_{cls}
\]
其中:
- \(\lambda_{coord}\) 是回归损失的权重。
- \(1_{ij}^{obj}\) 表示单元是否包含物体。
- \(p_{i}(c)\) 对应预测的类别概率。
- \(C_{ij}\) 表示物体存在分数。
整体损失是分类损失和回归损失的总和。
#### 3. 安装 Darknet
为了在自定义数据集上训练 YOLO,需要安装 Darknet,具体步骤如下:
1. **拉取 Git 仓库**:
```python
!git clone https://github.com/AlexeyAB/darknet
%cd darknet
```
2. **重新配置 Makefile 文件**:
```python
!sed -i 's/OPENCV=0/OPENCV=1/' Makefile
# 若没有 GPU,请注释以下 3 行
!sed -i 's/GPU=0/GPU=1/' Makefile
!sed -i 's/CUDNN=0/CUDNN=1/' Makefile
!sed -i 's/CUDNN_HALF=0/CUDNN_HALF=1/' Makefile
``
```
0
0
复制全文
相关推荐










