【object_detection】目标检测 — YOLO V3

一、YOLO 网络结构说明

网络结构主要由三个主要组件组成:

1. Backbone

在不同图像细粒度上聚合并形成图像特征的卷积神经网络

2. Neck

一系列混合和组合图像特征的网络层,并将图像特征传递到预测层

3. Head

对图像特征进行预测,生成边界框并预测类别

二、YOLO V3 简介

yolov3 的先验检测(Prior detection)系统将分类器或定位器重新用于执行检测任务。将模型应用于图像的多个位置和尺度。而那些评分较高的区域就可以视为检测结果。此外,相对于其它目标检测方法,yolov3 使用了完全不同的方法。

yolov3 将一个单神经网络应用于整张图像,该网络将图像划分为不同的区域,因而预测每一块区域的边界框和概率,这些边界框会通过预测的概率加权。相比于基于分类器的系统有一些优势。它在测试时会查看整个图像,所以它的预测利用了图像中的全局信息。与需要数千张单一目标图像的 R-CNN 不同,它通过单一网络评估进行预测。这令 YOLOv3 非常快,一般它比 R-CNN 快 1000 倍、比 Fast R-CNN 快 100 倍。

三、YOLO V3 网络结构

【object_detection】目标检测 — YOLO V3

Yolov3的三个基本组件

1. CBL: Yolov3网络结构中的最小组件,由 Conv+Bn+Leaky_relu 激活函数三者组成。
2. Res unit: 借鉴 Resnet 网络中的残差结构,让网络可以构建的更深。
3. ResX: 由一个 CBL 和 X 个残差组件构成,是 yolov3 中的大组件。每个 Res 模块前面的 CBL 都起到下采样的作用,因此经过 5 次 Res 模块后,得到的特征图是 608->304->152->76->38->19 大小。

其他基础操作:

  1. Concat: 张量拼接,会扩充两个张量的维度,例如 26*26*25626*26*512 两个张量拼接,结果是 26*26*768。Concat 和 cfg 文件中的 route 功能一样。
  2. add: 张量相加,张量直接相加,不会扩充维度,例如 104*104*128104*104*128 相加,结果还是 104*104*128。add 和 cfg 文件中的 shortcut 功能一样。

【object_detection】目标检测 — YOLO V3
Yolov3的网络结构说明:

  1. 在特征利用部分,yolo3 借助 darknet53 提取多特征层进行目标检测,一共提取三个特征层,三个特征层位于主*分 darknet53 的不同位置,分别位于中间层,中下层,底层,三个特征层的 shape 分别为 (52,52,256)、(26,26,512)、(13,13,1024)。
  2. 对这三个初始的特征层进行 5 次卷积处理,处理完后一部分用于输出该特征层对应的预测结果,一部分用于进行反卷积 UmSampling2d 后与其它特征层进行结合。
  3. 输出层的 shape 分别为 (13,13,75),(26,26,75),(52,52,75),最后一个维度为 75 是因为该图是基于 voc 数据集的,它的类为 20 种,yolo3 只有针对每一个特征层存在 3 个先验框,所以最后维度为 3x25;如果使用的是 coco 训练集,类则为 80 种,最后的维度应该为 255=3x85,三个特征层的 shape 为 (13,13,255),(26,26,255),(52,52,255)

Yolov3的输出问题:

  1. 9个 anchor 会被三个输出张量平分的。根据大中小三种 size 各自取自己的 anchor。
  2. 每个输出 y 在每个自己的网格都会输出 3 个预测框,这 3 个框是 9 除以 3 得到的,从输出张量的维度来看,13x13x255。255=3*(5+80)。80 表示 80 个种类,5 表示位置信息和置信度,3 表示要输出 3 个prediction。
  3. 使用了 logistic 回归来对每个 anchor 包围的内容进行了一个目标性评分(objectness score)。 根据目标性评分来选择 anchor prior 进行 predict,而不是所有 anchor prior 都会有输出。

四、预测结果的解码

由第二步可以获得三个特征层的预测结果,shape 分别为 (N,255,13,13),(N,255,26,26),(N,255,52,52) 的数据,对应每个图分为 13x13、26x26、52x52 的网格上 3 个预测框的位置。但是这个预测结果并不对应着最终的预测框在图片上的位置,还需要解码才可以完成。

特征层的预测结果对应着三个预测框的位置,先将其 reshape 一下,其结果为 (N,3,85,13,13,3,85),(N,3,85,26,26),(N,3,85,52,52)。

维度中的 85 包含了 4+1+80,分别代表 x_offset、y_offset、h 和 w、置信度、分类结果。

yolo3 的具体解码过程: 在代码中就是首先生成特征层大小的网格,然后将我们预先设置好了的在原图中 416*416 先验框的尺寸调整到有效特征层大小上,最后从 yolov3 的网络预测结果获得先验框的中心调整参数 x_offset 和 y_offset 和宽高的调整参数 h 和 w,对在特征层尺寸大小上的先验框进行调整,将每个网格点加上它对应的 x_offset 和 y_offset 的结果就是调整后的先验框的中心,也就是预测框的中心,然后再利用 先验框和 h、w 结合 计算出调整后的先验框的的长和宽,也就是预测框的高和宽,这样就能得到在特征层上整个预测框的位置了,最后将在有效特征层上的预测框的位置再调整到原图 416*416 的大小上。

