系列文章:
死磕YOLO系列,YOLOv2的自我修养
YOLO 是我非常喜欢的目标检测算法,堪称工业级的目标检测,能够达到实时的要求,它帮我解决了许多实际问题。


这就是 YOLO 的目标检测效果。它定位了图像中物体的位置,当然,也能预测物体的类别。

之前我有写博文介绍过它,但是每次重新读它的论文,我都有新的收获,为此我准备写一个系列的文章来详尽分析它。这是第一篇,从它的起始 YOLOv1 讲起。

YOLOv1 的论文地址:https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf

建议没有看过原论文的都应该好好看看。

YOLO 预测时,很简单。

1.缩放输入的图片
2.将图片送入到卷积神经网络中进行预测
3.通过预测的结果进行置信度的阈值处理,得到最终的结果。

本文围绕:

  1. YOLO 为什么能检测目标?
  2. YOLO 长什么样子?
  3. YOLO 如何训练?

三大问题来详细展开,为此我类比为 YOLO 的大脑、躯干和手脚。

1. 大脑,为什么能检测目标?

YOLO 是 One-Stage (单阶段) 检测算法,它只需要看图片一次,就可以预测图片中所有的物体边框。

我个人有一个形象的比喻,那就是撒渔网。

一个渔网撒下去,所有的鱼儿都要捕获。

而实际上,YOLO 真的有类似渔网的操作。

YOLO 把一张图片划分成了 SxS 个格子。

这里的 S 不固定,可以根据实际情况由开发者自主决定。


论文中,S 取值为 7,所以整张图片被分割成 7*7=49 个格子(Cell)。

这些格子像不像渔网的网眼呢?

那么,这些 Cell 是干什么用的呢?为什么要设置这么多的 Cell ?

这些 Cell 每个 Cell 都会预测 B 个 bbox。在论文中 B 取值为 2。

所以,一张图片经 YOLO 跑一遍,就会产生 98 个 bbox。


有同学可能会思考:

这么多 bbox,比目标的个数还要多,怎么选择呢?

以上面的图片为例:


图片中有狗、自行车、汽车 3 个目标,但是预测到的 bbox 有 98 个之多,最终肯定只能从 98 个 bbox 中选择 3 个。

那么,怎么操作呢?

分 2 步走。

第一步,有选择的响应 cell。

总共有 49 个 cell,但是并不是每一个 cell 的预测都有意义,我们需要找出有意义的 cell。

那么哪些 cell 算是有意义呢?

先来看看一个叫做 Confidence 可信度的概念。

每个 Cell 预测 B 个 bbox,还有每个 bbox 对应的 Confidence。

Confidence 公式定义如下:
Confidence=Pr(Obj)∗IOUpredtruthConfidence = Pr(Obj)*IOU_{pred}^{truth} Confidence=Pr(Obj)∗IOUpredtruth​

其中 Pr(Obj)Pr(Obj)Pr(Obj) 取值只有 0 和 1 两种可能性,代表一个 cell 中是否存在物体。

下面对这个概念详细解释一下。

假设:我们要检测的目标只有狗、汽车、自行车 3 种,那么其他的物体都被当成背景。


在上面的图片中,00,01,02 这些 cell 不包含任何的目标,所以它们的 Pr(Obj)Pr(Obj)Pr(Obj) 为0,所以 Confidence 也为 0.

10 和 20 两个 cell 因为包含了自行车的一部分,所以它们的 Pr(Obj)Pr(Obj)Pr(Obj) 为 1,它们的 Confidence 实质上就是 bbox 和 groundtruth 的 IOU。

另外怎么判断某个 cell 中有没有包含 Object 呢?

这其实是通过 label 中的 groundtruth 在线算出来的。

因此,一张图片经过 YOLO 跑一遍后,除了预测出 98 个 bbox,还会给出 49 个 cell 的 confidence.

所以,那些 confidence 不为 0 的 cell 都算作有意义。

不过,还可以更进一步。

一个 Object 可能覆盖很多个 Cell。

我们还需要从中选择一个 Cell,作为代表,这个 Cell 就负责(responsible)此 Object 的预测。


我们看上图。

狗的 groundtruth 覆盖了总共 15 个 Cell,那么哪个 cell 否则这条狗呢?


答案就是我上图标示出来的 cell。

为什么是它呢?

原则只有 1 个:Object 的中心落在哪个 cell,就决定了那个 cell 的核心地位。

很好理解嘛,一个国家最高的机构落地的城市,就是首都。

再往下走。

每个 Cell 还会预测 C 个类别的概率。

这是条件概率。

Pr(Classi∣Object)Pr(Class_{i}|Object) Pr(Classi​∣Object)

如果一个 Cell 存在 Object,预测这个 Object 的 class 才有意义。

在测试阶段,这个条件概率还要与 Cell 的 Confidence 相乘。

它的公式表达了两个思想:

  1. 类别的概率
  2. 预测的框距离 groudtruth 有多接近

需要注意的是,每个 Cell 输出的是一组概率,代表了 C 个类别的概率,在论文中 YOLO 的 C 取值为 20.

所以,YOLO 最终就是通过下图的方式来预测的。

它的本质是因为 YOLO 模型的最后一层是一个 7x7x30 的 tensor。

7x7 对应图像分割成 49 个 cell。

30 包含了 2 个 bbox 的数据,及 20 个 class 的概率。


以上,就是 YOLOv1 目标检测的核心思想,它能检测就是基于上面的思路。

2.躯干,长什么样子?

我指的躯干其实就是 YOLO 的神经网络结构。

这部分比较简单,我将快速略过。

原论文中说到,YOLO v1 的模型结构受 GoogLeNet 启发。

但是,有少许不同。

YOLO 采用了 1x1 和 3x3 的序列组合替代 Inception 模块。

总共 24 个卷积层加上 2 个全连接层。

输出层正是前面提到过的 7x7x30 的 tensor,用来预测最终的结果。

然后,需要注意的是 YOLO 将定位和目标分类统一成了一个回归问题。

3. 手脚,如何训练

YOLO 的训练并不复杂,其中最重要的内容就是 Loss 的设定。

1. 预训练

取 YOLO 模型前面的 20 个卷积加上 1 个全连接层在 ImageNet 上训练,也就是为了目标识别,目的是为了获取目标的特征表达能力。

2. 目标检测训练

在 pretrain 的基础上增加了 4 个卷积层和 2 个全连接层。

因为目标检测任务的训练一般对图像分辨率精细度要求比较高,所以,在这以阶段,输入图像的尺寸从之前 ImageNet 需要的尺寸 224x224,变成了 448x448。

另外,为了归一化的效果,对于之前预测的 bbox,YOLO 也做了特别的处理。

一般,我们讲 bbox 中的 4 个参数 (x,y,width,height) 指的是下图所示:


YOLO 做了调整。

X,Y 在预测的 bbox 中代表框的中心点位置,并且是相对于 Cell 中心点的偏移比例,取值是 0 到 1 之间。

可能难以理解,图例说明。


上图中某个 cell 预测了一个 bbox。

黄色的原点代表 cell 的中心。
红色的圆圈代表 bbox 的中心。

那么 x,y 的取值就是两个中心的偏移量和 cell 本身宽高的比值。

x = (bbox.x-cell.x)/cell.width
y = (bbox.y - cell.y)/cell.height

另外 bbox 包含的 w,h 也是一个归一化的结果。是 bbox 的宽高和整张图片的宽高的比值。

所以,w,h 同样取值为 0 到 1。

w = bbox.width / image.width
h = bbox.height / image.height

好,讲完 bbox 的 4 个参数,再回到训练上来。

YOLO 的激活层除了最后一层外都是采用 ReLu。

YOLO 用误差平方和(SSE) 进行优化,作者说因为这样比较简单。

但是 YOLO 的 Loss 由 4 个子 Loss 构成,也是最难以理解的一部分。


公式很长,慢慢分析其实也还行。