当然得到最终的预测结构后还要进行得分排序与非极大抑制筛选。这一部分基本上是所有目标检测通用的部分。不过该项目的处理方式与其它项目不同。其对于每一个类进行判别。

  1. 取出每一类得分大于 self.obj_threshold 的框和得分。
  2. 利用框的位置和得分进行非极大抑制。

总结: 先验框解码的过程就是利用 yolov3 网络的预测结果(3个有效的特征层)对先验框进行调整的过程,调整完就是预测框。

在原图上进行绘制

通过预测解码,可以获得预测框在原图上的位置,而且这些预测框都是经过筛选的。这些筛选后的框可以直接绘制在图片上,就可以获得结果了。

五、YOLO V3的改进之处

1. 多尺度预测 (类FPN)

每种尺度预测 3 个 box, anchor 的设计方式仍然使用聚类,得到 9 个聚类中心,将其按照大小均分给 3 个尺度。

  • 尺度1: 在基础网络之后添加一些卷积层再输出 box 信息。
  • 尺度2: 从尺度1中的倒数第二层的卷积层上采样(x2)再与最后一个 16x16 大小的特征图相加,再次通过多个卷积后输出 box 信息,相比尺度1变大两倍.
  • 尺度3: 与尺度2类似,使用了 32x32 大小的特征图

2. 更好的基础分类网络(类ResNet)和分类器 darknet-53

【object_detection】目标检测 — YOLO V3
主干网络修改为 darknet53,其重要特点是使用了残差网络 Residual,darknet53 中的残差卷积就是进行一次3*3、步长为 2 的卷积,然后保存该卷积 layer,再进行一次 1*1 的卷积和一次 3*3 的卷积,并把这个结果加上 layer 作为最后的结果, 残差网络的特点是容易优化,并且能够通过增加相当的深度来提高准确率。其内部的残差块使用了跳跃连接,缓解了在深度神经网络中增加深度带来的梯度消失问题。

darknet53 的每一个卷积部分使用了特有的 DarknetConv2D 结构,每一次卷积的时候进行 L2 正则化,完成卷积后进行 BatchNormalization 与 LeakyReLU。普通的ReLU是将所有的负值都设为零,Leaky ReLU 则是给所有负值赋予一个非零斜率。以数学的方式我们可以表示为:
【object_detection】目标检测 — YOLO V3

3. 分类器-类别预测

YOLOv3 不使用 Softmax 对每个框进行分类,主要考虑因素有两个:

(1)Softmax 使得每个框分配一个类别(得分最高的一个),而对于 Open Images 这种数据集,目标可能有重叠的类别标签,因此 Softmax 不适用于多标签分类。
(2)Softmax 可被独立的多个 logistic 分类器替代,且准确率不会下降。

分类损失采用 binary cross-entropy loss.

六、训练部分

1. pred 是什么?

对于 yolo3 的模型来说,网络最后输出的内容就是三个特征层每个网格点对应的预测框及其种类,即三个特征层分别对应着图片被分为不同 size 的网格后,每个网格点上三个先验框对应的位置、置信度及其种类。

输出层的 shape 分别为 (13,13,75),(26,26,75),(52,52,75),最后一个维度为 75 是因为是基于 voc 数据集的,它的类为 20 种,yolo3 只有针对每一个特征层存在 3 个先验框,所以最后维度为 3x25;如果使用的是 coco 训练集,类则为 80 种,最后的维度应该为 255 = 3x85,三个特征层的 shape 为 (13,13,255),(26,26,255),(52,52,255)

Note: 现在的 y_pre 还是没有解码的,解码了之后才是真实图像上的情况。

2. target是什么?

target 就是一个真实图像中,真实框的情况。第一个维度是 batch_size,第二个维度是每一张图片里面真实框的数量,第三个维度内部是真实框的信息,包括位置以及种类。

3. loss的计算过程

拿到 pred 和 target 后,不可以简单的减一下作为对比,需要进行如下步骤:

step 1: 对 yolov3 网络的预测结果进行解码,获得网络预测结果对先验框的调整数据

step 2: 对真实框进行处理,获得网络应该真正有的对先验框的调整数据,也就是网络真正应该有的预测结果 ,然后和我们得到的网络的预测结果进行对比,代码中 get_target 函数:

  1. 判断真实框在图片中的位置,判断其属于哪一个网格点去检测。

  2. 判断真实框和哪个先验框重合程度最高。

  3. 计算该网格点应该有怎么样的预测结果才能获得真实框(利用真实框的数据去调整预先设定好了的先验框,得到真实框该网格点应该预测的先验框的调整数据)

  4. 对所有真实框进行如上处理。

  5. 获得网络应该有的预测结果,将其与实际的预测结果对比。

step 3: 将真实框内部没有目标的对应的网络的预测结果的且重合程度较大的先验框进行忽略,因为图片的真实框中没有目标,也就是这个框的内部没有对象,框的位置信息是没有用的,网络输出的这个先验框的信息和其代表的种类是没有意义的,这样的得到调整的先验框应该被忽略掉,网络只输出框内部有目标的数据信息,代码中 get_ignore 函数。

step 4: 利用真实框得到网络真正的调整数据和网络预测的调整数据后,我们就对其进行对比 loss 计算

上一篇:YOLOv3论文解读


下一篇:YOLO v3 代码及数据集下载(小白教程---超详细)