首先 Loss 要计算:

  • 中心点的 Loss
  • 宽高的 Loss
  • 置信度的 Loss
  • 目标类别的 Loss

前面讲到一张图片产生 49 个 cell,有些 cell 没有什么意义,因为它们不包含任何的 Object。

所以,计算 Loss 时就只考虑有 Object 存在的 cell。

这也是下面的符号代表的意义。

1ijobj1_{ij}^{obj} 1ijobj​

下标 i 代表 cell 的序号,下标 j 代表这个 cell 的第 j 个 bbox。

这行 Loss 就是所有的存在目标的 cell 中所预测的 bbox 中心点的 SSE。

前面的 λcoord\lambda_{coord}λcoord​ 是权重,为什么要加这个权重呢?

这个需要细致说一下。

SSE 导致了 bbox 的定位和分类问题权重一样,并且那些没有包含物体的 cell ,它们的 confidence 是 0,这会导致训练过程中,梯度变化不平衡,整个模型变得不稳定。

为了解决这个问题,所以引入了两个 λ\lambdaλ 分别代表有 object 和没有 object 的权重。

这两个权重是惩罚项,代表不同的内容对于整个优化过程的贡献度。

另外有人注意到计算 bbox 宽高的 Loss 时。

为啥是平方根的差呢?

因为 bbox 对于尺寸敏感度很高。


假设上图两组 bbox 预测与真值比对结果中,w 这一维度的结果都是 0.2.

但是左右两组对于这个数值敏感度是不一样的,我们可以看到,右边那组小尺寸的更加敏感。

所以,用平方根就是为了缩短这种差距。

为此,我们可以对 Loss 总结如下:

  • 计算有物体的 Cell 的 bbox 中心点、宽高、物体类别的 Loss
  • 计算所有 Cell 的 Confidence 的 Loss,但是无 Object 的 Cell 它的 Loss 权重很低
  • 相对于物体类别,bbox 定位的权重要更高。

Loss 讲完后,YOLO 就差不多讲完了,接下来快速陈述一下它的训练过程。

训练过程

在 PASCAL VOC 2007 和 2012 训练和验证,总共 135 epochs。

batch size 是 64.
momentum 是 0.9
decay 是 0.0
  1. 第一个 epoch ,学习率缓慢从 0.001 到 0.02.
  2. 以 0.02 训练 75 个 epochs。
  3. 以 0.001 训练 30 个 epochs。
  4. 以 0.0001 训练最后 30 个 epochs。

为了防止过拟合,采用了 dropout 技术,比率为 0.5.

另外还做了数据增强。

YOLO 的局限性

因为一个 cell 只能预测一个类别,所以如果比较小的物体成群出现,会导致许多的 object 的中心点其实在一个 cell 中,那么就会出现漏检。

下一步

学完 YOLOv1 只是第一步。

下一步建议你将 YOLOv2 和 YOLOv3 也学习。

另外,你可以根据你的理解用 Tensorflow 或 Pytorch 复现或者仿照一个 YOLO 网络。

死磕YOLO系列,YOLOv1 的大脑、躯干和手脚相关推荐

  1. tomcat lifecyclelistener_大公司程序员带你死磕Tomcat系列(五)——容器

    死磕Tomcat系列(5)--容器 回顾 在死磕Tomcat系列(1)--整体架构中我们简单介绍了容器的概念,并且说了在容器中所有子容器的父接口是Container.在死磕Tomcat系列(2)--E ...

  2. 死磕shell系列-shell介绍

    写的比较好的博客推荐: 博主介绍:-纸短情长 死磕shell系列-shell介绍

  3. 什么?还在用delete删除数据《死磕MySQL系列 九》

    别再用delete删除数据 系列文章 一.表空间 二.数据删除流程 三.实践全表删除表文件大小不改变 四.如何正确的减少磁盘文件 五.实践是检验认识是否具有真理性的唯一标准 六.开发建议 七.总结 系 ...

  4. MySQL统计总数就用count,别花里胡哨的《死磕MySQL系列 十》

    有一个问题是这样的统计数据总数用count(*).count(主键ID).count(字段).count(1)那个效率高. 先说结论,不用那么花里胡哨遇到统计总数全部使用count(*). 但是有很多 ...

  5. 死磕数据库系列(二十六):MySQL 高可用之单主、双主模型组复制配置实践

    点关注公众号,回复"1024"获取2TB学习资源! 前面我们学习:MySQL 高可用之组复制(MGR)技术的相关原理知识,今天我将详细的为大家介绍 MySQL 高可用技术组复制的单 ...

  6. 死磕数据库系列(三十三):MySQL 性能分析与相关工具的使用

    点关注公众号,回复"1024"获取2TB学习资源! 今天我将详细的为大家介绍 MySQL 性能分析以及相关工具使用的相关知识,希望大家能够从中收获多多!如有帮助,请点在看.转发支持 ...

  7. S 锁与 X 锁的爱恨情仇《死磕MySQL系列 四》

    一网打尽MySQL的各种锁 系列文章 `获取MySQL各种学习资料可以联系咔咔` 前言 一.行锁 二.两阶段锁 三.理解死锁 四.优化你的代码尽量防止死锁 五.解释死锁的两种方案 六.如何解决热点数据 ...

  8. 死磕数据库系列(二十):MySQL 数据库 DDL、DML、DQL、DCL 语言理论与实践(sql 8.0 版)...

    点关注公众号,回复"1024"获取2TB学习资源! 今天,民工哥带大家一起来学习一下 MySQL 数据库的 DDL.DML.DQL.DCL 这几种语言的理论知识与实践.如有帮助,请 ...

  9. 死磕Tomcat系列(6)——Tomcat如何做到热加载和热部署的

    死磕Tomcat系列(6)--Tomcat如何做到热加载和热部署的 热部署就是在服务器运行时重新部署项目,热加载即在在运行时重新加载class,从而升级应用. 通常情况下在开发环境中我们使用的是热加载 ...

最新文章

  1. java 多线程 进程_Java多线程1:进程与线程概述
  2. 2019-10-12 线性最小方差估计和正交定理
  3. CF1253F Cheap Robot
  4. 【POJ - 2377】Bad Cowtractors (最大生成树,并查集)
  5. 对C语言进行调试的最好方法是什么?
  6. Google Pixel 解锁BL、刷入Twrp、magisk Root、安装 Xposed
  7. C/C++fflush(stdout)循环打印输出避免缓存区错误
  8. Log4j2日志框架集成Slf4j日志门面
  9. 移动端列表以树的形式展示
  10. 基于JAVA+SpringMVC+Mybatis+MYSQL的账单管理系统
  11. selenium对浏览器属性操作的方法
  12. java 异常 出口_java语言中,下列哪一子句是异常处理的出口java语言中,下列哪一子句是异常处理的出口Java语言中,下列哪一子句是异常处理的出口()。...
  13. osgEarth世界坐标和经纬度坐标相互转换
  14. Matlab分号的使用
  15. HPC应用安装之roms
  16. C++项目实战——简易版日期计算器(Date类改编)
  17. selenium 浏览器复用(java)
  18. linux发行版本排行,2020年10种最受欢迎的Linux发行版排名
  19. 追星必备神器 -- 爱豆APP
  20. 测试 必问面经华子~

热门文章

  1. 征服统计学08|天天在用的P值到底是个啥?
  2. 射频和无线技术入门--传统技术--7
  3. 18_一文总结Flask语法
  4. 复旦大学计算机专业博士生导师,危辉 - 复旦大学 - 计算机科学技术学院
  5. 微信公众号扫一扫功能vue配置
  6. python练习题---矩阵求和
  7. pthon爬虫笔记--名著小说网
  8. 卸载Resharper
  9. 【贪玩巴斯】数字信号处理Digital Signal Processing(DSP)——第四节「离散时间系统分类、线性和非线性、因果和非因果、稳定和不稳定以及互联」2021-10-20
  10. 淘宝直播弹幕API接口协议